感谢平台分享-http://bjbsair.com/2020-04-10/tech-info/53257.html

《css揭秘》中讲了47个css技巧,其中有很多日常编码中并不会用到,本文除了将书中部分实用技巧罗列出来之外,还尝试用帮助读者搞明白background、animation 等常用但是却掌握不牢固的知识点。所以阅读本文不仅可以学习一些实用技巧,也可以巩固自己的 css 基础知识。

实用小技巧

DRY原则

全名Don’t Repeat Yourself,该原则适用于所有编程语言而不限于css。

扩大可点击区域

  • 关键实现:伪元素
  • 具体分析:利用伪元素和定位达到鼠标移到边缘时候出现手型且可点击
.expand-range {  position: relative;
}
.expand-range:after {  content: '';  position: absolute;  top: -10px; right: -10px; bottom: -10px; left: -10px;
}

推荐使用scss:

@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {  position: $position;  &:after {  content: '';  position: absolute;  top: $top;  right: $right;  bottom: $bottom;  left: $left;  }
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }

巧用层叠上下文

  • 关键实现: 伪元素 层叠上下文
  • 具体分析: 利用层叠上下文和 z-index: -1 特性实现伪元素覆盖背景同时又不会遮挡文字(具体实现原理参考这里 )。这是一个非常常用又好用的技巧,善加利用可以达到很多意想不到的效果。地址
  position: absolute;  top: 0; right: 0; bottom: 0; left: 0;  z-index: -1;

层叠上下文

边框内圆角

  • 关键实现:伪元素 层叠上下文
  • 具体分析:利用伪元素实现圆角矩形并叠加在父元素的背景之上文字之下:地址

边框内圆角

clip-path

  • 关键实现: clip-path
  • 具体分析:css3 新属性 clip-path 可以实现区域裁剪,现在浏览器支持较好的有三个函数:clip-path: circle(50px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个半径 50px 的圆;clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个横向半径 30px,纵向半径 40px 的椭圆;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) 按照多个坐标剪裁一个多边形,此处是菱形。有了 clip-path,就可以轻易的实现任意多边形了:地址

clip-path

自适应的椭圆

  • 关键实现:border-radius
  • 具体分析:border-radius 竟然可以设置 8 个角的半径~ 其中水平方向(对角线上下有弧度的地方)和垂直方向(对角线左右有弧度的地方)各四个,可以用 / 分割。如果水平或垂直方向指定的值少于四个,则会按照和 margin、padding 一样的规则重复。如果只指定来水平方向的,那么垂直方向的跟水平方向的一样。
    border-radius: 5em 1em; /*相当于border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/

自适应的椭圆

自适应宽度

  • 关键实现:min-content关键字
  • 具体分析:如何实现一个元素的宽度根据后代元素的最大固定元素宽度自适应呢?绞尽脑汁,也只能利用 display: inline-block 的包裹特性实现一个不完全的版本:地址 这种方法的缺陷是文本脱离了文档流,高度未计入包含块。但是如果利用 min-content 关键字,可以一行代码实现且无副作用:地址
  width: min-content;

自适应宽度

投影模拟多重边框

  • 关键实现:box-shadow的inset
  • 具体分析:使用box-shadow可以模拟实现多重边框,但是由于阴影不占空间,所以无法触发点击事件,鼠标hover边框时无法出现小手,所以需要配合inset关键字使用:地址
  height: 200px;  background: cyan;  box-shadow: 0 0 0 5px #000 inset,  0 0 0 10px #555 inset,  0 0 0 15px #999 inset;

投影模拟多重边框

单侧投影

  • 关键实现:box-shadow
  • 具体分析:box-shadow 前两个参数指定阴影的x、y偏移量,注意若为正数时整体向右/向下偏移,那么相应的左方/上方会空出一部分来(可以用来隐藏模糊半径或扩张半径),负数相反;第三个参数是阴影模糊半径,即高斯模糊多增加出来的过度颜色;第四个参数是阴影扩张半径,表示阴影增加的尺寸,可以是负数,表示阴影缩短的尺寸:地址
  box-shadow: 0 5px 4px -4px black;

第二个参数使阴影整体下移 5px ,第三个参数使阴影四周多了 4px 的高斯模糊(注意由于整体下移了 5px,所以此时上方还是没有阴影露出的),第四个参数又把阴影整体缩小了 4px,,所以左右两边才没有出现模糊半径导致的高斯模糊阴影色,从而实现单侧投影。

单侧投影

还可以逗号分隔设置多个阴影色,比如下面的两侧投影效果:地址

  box-shadow: 5px 0 5px -5px black,  -5px 0 5px -5px black;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xlIeoEBT-1586506401341)(http://p1.pstatp.com/large/pgc-image/d5a033e70a66436baa01307828811596)]

单侧投影

不规则投影

  • 关键实现:filter: drop-shadow()
  • 具体分析:box-shadow 不能透过透明背景显示出来,不能越过伪元素/子元素显示出来,而这些drop-shadow能做到。(但无论哪种投影都会被clip-path剪裁掉~~)地址
  filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));

不规则投影

滤镜的染色和褪色效果

前端开发大都了解糊滤的高斯模镜效果是filter: blur()实现的,但是却很少使用滤镜的其他几个调色效果。filter 的值有blur()、drop-shadow()、url()、brightness()、contrast()、grayscale()、hue-rotate()、invert()、opacity()、saturate()、sepia()~~可以使用复合形式如:filter: sepia(1) saturate(4)等。下面是filter属性值大集合:地址

滤镜的染色和褪色效果

饼图 svg

饼图的 css 实现方案非常奇怪,所以我忽略之。推荐使用 svg 的实现方案,非常简单,先来个基本教学吧~

先画个圆:

<svg width="100" height="100">  <circle r="25" cx="50" cy="50" />
</svg>

这里 r=“25” 是半径25, cx cy 分别表示圆心的 x y 坐标。

circle {  fill: yellowgreen;  stroke: #666;  stroke-width: 50;
}

这里给圆形定义了一个宽度 40 的描边:

饼图 svg

再把描边设为线段长度 20 间隔 10 的虚线:

circle {  ...  stroke-dasharray: 20 10;
}

当把虚线的间隔设定为大于等于圆周时,虚线的线段长度就是一个扇形区域(当线段长度等于圆周时扇区达到100%):

给 svg 设置圆角和背景色,并旋转 -90deg ,就可以实现一个饼图:地址(使用currentColor关键字和color: inherit 是为了实现DRY原则。)

但是这样的饼图其扇区大小是不易计算的,为了方便计算,可以让虚线的线段长度同时也是圆周无限接近100,这样就可以更方便的设置扇区的百分比。圆周是 2πr ,所以 100 = 2πr ,计算得出半径 r 近似值 16。再利用 svg 的 viewBox 属性,实现自适应容器大小的饼图:地址

这种方法有个弊端,就是当设置 stroke-dasharray: 100 100 时会有一条缝,这是取近似值无法避免的。

背景background

background 是我们最常用的属性之一,但作为一个老前端,我也只能羞耻的说我目前并没有完全掌握这个属性。

background 是一个简写属性,可以包括多个属性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment。接下来我们一个个来看看这些属性的作用:

  • background-color 最常用的属性,默认不继承(background的所有属性都默认不继承),初始值为 transparent;有时候使用默认继承可以实现一些好玩的效果,比如倒影;
  • backgroundo-image 背景图片,可以逗号分割设置多个,可以是图片url或者渐变色;
  • background-clip 背景剪裁,可以逗号分割设置多个,值可以为 broder-box(初始值)、padding-box、content-box、text(新,将背景被文字剪裁);
  • background-origin 设置背景起始点的相对区域,搭配 background-position使用,可以逗号分割设置多个,值可以是border-box、padding-box(初始值)、content-box;
  • background-position 设置背景的起始点,可以逗号分割设置多个,值可以是 10px 20px 、center center 、left 10px bottom 20px等等,非常灵活;
  • background-size 设置背景的大小,可以逗号分割设置多个,值可以是数字值如30px 40px、auto auto(初始值)、conver、contain;background-repeat: repeat就是根据这个尺寸大小来重复的。
  • background-repeat 设置背景的重复方式,初始值为 repeat,常使用值的还有no-repeat;
  • background-attachment 设置背景图像的位置是在视口内固定,还是随着包含它的区块滚动。可以逗号分割设置多个,值有scroll(初始值)、local、fixed。详情查看MDN

简写时 background-size 只能紧接着 background-position 出现,以 / 分割,如: “center / 80%”。

半透明边框

  • 关键实现:background-clip
  • 具体分析:由于background属性默认会覆盖整个盒模型包括边框border,所以设置border-color: rgba(0, 0, 0, .5)时会透出背景色,达不到半透明边框的效果。css3增加了background-clip属性,定义背景填充的裁剪区域。设置padding-box便可以实现半透明边框:地址
  border: 10px solid rgba(255, 255, 255, .5);  background: white;  background-clip: padding-box;

半透明边框

灵活的背景定位

  • 关键实现:backgrond-position background-origin
  • 具体分析:我们都知道background-position可以定位背景图片等位置,但是都是相对padding-box的左上角开始等。css3 允许这样写:background-position: right 10px bottom 20px,同时 css3 还支持background-origin,其默认值如同其表现border-box,支持设为padding-box和content-box:地址
  height: 200px;  padding: 10px;  border: 5px solid cyan;  background: lightblue;  background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;  background-origin: content-box;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5lui6mWM-1586506401349)(http://p1.pstatp.com/large/pgc-image/04b65969ef194d88958b6f9b285f3b63)]

背景定位

background-position 设为百分比值较为复杂。百分比值实际上执行了以下的计算公式:

(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)

由计算公式可知:当值为0%时,实际偏移值为0px,此时图片的左边界(或上边界)和容器的左边界(或上边界)重合;当值为50%时,实际偏移值为容器减图片剩余空间的一半,图片左右边界(或上下边界)距离容器左右边界(或上下边界)相等,此时图片的中点和容器的中点重合。当值100%时,实际偏移值为容器减图片的剩余空间,所以此时图片的右边界(或下边界)和容器的右边界(或下边界)重合。二者之差为负值时同样有效。地址

背景定位

条纹背景

  • 关键实现:background-image
  • 实现分析:利用线性渐变实现多种颜色的交错重复,形成条纹背景。lienar-gradient的第一个参数是渐变的角度,可以是方向关键字to top(初始值,可忽略不写)等,也可以是角度90deg等;#fb3 50%指的是色标和终点位置值;这里linear-gradient的第二个位置值设置为0会被解析为前一个色标的位置值即50%,这样写更加符合DRY原则。
background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;

条纹背景

也可以设置为垂直条纹背景:

background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;

还可以设置为斜向条纹:

background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;

垂直条纹背景

斜向条纹需要设置四条条纹才能在平铺到时候做到无缝拼接。

更好的斜向条纹:(这里必须设置起始值#fb3 0)

background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);

更好的斜向条纹

网格

  • 关键实现:background-image、background-size
  • 给多个渐变设置不同的方向、大小,可以实现网格的效果。地址
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),  linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;

网格

更好的网格:

background: #58a;
background-image: linear-gradient(white 2px, transparent 0),  linear-gradient(to right, white 2px, transparent 0),  linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),  linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;

更好的网格

棋盘

  • 关键实现:background-image、background-size、background-position
  • 具体分析:给多个渐变设置不同的大小、位置,可以实现网格的效果。地址
  background: #eee;  background-image:  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

棋盘

折角

  • 关键实现:线性渐变
  • 具体分析:150deg 是为了形成30度角,方便利用勾股定理测出各种长度,其他的靠你自己看了~ 地址

折角

到这里 background 属性基本讲完了,光看无用,多动手实践吧。

波点

  • 关键实现:径向渐变
  • 具体分析:利用径向渐变实现一个个小圆点,按规律摆放即能生成波点 地址
  background:  radial-gradient(tan 30%, transparent 0),  radial-gradient(tan 30%, transparent 0);  background-color: #666;  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

波点

切角

  • 关键实现:clip-path、径向渐变
  • 具体分析:一般来说多边形的切角效果(其实还是不规则多边形)用clip-path都可以轻松实现,但是对于圆形的切角,使用径向渐变是最好的选择。但是如果有弧形的切角呢?radial-linear第一个参数指定渐变的起始点点(默认为中心点),同时可指定渐变类型是椭圆还是圆;地址
  background:  radial-gradient(circle at top left, transparent 15px, blue 0) top left,  radial-gradient(circle at top right, transparent 15px, cyan 0) top right,  radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,  radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;  background-size: 50% 50%;  background-repeat: no-repeat;

切角

饼图

  • 关键实现:锥形渐变
  • 具体分析:利用锥形渐变可以轻松实现多个扇区,所以 svg 的方法权当学习了一波 svg 用法吧。
  background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S7s8ibp0-1586506401363)(http://p3.pstatp.com/large/pgc-image/a38bf9e102fe45abbe49939d5a9fbcbd)]

饼图

动画animation

animation 属性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state属性的一个简写属性形式。

  • animation-name 指定动画的名称,可以逗号分割设置多个(以下皆可);
  • animation-duration 指定动画运行的时间;
  • animation-delay 指定动画执行前的延时;
  • animation-timing-function 指定动画执行的速度函数,如linear、ease(默认)、ease-in-out等,也可用贝塞尔函数cubic-bezier();
  • animation-iteration-count 指定动画的运行的次数,默认为1,可以为Infinite无限次;
  • animation-direction 指定动画是否反方向播放,normal 正常的顺序,alternate 交替运行,reverse 反向运行,alternate-reverse 反向交替运行;
  • animation-fill-mode 设置CSS动画在执行之前和之后的样式,none 不设置,forwards 保留最后一帧动画的样式,backwards 立即应用第一个关键帧中定义的值,并在animation-delay期间保留此值,both 同时应用forwards和backwards的规则;
  • animation-play-state 定义一个动画是否运行或者暂停,值为running、paused。

回弹效果

如何给动画加上回弹效果呢?这里介绍一种最便利的方法:

  • 关键实现:cubic-bezier(x1, y1, x2, y2)
  • 具体分析:利用贝塞尔曲线的第二个控制锚点大于 1 时的特性实现回弹

回弹效果

上图图横轴为时间,纵轴为动画进度。图中贝塞尔曲线有两个控制手柄,x1, y1 控制第一个锚点,x2, y2控制第二个锚点。其中 x1 、x2 不能大于/小于 1,但是y1, y2 可以。当 y2 大于 1 时,就会产生提前到达终点,然后超过终点,然后再返回终点的效果,像回弹一样。地址

  animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);

transition 属性是 transition-property、transition-duration、transition-timing-function、transition-delay的一个简写属性。使用 transition 同样可以实现回弹效果:地址

p {  transform-origin: 1.4em -.4em;  transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}  input:not(:focus) + p {  transform: scale(0);  transition: transform 300ms; /*此处是为了缩小时重置transition-timing-function,不触发回弹*/
}

会动的背景

  • 关键实现:animation、background-position
  • 具体分析:将动画最后一帧的background-position设为100% 0%,动画便会将背景位置从最初的0% 0%向最后的100% 0%过度:地址
div {  width: 150px; height: 150px;  background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');  background-size: auto 100%;   animation: panoramic 10s linear infinite alternate;
}
div:hover {  animation-play-state: paused;
}  @keyframes panoramic {  to { background-position: 100% 0; }
}

环形路径移动的动画

  • 关键实现:animation transform-origin
  • 具体分析:设置旋转容器的transform-origin为大圆容器中心点,同时利用两个元素在向不同方向旋转时旋转角度互相抵消的原理,实现图像沿环形路径旋转同时保持自身角度的不变。注意小圆距离大圆的距离由大圆的padding属性控制,调整padding时需要调整小圆的旋转原点transform-origin以保持环形路径的正确:地址
@keyframes spin {  to { transform: rotate(1turn); }
}
.avatar {  animation: spin 3s linear 2s infinite;  transform-origin: 110px 110px;
}
.avatar > img {  animation: inherit;  animation-direction: reverse;
}

环形路径移动的动画

笔者推荐css文章

其实现在社区已经不乏介绍 css 技巧的好文,这里推荐几篇我觉得写的极好的css技巧文章(当然可能大家也看过,很惭愧我其实现在也没看完):

总结

总体来说,《css揭秘》这本书并没有给我带来太大惊喜,个人感觉不如阅读《css世界》带来的收获多。当然了,这本书属于纯技巧型的,并没有讲述很多原理知识,所以也不能苛责吧。有兴趣的同学可以跟着我学习一波 css世界,相信肯定会有更大的收获~感谢平台分享-http://bjbsair.com/2020-04-10/tech-info/53257.html

《css揭秘》中讲了47个css技巧,其中有很多日常编码中并不会用到,本文除了将书中部分实用技巧罗列出来之外,还尝试用帮助读者搞明白background、animation 等常用但是却掌握不牢固的知识点。所以阅读本文不仅可以学习一些实用技巧,也可以巩固自己的 css 基础知识。

实用小技巧

DRY原则

全名Don’t Repeat Yourself,该原则适用于所有编程语言而不限于css。

扩大可点击区域

  • 关键实现:伪元素
  • 具体分析:利用伪元素和定位达到鼠标移到边缘时候出现手型且可点击
.expand-range {  position: relative;
}
.expand-range:after {  content: '';  position: absolute;  top: -10px; right: -10px; bottom: -10px; left: -10px;
}

推荐使用scss:

@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {  position: $position;  &:after {  content: '';  position: absolute;  top: $top;  right: $right;  bottom: $bottom;  left: $left;  }
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }

巧用层叠上下文

  • 关键实现: 伪元素 层叠上下文
  • 具体分析: 利用层叠上下文和 z-index: -1 特性实现伪元素覆盖背景同时又不会遮挡文字(具体实现原理参考这里 )。这是一个非常常用又好用的技巧,善加利用可以达到很多意想不到的效果。地址
  position: absolute;  top: 0; right: 0; bottom: 0; left: 0;  z-index: -1;

层叠上下文

边框内圆角

  • 关键实现:伪元素 层叠上下文
  • 具体分析:利用伪元素实现圆角矩形并叠加在父元素的背景之上文字之下:地址

边框内圆角

clip-path

  • 关键实现: clip-path
  • 具体分析:css3 新属性 clip-path 可以实现区域裁剪,现在浏览器支持较好的有三个函数:clip-path: circle(50px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个半径 50px 的圆;clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个横向半径 30px,纵向半径 40px 的椭圆;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) 按照多个坐标剪裁一个多边形,此处是菱形。有了 clip-path,就可以轻易的实现任意多边形了:地址

clip-path

自适应的椭圆

  • 关键实现:border-radius
  • 具体分析:border-radius 竟然可以设置 8 个角的半径~ 其中水平方向(对角线上下有弧度的地方)和垂直方向(对角线左右有弧度的地方)各四个,可以用 / 分割。如果水平或垂直方向指定的值少于四个,则会按照和 margin、padding 一样的规则重复。如果只指定来水平方向的,那么垂直方向的跟水平方向的一样。
    border-radius: 5em 1em; /*相当于border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/

自适应的椭圆

自适应宽度

  • 关键实现:min-content关键字
  • 具体分析:如何实现一个元素的宽度根据后代元素的最大固定元素宽度自适应呢?绞尽脑汁,也只能利用 display: inline-block 的包裹特性实现一个不完全的版本:地址 这种方法的缺陷是文本脱离了文档流,高度未计入包含块。但是如果利用 min-content 关键字,可以一行代码实现且无副作用:地址
  width: min-content;

自适应宽度

投影模拟多重边框

  • 关键实现:box-shadow的inset
  • 具体分析:使用box-shadow可以模拟实现多重边框,但是由于阴影不占空间,所以无法触发点击事件,鼠标hover边框时无法出现小手,所以需要配合inset关键字使用:地址
  height: 200px;  background: cyan;  box-shadow: 0 0 0 5px #000 inset,  0 0 0 10px #555 inset,  0 0 0 15px #999 inset;

投影模拟多重边框

单侧投影

  • 关键实现:box-shadow
  • 具体分析:box-shadow 前两个参数指定阴影的x、y偏移量,注意若为正数时整体向右/向下偏移,那么相应的左方/上方会空出一部分来(可以用来隐藏模糊半径或扩张半径),负数相反;第三个参数是阴影模糊半径,即高斯模糊多增加出来的过度颜色;第四个参数是阴影扩张半径,表示阴影增加的尺寸,可以是负数,表示阴影缩短的尺寸:地址
  box-shadow: 0 5px 4px -4px black;

第二个参数使阴影整体下移 5px ,第三个参数使阴影四周多了 4px 的高斯模糊(注意由于整体下移了 5px,所以此时上方还是没有阴影露出的),第四个参数又把阴影整体缩小了 4px,,所以左右两边才没有出现模糊半径导致的高斯模糊阴影色,从而实现单侧投影。

单侧投影

还可以逗号分隔设置多个阴影色,比如下面的两侧投影效果:地址

  box-shadow: 5px 0 5px -5px black,  -5px 0 5px -5px black;

单侧投影

不规则投影

  • 关键实现:filter: drop-shadow()
  • 具体分析:box-shadow 不能透过透明背景显示出来,不能越过伪元素/子元素显示出来,而这些drop-shadow能做到。(但无论哪种投影都会被clip-path剪裁掉~~)地址
  filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));

不规则投影

滤镜的染色和褪色效果

前端开发大都了解糊滤的高斯模镜效果是filter: blur()实现的,但是却很少使用滤镜的其他几个调色效果。filter 的值有blur()、drop-shadow()、url()、brightness()、contrast()、grayscale()、hue-rotate()、invert()、opacity()、saturate()、sepia()~~可以使用复合形式如:filter: sepia(1) saturate(4)等。下面是filter属性值大集合:地址

滤镜的染色和褪色效果

饼图 svg

饼图的 css 实现方案非常奇怪,所以我忽略之。推荐使用 svg 的实现方案,非常简单,先来个基本教学吧~

先画个圆:

<svg width="100" height="100">  <circle r="25" cx="50" cy="50" />
</svg>

这里 r=“25” 是半径25, cx cy 分别表示圆心的 x y 坐标。

circle {  fill: yellowgreen;  stroke: #666;  stroke-width: 50;
}

这里给圆形定义了一个宽度 40 的描边:

饼图 svg

再把描边设为线段长度 20 间隔 10 的虚线:

circle {  ...  stroke-dasharray: 20 10;
}

当把虚线的间隔设定为大于等于圆周时,虚线的线段长度就是一个扇形区域(当线段长度等于圆周时扇区达到100%):

给 svg 设置圆角和背景色,并旋转 -90deg ,就可以实现一个饼图:地址(使用currentColor关键字和color: inherit 是为了实现DRY原则。)

但是这样的饼图其扇区大小是不易计算的,为了方便计算,可以让虚线的线段长度同时也是圆周无限接近100,这样就可以更方便的设置扇区的百分比。圆周是 2πr ,所以 100 = 2πr ,计算得出半径 r 近似值 16。再利用 svg 的 viewBox 属性,实现自适应容器大小的饼图:地址

这种方法有个弊端,就是当设置 stroke-dasharray: 100 100 时会有一条缝,这是取近似值无法避免的。

背景background

background 是我们最常用的属性之一,但作为一个老前端,我也只能羞耻的说我目前并没有完全掌握这个属性。

background 是一个简写属性,可以包括多个属性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment。接下来我们一个个来看看这些属性的作用:

  • background-color 最常用的属性,默认不继承(background的所有属性都默认不继承),初始值为 transparent;有时候使用默认继承可以实现一些好玩的效果,比如倒影;
  • backgroundo-image 背景图片,可以逗号分割设置多个,可以是图片url或者渐变色;
  • background-clip 背景剪裁,可以逗号分割设置多个,值可以为 broder-box(初始值)、padding-box、content-box、text(新,将背景被文字剪裁);
  • background-origin 设置背景起始点的相对区域,搭配 background-position使用,可以逗号分割设置多个,值可以是border-box、padding-box(初始值)、content-box;
  • background-position 设置背景的起始点,可以逗号分割设置多个,值可以是 10px 20px 、center center 、left 10px bottom 20px等等,非常灵活;
  • background-size 设置背景的大小,可以逗号分割设置多个,值可以是数字值如30px 40px、auto auto(初始值)、conver、contain;background-repeat: repeat就是根据这个尺寸大小来重复的。
  • background-repeat 设置背景的重复方式,初始值为 repeat,常使用值的还有no-repeat;
  • background-attachment 设置背景图像的位置是在视口内固定,还是随着包含它的区块滚动。可以逗号分割设置多个,值有scroll(初始值)、local、fixed。详情查看MDN

简写时 background-size 只能紧接着 background-position 出现,以 / 分割,如: “center / 80%”。

半透明边框

  • 关键实现:background-clip
  • 具体分析:由于background属性默认会覆盖整个盒模型包括边框border,所以设置border-color: rgba(0, 0, 0, .5)时会透出背景色,达不到半透明边框的效果。css3增加了background-clip属性,定义背景填充的裁剪区域。设置padding-box便可以实现半透明边框:地址
  border: 10px solid rgba(255, 255, 255, .5);  background: white;  background-clip: padding-box;

半透明边框

灵活的背景定位

  • 关键实现:backgrond-position background-origin
  • 具体分析:我们都知道background-position可以定位背景图片等位置,但是都是相对padding-box的左上角开始等。css3 允许这样写:background-position: right 10px bottom 20px,同时 css3 还支持background-origin,其默认值如同其表现border-box,支持设为padding-box和content-box:地址
  height: 200px;  padding: 10px;  border: 5px solid cyan;  background: lightblue;  background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;  background-origin: content-box;

背景定位

background-position 设为百分比值较为复杂。百分比值实际上执行了以下的计算公式:

(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)

由计算公式可知:当值为0%时,实际偏移值为0px,此时图片的左边界(或上边界)和容器的左边界(或上边界)重合;当值为50%时,实际偏移值为容器减图片剩余空间的一半,图片左右边界(或上下边界)距离容器左右边界(或上下边界)相等,此时图片的中点和容器的中点重合。当值100%时,实际偏移值为容器减图片的剩余空间,所以此时图片的右边界(或下边界)和容器的右边界(或下边界)重合。二者之差为负值时同样有效。地址

背景定位

条纹背景

  • 关键实现:background-image
  • 实现分析:利用线性渐变实现多种颜色的交错重复,形成条纹背景。lienar-gradient的第一个参数是渐变的角度,可以是方向关键字to top(初始值,可忽略不写)等,也可以是角度90deg等;#fb3 50%指的是色标和终点位置值;这里linear-gradient的第二个位置值设置为0会被解析为前一个色标的位置值即50%,这样写更加符合DRY原则。
background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lO86lHcd-1586506402250)(http://p1.pstatp.com/large/pgc-image/7c69fe8fd3134e74a07424893aa8a76a)]

条纹背景

也可以设置为垂直条纹背景:

background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;

还可以设置为斜向条纹:

background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;

垂直条纹背景

斜向条纹需要设置四条条纹才能在平铺到时候做到无缝拼接。

更好的斜向条纹:(这里必须设置起始值#fb3 0)

background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);

更好的斜向条纹

网格

  • 关键实现:background-image、background-size
  • 给多个渐变设置不同的方向、大小,可以实现网格的效果。地址
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),  linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;

网格

更好的网格:

background: #58a;
background-image: linear-gradient(white 2px, transparent 0),  linear-gradient(to right, white 2px, transparent 0),  linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),  linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;

更好的网格

棋盘

  • 关键实现:background-image、background-size、background-position
  • 具体分析:给多个渐变设置不同的大小、位置,可以实现网格的效果。地址
  background: #eee;  background-image:  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

棋盘

折角

  • 关键实现:线性渐变
  • 具体分析:150deg 是为了形成30度角,方便利用勾股定理测出各种长度,其他的靠你自己看了~ 地址

折角

到这里 background 属性基本讲完了,光看无用,多动手实践吧。

波点

  • 关键实现:径向渐变
  • 具体分析:利用径向渐变实现一个个小圆点,按规律摆放即能生成波点 地址
  background:  radial-gradient(tan 30%, transparent 0),  radial-gradient(tan 30%, transparent 0);  background-color: #666;  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

波点

切角

  • 关键实现:clip-path、径向渐变
  • 具体分析:一般来说多边形的切角效果(其实还是不规则多边形)用clip-path都可以轻松实现,但是对于圆形的切角,使用径向渐变是最好的选择。但是如果有弧形的切角呢?radial-linear第一个参数指定渐变的起始点点(默认为中心点),同时可指定渐变类型是椭圆还是圆;地址
  background:  radial-gradient(circle at top left, transparent 15px, blue 0) top left,  radial-gradient(circle at top right, transparent 15px, cyan 0) top right,  radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,  radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;  background-size: 50% 50%;  background-repeat: no-repeat;

切角

饼图

  • 关键实现:锥形渐变
  • 具体分析:利用锥形渐变可以轻松实现多个扇区,所以 svg 的方法权当学习了一波 svg 用法吧。
  background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);

饼图

动画animation

animation 属性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state属性的一个简写属性形式。

  • animation-name 指定动画的名称,可以逗号分割设置多个(以下皆可);
  • animation-duration 指定动画运行的时间;
  • animation-delay 指定动画执行前的延时;
  • animation-timing-function 指定动画执行的速度函数,如linear、ease(默认)、ease-in-out等,也可用贝塞尔函数cubic-bezier();
  • animation-iteration-count 指定动画的运行的次数,默认为1,可以为Infinite无限次;
  • animation-direction 指定动画是否反方向播放,normal 正常的顺序,alternate 交替运行,reverse 反向运行,alternate-reverse 反向交替运行;
  • animation-fill-mode 设置CSS动画在执行之前和之后的样式,none 不设置,forwards 保留最后一帧动画的样式,backwards 立即应用第一个关键帧中定义的值,并在animation-delay期间保留此值,both 同时应用forwards和backwards的规则;
  • animation-play-state 定义一个动画是否运行或者暂停,值为running、paused。

回弹效果

如何给动画加上回弹效果呢?这里介绍一种最便利的方法:

  • 关键实现:cubic-bezier(x1, y1, x2, y2)
  • 具体分析:利用贝塞尔曲线的第二个控制锚点大于 1 时的特性实现回弹

回弹效果

上图图横轴为时间,纵轴为动画进度。图中贝塞尔曲线有两个控制手柄,x1, y1 控制第一个锚点,x2, y2控制第二个锚点。其中 x1 、x2 不能大于/小于 1,但是y1, y2 可以。当 y2 大于 1 时,就会产生提前到达终点,然后超过终点,然后再返回终点的效果,像回弹一样。地址

  animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);

transition 属性是 transition-property、transition-duration、transition-timing-function、transition-delay的一个简写属性。使用 transition 同样可以实现回弹效果:地址

p {  transform-origin: 1.4em -.4em;  transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}  input:not(:focus) + p {  transform: scale(0);  transition: transform 300ms; /*此处是为了缩小时重置transition-timing-function,不触发回弹*/
}

会动的背景

  • 关键实现:animation、background-position
  • 具体分析:将动画最后一帧的background-position设为100% 0%,动画便会将背景位置从最初的0% 0%向最后的100% 0%过度:地址
div {  width: 150px; height: 150px;  background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');  background-size: auto 100%;   animation: panoramic 10s linear infinite alternate;
}
div:hover {  animation-play-state: paused;
}  @keyframes panoramic {  to { background-position: 100% 0; }
}

环形路径移动的动画

  • 关键实现:animation transform-origin
  • 具体分析:设置旋转容器的transform-origin为大圆容器中心点,同时利用两个元素在向不同方向旋转时旋转角度互相抵消的原理,实现图像沿环形路径旋转同时保持自身角度的不变。注意小圆距离大圆的距离由大圆的padding属性控制,调整padding时需要调整小圆的旋转原点transform-origin以保持环形路径的正确:地址
@keyframes spin {  to { transform: rotate(1turn); }
}
.avatar {  animation: spin 3s linear 2s infinite;  transform-origin: 110px 110px;
}
.avatar > img {  animation: inherit;  animation-direction: reverse;
}

环形路径移动的动画

笔者推荐css文章

其实现在社区已经不乏介绍 css 技巧的好文,这里推荐几篇我觉得写的极好的css技巧文章(当然可能大家也看过,很惭愧我其实现在也没看完):

总结

总体来说,《css揭秘》这本书并没有给我带来太大惊喜,个人感觉不如阅读《css世界》带来的收获多。当然了,这本书属于纯技巧型的,并没有讲述很多原理知识,所以也不能苛责吧。有兴趣的同学可以跟着我学习一波 css世界,相信肯定会有更大的收获~感谢平台分享-http://bjbsair.com/2020-04-10/tech-info/53257.html

《css揭秘》中讲了47个css技巧,其中有很多日常编码中并不会用到,本文除了将书中部分实用技巧罗列出来之外,还尝试用帮助读者搞明白background、animation 等常用但是却掌握不牢固的知识点。所以阅读本文不仅可以学习一些实用技巧,也可以巩固自己的 css 基础知识。

实用小技巧

DRY原则

全名Don’t Repeat Yourself,该原则适用于所有编程语言而不限于css。

扩大可点击区域

  • 关键实现:伪元素
  • 具体分析:利用伪元素和定位达到鼠标移到边缘时候出现手型且可点击
.expand-range {  position: relative;
}
.expand-range:after {  content: '';  position: absolute;  top: -10px; right: -10px; bottom: -10px; left: -10px;
}

推荐使用scss:

@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {  position: $position;  &:after {  content: '';  position: absolute;  top: $top;  right: $right;  bottom: $bottom;  left: $left;  }
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }

巧用层叠上下文

  • 关键实现: 伪元素 层叠上下文
  • 具体分析: 利用层叠上下文和 z-index: -1 特性实现伪元素覆盖背景同时又不会遮挡文字(具体实现原理参考这里 )。这是一个非常常用又好用的技巧,善加利用可以达到很多意想不到的效果。地址
  position: absolute;  top: 0; right: 0; bottom: 0; left: 0;  z-index: -1;

层叠上下文

边框内圆角

  • 关键实现:伪元素 层叠上下文
  • 具体分析:利用伪元素实现圆角矩形并叠加在父元素的背景之上文字之下:地址

边框内圆角

clip-path

  • 关键实现: clip-path
  • 具体分析:css3 新属性 clip-path 可以实现区域裁剪,现在浏览器支持较好的有三个函数:clip-path: circle(50px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个半径 50px 的圆;clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个横向半径 30px,纵向半径 40px 的椭圆;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) 按照多个坐标剪裁一个多边形,此处是菱形。有了 clip-path,就可以轻易的实现任意多边形了:地址

clip-path

自适应的椭圆

  • 关键实现:border-radius
  • 具体分析:border-radius 竟然可以设置 8 个角的半径~ 其中水平方向(对角线上下有弧度的地方)和垂直方向(对角线左右有弧度的地方)各四个,可以用 / 分割。如果水平或垂直方向指定的值少于四个,则会按照和 margin、padding 一样的规则重复。如果只指定来水平方向的,那么垂直方向的跟水平方向的一样。
    border-radius: 5em 1em; /*相当于border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/

自适应的椭圆

自适应宽度

  • 关键实现:min-content关键字
  • 具体分析:如何实现一个元素的宽度根据后代元素的最大固定元素宽度自适应呢?绞尽脑汁,也只能利用 display: inline-block 的包裹特性实现一个不完全的版本:地址 这种方法的缺陷是文本脱离了文档流,高度未计入包含块。但是如果利用 min-content 关键字,可以一行代码实现且无副作用:地址
  width: min-content;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-giHNiEqj-1586506402978)(http://p1.pstatp.com/large/pgc-image/cd37043f28b64ae699da8aea30b9b568)]

自适应宽度

投影模拟多重边框

  • 关键实现:box-shadow的inset
  • 具体分析:使用box-shadow可以模拟实现多重边框,但是由于阴影不占空间,所以无法触发点击事件,鼠标hover边框时无法出现小手,所以需要配合inset关键字使用:地址
  height: 200px;  background: cyan;  box-shadow: 0 0 0 5px #000 inset,  0 0 0 10px #555 inset,  0 0 0 15px #999 inset;

投影模拟多重边框

单侧投影

  • 关键实现:box-shadow
  • 具体分析:box-shadow 前两个参数指定阴影的x、y偏移量,注意若为正数时整体向右/向下偏移,那么相应的左方/上方会空出一部分来(可以用来隐藏模糊半径或扩张半径),负数相反;第三个参数是阴影模糊半径,即高斯模糊多增加出来的过度颜色;第四个参数是阴影扩张半径,表示阴影增加的尺寸,可以是负数,表示阴影缩短的尺寸:地址
  box-shadow: 0 5px 4px -4px black;

第二个参数使阴影整体下移 5px ,第三个参数使阴影四周多了 4px 的高斯模糊(注意由于整体下移了 5px,所以此时上方还是没有阴影露出的),第四个参数又把阴影整体缩小了 4px,,所以左右两边才没有出现模糊半径导致的高斯模糊阴影色,从而实现单侧投影。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GfjdIsdE-1586506402981)(http://p3.pstatp.com/large/pgc-image/84f74745080d4aec96a0b19b4766371a)]

单侧投影

还可以逗号分隔设置多个阴影色,比如下面的两侧投影效果:地址

  box-shadow: 5px 0 5px -5px black,  -5px 0 5px -5px black;

单侧投影

不规则投影

  • 关键实现:filter: drop-shadow()
  • 具体分析:box-shadow 不能透过透明背景显示出来,不能越过伪元素/子元素显示出来,而这些drop-shadow能做到。(但无论哪种投影都会被clip-path剪裁掉~~)地址
  filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));

不规则投影

滤镜的染色和褪色效果

前端开发大都了解糊滤的高斯模镜效果是filter: blur()实现的,但是却很少使用滤镜的其他几个调色效果。filter 的值有blur()、drop-shadow()、url()、brightness()、contrast()、grayscale()、hue-rotate()、invert()、opacity()、saturate()、sepia()~~可以使用复合形式如:filter: sepia(1) saturate(4)等。下面是filter属性值大集合:地址

滤镜的染色和褪色效果

饼图 svg

饼图的 css 实现方案非常奇怪,所以我忽略之。推荐使用 svg 的实现方案,非常简单,先来个基本教学吧~

先画个圆:

<svg width="100" height="100">  <circle r="25" cx="50" cy="50" />
</svg>

这里 r=“25” 是半径25, cx cy 分别表示圆心的 x y 坐标。

circle {  fill: yellowgreen;  stroke: #666;  stroke-width: 50;
}

这里给圆形定义了一个宽度 40 的描边:

饼图 svg

再把描边设为线段长度 20 间隔 10 的虚线:

circle {  ...  stroke-dasharray: 20 10;
}

当把虚线的间隔设定为大于等于圆周时,虚线的线段长度就是一个扇形区域(当线段长度等于圆周时扇区达到100%):

给 svg 设置圆角和背景色,并旋转 -90deg ,就可以实现一个饼图:地址(使用currentColor关键字和color: inherit 是为了实现DRY原则。)

但是这样的饼图其扇区大小是不易计算的,为了方便计算,可以让虚线的线段长度同时也是圆周无限接近100,这样就可以更方便的设置扇区的百分比。圆周是 2πr ,所以 100 = 2πr ,计算得出半径 r 近似值 16。再利用 svg 的 viewBox 属性,实现自适应容器大小的饼图:地址

这种方法有个弊端,就是当设置 stroke-dasharray: 100 100 时会有一条缝,这是取近似值无法避免的。

背景background

background 是我们最常用的属性之一,但作为一个老前端,我也只能羞耻的说我目前并没有完全掌握这个属性。

background 是一个简写属性,可以包括多个属性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment。接下来我们一个个来看看这些属性的作用:

  • background-color 最常用的属性,默认不继承(background的所有属性都默认不继承),初始值为 transparent;有时候使用默认继承可以实现一些好玩的效果,比如倒影;
  • backgroundo-image 背景图片,可以逗号分割设置多个,可以是图片url或者渐变色;
  • background-clip 背景剪裁,可以逗号分割设置多个,值可以为 broder-box(初始值)、padding-box、content-box、text(新,将背景被文字剪裁);
  • background-origin 设置背景起始点的相对区域,搭配 background-position使用,可以逗号分割设置多个,值可以是border-box、padding-box(初始值)、content-box;
  • background-position 设置背景的起始点,可以逗号分割设置多个,值可以是 10px 20px 、center center 、left 10px bottom 20px等等,非常灵活;
  • background-size 设置背景的大小,可以逗号分割设置多个,值可以是数字值如30px 40px、auto auto(初始值)、conver、contain;background-repeat: repeat就是根据这个尺寸大小来重复的。
  • background-repeat 设置背景的重复方式,初始值为 repeat,常使用值的还有no-repeat;
  • background-attachment 设置背景图像的位置是在视口内固定,还是随着包含它的区块滚动。可以逗号分割设置多个,值有scroll(初始值)、local、fixed。详情查看MDN

简写时 background-size 只能紧接着 background-position 出现,以 / 分割,如: “center / 80%”。

半透明边框

  • 关键实现:background-clip
  • 具体分析:由于background属性默认会覆盖整个盒模型包括边框border,所以设置border-color: rgba(0, 0, 0, .5)时会透出背景色,达不到半透明边框的效果。css3增加了background-clip属性,定义背景填充的裁剪区域。设置padding-box便可以实现半透明边框:地址
  border: 10px solid rgba(255, 255, 255, .5);  background: white;  background-clip: padding-box;

半透明边框

灵活的背景定位

  • 关键实现:backgrond-position background-origin
  • 具体分析:我们都知道background-position可以定位背景图片等位置,但是都是相对padding-box的左上角开始等。css3 允许这样写:background-position: right 10px bottom 20px,同时 css3 还支持background-origin,其默认值如同其表现border-box,支持设为padding-box和content-box:地址
  height: 200px;  padding: 10px;  border: 5px solid cyan;  background: lightblue;  background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;  background-origin: content-box;

背景定位

background-position 设为百分比值较为复杂。百分比值实际上执行了以下的计算公式:

(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)

由计算公式可知:当值为0%时,实际偏移值为0px,此时图片的左边界(或上边界)和容器的左边界(或上边界)重合;当值为50%时,实际偏移值为容器减图片剩余空间的一半,图片左右边界(或上下边界)距离容器左右边界(或上下边界)相等,此时图片的中点和容器的中点重合。当值100%时,实际偏移值为容器减图片的剩余空间,所以此时图片的右边界(或下边界)和容器的右边界(或下边界)重合。二者之差为负值时同样有效。地址

背景定位

条纹背景

  • 关键实现:background-image
  • 实现分析:利用线性渐变实现多种颜色的交错重复,形成条纹背景。lienar-gradient的第一个参数是渐变的角度,可以是方向关键字to top(初始值,可忽略不写)等,也可以是角度90deg等;#fb3 50%指的是色标和终点位置值;这里linear-gradient的第二个位置值设置为0会被解析为前一个色标的位置值即50%,这样写更加符合DRY原则。
background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;

条纹背景

也可以设置为垂直条纹背景:

background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;

还可以设置为斜向条纹:

background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;

垂直条纹背景

斜向条纹需要设置四条条纹才能在平铺到时候做到无缝拼接。

更好的斜向条纹:(这里必须设置起始值#fb3 0)

background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);

更好的斜向条纹

网格

  • 关键实现:background-image、background-size
  • 给多个渐变设置不同的方向、大小,可以实现网格的效果。地址
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),  linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;

网格

更好的网格:

background: #58a;
background-image: linear-gradient(white 2px, transparent 0),  linear-gradient(to right, white 2px, transparent 0),  linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),  linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;

更好的网格

棋盘

  • 关键实现:background-image、background-size、background-position
  • 具体分析:给多个渐变设置不同的大小、位置,可以实现网格的效果。地址
  background: #eee;  background-image:  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

棋盘

折角

  • 关键实现:线性渐变
  • 具体分析:150deg 是为了形成30度角,方便利用勾股定理测出各种长度,其他的靠你自己看了~ 地址

折角

到这里 background 属性基本讲完了,光看无用,多动手实践吧。

波点

  • 关键实现:径向渐变
  • 具体分析:利用径向渐变实现一个个小圆点,按规律摆放即能生成波点 地址
  background:  radial-gradient(tan 30%, transparent 0),  radial-gradient(tan 30%, transparent 0);  background-color: #666;  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

波点

切角

  • 关键实现:clip-path、径向渐变
  • 具体分析:一般来说多边形的切角效果(其实还是不规则多边形)用clip-path都可以轻松实现,但是对于圆形的切角,使用径向渐变是最好的选择。但是如果有弧形的切角呢?radial-linear第一个参数指定渐变的起始点点(默认为中心点),同时可指定渐变类型是椭圆还是圆;地址
  background:  radial-gradient(circle at top left, transparent 15px, blue 0) top left,  radial-gradient(circle at top right, transparent 15px, cyan 0) top right,  radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,  radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;  background-size: 50% 50%;  background-repeat: no-repeat;

切角

饼图

  • 关键实现:锥形渐变
  • 具体分析:利用锥形渐变可以轻松实现多个扇区,所以 svg 的方法权当学习了一波 svg 用法吧。
  background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fjwvynEr-1586506403007)(http://p3.pstatp.com/large/pgc-image/a38bf9e102fe45abbe49939d5a9fbcbd)]

饼图

动画animation

animation 属性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state属性的一个简写属性形式。

  • animation-name 指定动画的名称,可以逗号分割设置多个(以下皆可);
  • animation-duration 指定动画运行的时间;
  • animation-delay 指定动画执行前的延时;
  • animation-timing-function 指定动画执行的速度函数,如linear、ease(默认)、ease-in-out等,也可用贝塞尔函数cubic-bezier();
  • animation-iteration-count 指定动画的运行的次数,默认为1,可以为Infinite无限次;
  • animation-direction 指定动画是否反方向播放,normal 正常的顺序,alternate 交替运行,reverse 反向运行,alternate-reverse 反向交替运行;
  • animation-fill-mode 设置CSS动画在执行之前和之后的样式,none 不设置,forwards 保留最后一帧动画的样式,backwards 立即应用第一个关键帧中定义的值,并在animation-delay期间保留此值,both 同时应用forwards和backwards的规则;
  • animation-play-state 定义一个动画是否运行或者暂停,值为running、paused。

回弹效果

如何给动画加上回弹效果呢?这里介绍一种最便利的方法:

  • 关键实现:cubic-bezier(x1, y1, x2, y2)
  • 具体分析:利用贝塞尔曲线的第二个控制锚点大于 1 时的特性实现回弹

回弹效果

上图图横轴为时间,纵轴为动画进度。图中贝塞尔曲线有两个控制手柄,x1, y1 控制第一个锚点,x2, y2控制第二个锚点。其中 x1 、x2 不能大于/小于 1,但是y1, y2 可以。当 y2 大于 1 时,就会产生提前到达终点,然后超过终点,然后再返回终点的效果,像回弹一样。地址

  animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);

transition 属性是 transition-property、transition-duration、transition-timing-function、transition-delay的一个简写属性。使用 transition 同样可以实现回弹效果:地址

p {  transform-origin: 1.4em -.4em;  transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}  input:not(:focus) + p {  transform: scale(0);  transition: transform 300ms; /*此处是为了缩小时重置transition-timing-function,不触发回弹*/
}

会动的背景

  • 关键实现:animation、background-position
  • 具体分析:将动画最后一帧的background-position设为100% 0%,动画便会将背景位置从最初的0% 0%向最后的100% 0%过度:地址
div {  width: 150px; height: 150px;  background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');  background-size: auto 100%;   animation: panoramic 10s linear infinite alternate;
}
div:hover {  animation-play-state: paused;
}  @keyframes panoramic {  to { background-position: 100% 0; }
}

环形路径移动的动画

  • 关键实现:animation transform-origin
  • 具体分析:设置旋转容器的transform-origin为大圆容器中心点,同时利用两个元素在向不同方向旋转时旋转角度互相抵消的原理,实现图像沿环形路径旋转同时保持自身角度的不变。注意小圆距离大圆的距离由大圆的padding属性控制,调整padding时需要调整小圆的旋转原点transform-origin以保持环形路径的正确:地址
@keyframes spin {  to { transform: rotate(1turn); }
}
.avatar {  animation: spin 3s linear 2s infinite;  transform-origin: 110px 110px;
}
.avatar > img {  animation: inherit;  animation-direction: reverse;
}

环形路径移动的动画

笔者推荐css文章

其实现在社区已经不乏介绍 css 技巧的好文,这里推荐几篇我觉得写的极好的css技巧文章(当然可能大家也看过,很惭愧我其实现在也没看完):

总结

总体来说,《css揭秘》这本书并没有给我带来太大惊喜,个人感觉不如阅读《css世界》带来的收获多。当然了,这本书属于纯技巧型的,并没有讲述很多原理知识,所以也不能苛责吧。有兴趣的同学可以跟着我学习一波 css世界,相信肯定会有更大的收获~感谢平台分享-http://bjbsair.com/2020-04-10/tech-info/53257.html

《css揭秘》中讲了47个css技巧,其中有很多日常编码中并不会用到,本文除了将书中部分实用技巧罗列出来之外,还尝试用帮助读者搞明白background、animation 等常用但是却掌握不牢固的知识点。所以阅读本文不仅可以学习一些实用技巧,也可以巩固自己的 css 基础知识。

实用小技巧

DRY原则

全名Don’t Repeat Yourself,该原则适用于所有编程语言而不限于css。

扩大可点击区域

  • 关键实现:伪元素
  • 具体分析:利用伪元素和定位达到鼠标移到边缘时候出现手型且可点击
.expand-range {  position: relative;
}
.expand-range:after {  content: '';  position: absolute;  top: -10px; right: -10px; bottom: -10px; left: -10px;
}

推荐使用scss:

@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {  position: $position;  &:after {  content: '';  position: absolute;  top: $top;  right: $right;  bottom: $bottom;  left: $left;  }
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }

巧用层叠上下文

  • 关键实现: 伪元素 层叠上下文
  • 具体分析: 利用层叠上下文和 z-index: -1 特性实现伪元素覆盖背景同时又不会遮挡文字(具体实现原理参考这里 )。这是一个非常常用又好用的技巧,善加利用可以达到很多意想不到的效果。地址
  position: absolute;  top: 0; right: 0; bottom: 0; left: 0;  z-index: -1;

层叠上下文

边框内圆角

  • 关键实现:伪元素 层叠上下文
  • 具体分析:利用伪元素实现圆角矩形并叠加在父元素的背景之上文字之下:地址

边框内圆角

clip-path

  • 关键实现: clip-path
  • 具体分析:css3 新属性 clip-path 可以实现区域裁剪,现在浏览器支持较好的有三个函数:clip-path: circle(50px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个半径 50px 的圆;clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个横向半径 30px,纵向半径 40px 的椭圆;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) 按照多个坐标剪裁一个多边形,此处是菱形。有了 clip-path,就可以轻易的实现任意多边形了:地址

clip-path

自适应的椭圆

  • 关键实现:border-radius
  • 具体分析:border-radius 竟然可以设置 8 个角的半径~ 其中水平方向(对角线上下有弧度的地方)和垂直方向(对角线左右有弧度的地方)各四个,可以用 / 分割。如果水平或垂直方向指定的值少于四个,则会按照和 margin、padding 一样的规则重复。如果只指定来水平方向的,那么垂直方向的跟水平方向的一样。
    border-radius: 5em 1em; /*相当于border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/

自适应的椭圆

自适应宽度

  • 关键实现:min-content关键字
  • 具体分析:如何实现一个元素的宽度根据后代元素的最大固定元素宽度自适应呢?绞尽脑汁,也只能利用 display: inline-block 的包裹特性实现一个不完全的版本:地址 这种方法的缺陷是文本脱离了文档流,高度未计入包含块。但是如果利用 min-content 关键字,可以一行代码实现且无副作用:地址
  width: min-content;

自适应宽度

投影模拟多重边框

  • 关键实现:box-shadow的inset
  • 具体分析:使用box-shadow可以模拟实现多重边框,但是由于阴影不占空间,所以无法触发点击事件,鼠标hover边框时无法出现小手,所以需要配合inset关键字使用:地址
  height: 200px;  background: cyan;  box-shadow: 0 0 0 5px #000 inset,  0 0 0 10px #555 inset,  0 0 0 15px #999 inset;

投影模拟多重边框

单侧投影

  • 关键实现:box-shadow
  • 具体分析:box-shadow 前两个参数指定阴影的x、y偏移量,注意若为正数时整体向右/向下偏移,那么相应的左方/上方会空出一部分来(可以用来隐藏模糊半径或扩张半径),负数相反;第三个参数是阴影模糊半径,即高斯模糊多增加出来的过度颜色;第四个参数是阴影扩张半径,表示阴影增加的尺寸,可以是负数,表示阴影缩短的尺寸:地址
  box-shadow: 0 5px 4px -4px black;

第二个参数使阴影整体下移 5px ,第三个参数使阴影四周多了 4px 的高斯模糊(注意由于整体下移了 5px,所以此时上方还是没有阴影露出的),第四个参数又把阴影整体缩小了 4px,,所以左右两边才没有出现模糊半径导致的高斯模糊阴影色,从而实现单侧投影。

单侧投影

还可以逗号分隔设置多个阴影色,比如下面的两侧投影效果:地址

  box-shadow: 5px 0 5px -5px black,  -5px 0 5px -5px black;

单侧投影

不规则投影

  • 关键实现:filter: drop-shadow()
  • 具体分析:box-shadow 不能透过透明背景显示出来,不能越过伪元素/子元素显示出来,而这些drop-shadow能做到。(但无论哪种投影都会被clip-path剪裁掉~~)地址
  filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));

不规则投影

滤镜的染色和褪色效果

前端开发大都了解糊滤的高斯模镜效果是filter: blur()实现的,但是却很少使用滤镜的其他几个调色效果。filter 的值有blur()、drop-shadow()、url()、brightness()、contrast()、grayscale()、hue-rotate()、invert()、opacity()、saturate()、sepia()~~可以使用复合形式如:filter: sepia(1) saturate(4)等。下面是filter属性值大集合:地址

滤镜的染色和褪色效果

饼图 svg

饼图的 css 实现方案非常奇怪,所以我忽略之。推荐使用 svg 的实现方案,非常简单,先来个基本教学吧~

先画个圆:

<svg width="100" height="100">  <circle r="25" cx="50" cy="50" />
</svg>

这里 r=“25” 是半径25, cx cy 分别表示圆心的 x y 坐标。

circle {  fill: yellowgreen;  stroke: #666;  stroke-width: 50;
}

这里给圆形定义了一个宽度 40 的描边:

饼图 svg

再把描边设为线段长度 20 间隔 10 的虚线:

circle {  ...  stroke-dasharray: 20 10;
}

当把虚线的间隔设定为大于等于圆周时,虚线的线段长度就是一个扇形区域(当线段长度等于圆周时扇区达到100%):

给 svg 设置圆角和背景色,并旋转 -90deg ,就可以实现一个饼图:地址(使用currentColor关键字和color: inherit 是为了实现DRY原则。)

但是这样的饼图其扇区大小是不易计算的,为了方便计算,可以让虚线的线段长度同时也是圆周无限接近100,这样就可以更方便的设置扇区的百分比。圆周是 2πr ,所以 100 = 2πr ,计算得出半径 r 近似值 16。再利用 svg 的 viewBox 属性,实现自适应容器大小的饼图:地址

这种方法有个弊端,就是当设置 stroke-dasharray: 100 100 时会有一条缝,这是取近似值无法避免的。

背景background

background 是我们最常用的属性之一,但作为一个老前端,我也只能羞耻的说我目前并没有完全掌握这个属性。

background 是一个简写属性,可以包括多个属性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment。接下来我们一个个来看看这些属性的作用:

  • background-color 最常用的属性,默认不继承(background的所有属性都默认不继承),初始值为 transparent;有时候使用默认继承可以实现一些好玩的效果,比如倒影;
  • backgroundo-image 背景图片,可以逗号分割设置多个,可以是图片url或者渐变色;
  • background-clip 背景剪裁,可以逗号分割设置多个,值可以为 broder-box(初始值)、padding-box、content-box、text(新,将背景被文字剪裁);
  • background-origin 设置背景起始点的相对区域,搭配 background-position使用,可以逗号分割设置多个,值可以是border-box、padding-box(初始值)、content-box;
  • background-position 设置背景的起始点,可以逗号分割设置多个,值可以是 10px 20px 、center center 、left 10px bottom 20px等等,非常灵活;
  • background-size 设置背景的大小,可以逗号分割设置多个,值可以是数字值如30px 40px、auto auto(初始值)、conver、contain;background-repeat: repeat就是根据这个尺寸大小来重复的。
  • background-repeat 设置背景的重复方式,初始值为 repeat,常使用值的还有no-repeat;
  • background-attachment 设置背景图像的位置是在视口内固定,还是随着包含它的区块滚动。可以逗号分割设置多个,值有scroll(初始值)、local、fixed。详情查看MDN

简写时 background-size 只能紧接着 background-position 出现,以 / 分割,如: “center / 80%”。

半透明边框

  • 关键实现:background-clip
  • 具体分析:由于background属性默认会覆盖整个盒模型包括边框border,所以设置border-color: rgba(0, 0, 0, .5)时会透出背景色,达不到半透明边框的效果。css3增加了background-clip属性,定义背景填充的裁剪区域。设置padding-box便可以实现半透明边框:地址
  border: 10px solid rgba(255, 255, 255, .5);  background: white;  background-clip: padding-box;

半透明边框

灵活的背景定位

  • 关键实现:backgrond-position background-origin
  • 具体分析:我们都知道background-position可以定位背景图片等位置,但是都是相对padding-box的左上角开始等。css3 允许这样写:background-position: right 10px bottom 20px,同时 css3 还支持background-origin,其默认值如同其表现border-box,支持设为padding-box和content-box:地址
  height: 200px;  padding: 10px;  border: 5px solid cyan;  background: lightblue;  background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;  background-origin: content-box;

背景定位

background-position 设为百分比值较为复杂。百分比值实际上执行了以下的计算公式:

(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)

由计算公式可知:当值为0%时,实际偏移值为0px,此时图片的左边界(或上边界)和容器的左边界(或上边界)重合;当值为50%时,实际偏移值为容器减图片剩余空间的一半,图片左右边界(或上下边界)距离容器左右边界(或上下边界)相等,此时图片的中点和容器的中点重合。当值100%时,实际偏移值为容器减图片的剩余空间,所以此时图片的右边界(或下边界)和容器的右边界(或下边界)重合。二者之差为负值时同样有效。地址

背景定位

条纹背景

  • 关键实现:background-image
  • 实现分析:利用线性渐变实现多种颜色的交错重复,形成条纹背景。lienar-gradient的第一个参数是渐变的角度,可以是方向关键字to top(初始值,可忽略不写)等,也可以是角度90deg等;#fb3 50%指的是色标和终点位置值;这里linear-gradient的第二个位置值设置为0会被解析为前一个色标的位置值即50%,这样写更加符合DRY原则。
background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;

条纹背景

也可以设置为垂直条纹背景:

background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;

还可以设置为斜向条纹:

background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;

垂直条纹背景

斜向条纹需要设置四条条纹才能在平铺到时候做到无缝拼接。

更好的斜向条纹:(这里必须设置起始值#fb3 0)

background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);

更好的斜向条纹

网格

  • 关键实现:background-image、background-size
  • 给多个渐变设置不同的方向、大小,可以实现网格的效果。地址
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),  linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;

网格

更好的网格:

background: #58a;
background-image: linear-gradient(white 2px, transparent 0),  linear-gradient(to right, white 2px, transparent 0),  linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),  linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;

更好的网格

棋盘

  • 关键实现:background-image、background-size、background-position
  • 具体分析:给多个渐变设置不同的大小、位置,可以实现网格的效果。地址
  background: #eee;  background-image:  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

棋盘

折角

  • 关键实现:线性渐变
  • 具体分析:150deg 是为了形成30度角,方便利用勾股定理测出各种长度,其他的靠你自己看了~ 地址

折角

到这里 background 属性基本讲完了,光看无用,多动手实践吧。

波点

  • 关键实现:径向渐变
  • 具体分析:利用径向渐变实现一个个小圆点,按规律摆放即能生成波点 地址
  background:  radial-gradient(tan 30%, transparent 0),  radial-gradient(tan 30%, transparent 0);  background-color: #666;  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

波点

切角

  • 关键实现:clip-path、径向渐变
  • 具体分析:一般来说多边形的切角效果(其实还是不规则多边形)用clip-path都可以轻松实现,但是对于圆形的切角,使用径向渐变是最好的选择。但是如果有弧形的切角呢?radial-linear第一个参数指定渐变的起始点点(默认为中心点),同时可指定渐变类型是椭圆还是圆;地址
  background:  radial-gradient(circle at top left, transparent 15px, blue 0) top left,  radial-gradient(circle at top right, transparent 15px, cyan 0) top right,  radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,  radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;  background-size: 50% 50%;  background-repeat: no-repeat;

切角

饼图

  • 关键实现:锥形渐变
  • 具体分析:利用锥形渐变可以轻松实现多个扇区,所以 svg 的方法权当学习了一波 svg 用法吧。
  background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ecHfzw1B-1586506403680)(http://p3.pstatp.com/large/pgc-image/a38bf9e102fe45abbe49939d5a9fbcbd)]

饼图

动画animation

animation 属性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state属性的一个简写属性形式。

  • animation-name 指定动画的名称,可以逗号分割设置多个(以下皆可);
  • animation-duration 指定动画运行的时间;
  • animation-delay 指定动画执行前的延时;
  • animation-timing-function 指定动画执行的速度函数,如linear、ease(默认)、ease-in-out等,也可用贝塞尔函数cubic-bezier();
  • animation-iteration-count 指定动画的运行的次数,默认为1,可以为Infinite无限次;
  • animation-direction 指定动画是否反方向播放,normal 正常的顺序,alternate 交替运行,reverse 反向运行,alternate-reverse 反向交替运行;
  • animation-fill-mode 设置CSS动画在执行之前和之后的样式,none 不设置,forwards 保留最后一帧动画的样式,backwards 立即应用第一个关键帧中定义的值,并在animation-delay期间保留此值,both 同时应用forwards和backwards的规则;
  • animation-play-state 定义一个动画是否运行或者暂停,值为running、paused。

回弹效果

如何给动画加上回弹效果呢?这里介绍一种最便利的方法:

  • 关键实现:cubic-bezier(x1, y1, x2, y2)
  • 具体分析:利用贝塞尔曲线的第二个控制锚点大于 1 时的特性实现回弹

回弹效果

上图图横轴为时间,纵轴为动画进度。图中贝塞尔曲线有两个控制手柄,x1, y1 控制第一个锚点,x2, y2控制第二个锚点。其中 x1 、x2 不能大于/小于 1,但是y1, y2 可以。当 y2 大于 1 时,就会产生提前到达终点,然后超过终点,然后再返回终点的效果,像回弹一样。地址

  animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);

transition 属性是 transition-property、transition-duration、transition-timing-function、transition-delay的一个简写属性。使用 transition 同样可以实现回弹效果:地址

p {  transform-origin: 1.4em -.4em;  transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}  input:not(:focus) + p {  transform: scale(0);  transition: transform 300ms; /*此处是为了缩小时重置transition-timing-function,不触发回弹*/
}

会动的背景

  • 关键实现:animation、background-position
  • 具体分析:将动画最后一帧的background-position设为100% 0%,动画便会将背景位置从最初的0% 0%向最后的100% 0%过度:地址
div {  width: 150px; height: 150px;  background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');  background-size: auto 100%;   animation: panoramic 10s linear infinite alternate;
}
div:hover {  animation-play-state: paused;
}  @keyframes panoramic {  to { background-position: 100% 0; }
}

环形路径移动的动画

  • 关键实现:animation transform-origin
  • 具体分析:设置旋转容器的transform-origin为大圆容器中心点,同时利用两个元素在向不同方向旋转时旋转角度互相抵消的原理,实现图像沿环形路径旋转同时保持自身角度的不变。注意小圆距离大圆的距离由大圆的padding属性控制,调整padding时需要调整小圆的旋转原点transform-origin以保持环形路径的正确:地址
@keyframes spin {  to { transform: rotate(1turn); }
}
.avatar {  animation: spin 3s linear 2s infinite;  transform-origin: 110px 110px;
}
.avatar > img {  animation: inherit;  animation-direction: reverse;
}

环形路径移动的动画

笔者推荐css文章

其实现在社区已经不乏介绍 css 技巧的好文,这里推荐几篇我觉得写的极好的css技巧文章(当然可能大家也看过,很惭愧我其实现在也没看完):

总结

总体来说,《css揭秘》这本书并没有给我带来太大惊喜,个人感觉不如阅读《css世界》带来的收获多。当然了,这本书属于纯技巧型的,并没有讲述很多原理知识,所以也不能苛责吧。有兴趣的同学可以跟着我学习一波 css世界,相信肯定会有更大的收获~感谢平台分享-http://bjbsair.com/2020-04-10/tech-info/53257.html

《css揭秘》中讲了47个css技巧,其中有很多日常编码中并不会用到,本文除了将书中部分实用技巧罗列出来之外,还尝试用帮助读者搞明白background、animation 等常用但是却掌握不牢固的知识点。所以阅读本文不仅可以学习一些实用技巧,也可以巩固自己的 css 基础知识。

实用小技巧

DRY原则

全名Don’t Repeat Yourself,该原则适用于所有编程语言而不限于css。

扩大可点击区域

  • 关键实现:伪元素
  • 具体分析:利用伪元素和定位达到鼠标移到边缘时候出现手型且可点击
.expand-range {  position: relative;
}
.expand-range:after {  content: '';  position: absolute;  top: -10px; right: -10px; bottom: -10px; left: -10px;
}

推荐使用scss:

@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {  position: $position;  &:after {  content: '';  position: absolute;  top: $top;  right: $right;  bottom: $bottom;  left: $left;  }
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }

巧用层叠上下文

  • 关键实现: 伪元素 层叠上下文
  • 具体分析: 利用层叠上下文和 z-index: -1 特性实现伪元素覆盖背景同时又不会遮挡文字(具体实现原理参考这里 )。这是一个非常常用又好用的技巧,善加利用可以达到很多意想不到的效果。地址
  position: absolute;  top: 0; right: 0; bottom: 0; left: 0;  z-index: -1;

层叠上下文

边框内圆角

  • 关键实现:伪元素 层叠上下文
  • 具体分析:利用伪元素实现圆角矩形并叠加在父元素的背景之上文字之下:地址

边框内圆角

clip-path

  • 关键实现: clip-path
  • 具体分析:css3 新属性 clip-path 可以实现区域裁剪,现在浏览器支持较好的有三个函数:clip-path: circle(50px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个半径 50px 的圆;clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个横向半径 30px,纵向半径 40px 的椭圆;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) 按照多个坐标剪裁一个多边形,此处是菱形。有了 clip-path,就可以轻易的实现任意多边形了:地址

clip-path

自适应的椭圆

  • 关键实现:border-radius
  • 具体分析:border-radius 竟然可以设置 8 个角的半径~ 其中水平方向(对角线上下有弧度的地方)和垂直方向(对角线左右有弧度的地方)各四个,可以用 / 分割。如果水平或垂直方向指定的值少于四个,则会按照和 margin、padding 一样的规则重复。如果只指定来水平方向的,那么垂直方向的跟水平方向的一样。
    border-radius: 5em 1em; /*相当于border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/

自适应的椭圆

自适应宽度

  • 关键实现:min-content关键字
  • 具体分析:如何实现一个元素的宽度根据后代元素的最大固定元素宽度自适应呢?绞尽脑汁,也只能利用 display: inline-block 的包裹特性实现一个不完全的版本:地址 这种方法的缺陷是文本脱离了文档流,高度未计入包含块。但是如果利用 min-content 关键字,可以一行代码实现且无副作用:地址
  width: min-content;

自适应宽度

投影模拟多重边框

  • 关键实现:box-shadow的inset
  • 具体分析:使用box-shadow可以模拟实现多重边框,但是由于阴影不占空间,所以无法触发点击事件,鼠标hover边框时无法出现小手,所以需要配合inset关键字使用:地址
  height: 200px;  background: cyan;  box-shadow: 0 0 0 5px #000 inset,  0 0 0 10px #555 inset,  0 0 0 15px #999 inset;

投影模拟多重边框

单侧投影

  • 关键实现:box-shadow
  • 具体分析:box-shadow 前两个参数指定阴影的x、y偏移量,注意若为正数时整体向右/向下偏移,那么相应的左方/上方会空出一部分来(可以用来隐藏模糊半径或扩张半径),负数相反;第三个参数是阴影模糊半径,即高斯模糊多增加出来的过度颜色;第四个参数是阴影扩张半径,表示阴影增加的尺寸,可以是负数,表示阴影缩短的尺寸:地址
  box-shadow: 0 5px 4px -4px black;

第二个参数使阴影整体下移 5px ,第三个参数使阴影四周多了 4px 的高斯模糊(注意由于整体下移了 5px,所以此时上方还是没有阴影露出的),第四个参数又把阴影整体缩小了 4px,,所以左右两边才没有出现模糊半径导致的高斯模糊阴影色,从而实现单侧投影。

单侧投影

还可以逗号分隔设置多个阴影色,比如下面的两侧投影效果:地址

  box-shadow: 5px 0 5px -5px black,  -5px 0 5px -5px black;

单侧投影

不规则投影

  • 关键实现:filter: drop-shadow()
  • 具体分析:box-shadow 不能透过透明背景显示出来,不能越过伪元素/子元素显示出来,而这些drop-shadow能做到。(但无论哪种投影都会被clip-path剪裁掉~~)地址
  filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));

不规则投影

滤镜的染色和褪色效果

前端开发大都了解糊滤的高斯模镜效果是filter: blur()实现的,但是却很少使用滤镜的其他几个调色效果。filter 的值有blur()、drop-shadow()、url()、brightness()、contrast()、grayscale()、hue-rotate()、invert()、opacity()、saturate()、sepia()~~可以使用复合形式如:filter: sepia(1) saturate(4)等。下面是filter属性值大集合:地址

滤镜的染色和褪色效果

饼图 svg

饼图的 css 实现方案非常奇怪,所以我忽略之。推荐使用 svg 的实现方案,非常简单,先来个基本教学吧~

先画个圆:

<svg width="100" height="100">  <circle r="25" cx="50" cy="50" />
</svg>

这里 r=“25” 是半径25, cx cy 分别表示圆心的 x y 坐标。

circle {  fill: yellowgreen;  stroke: #666;  stroke-width: 50;
}

这里给圆形定义了一个宽度 40 的描边:

饼图 svg

再把描边设为线段长度 20 间隔 10 的虚线:

circle {  ...  stroke-dasharray: 20 10;
}

当把虚线的间隔设定为大于等于圆周时,虚线的线段长度就是一个扇形区域(当线段长度等于圆周时扇区达到100%):

给 svg 设置圆角和背景色,并旋转 -90deg ,就可以实现一个饼图:地址(使用currentColor关键字和color: inherit 是为了实现DRY原则。)

但是这样的饼图其扇区大小是不易计算的,为了方便计算,可以让虚线的线段长度同时也是圆周无限接近100,这样就可以更方便的设置扇区的百分比。圆周是 2πr ,所以 100 = 2πr ,计算得出半径 r 近似值 16。再利用 svg 的 viewBox 属性,实现自适应容器大小的饼图:地址

这种方法有个弊端,就是当设置 stroke-dasharray: 100 100 时会有一条缝,这是取近似值无法避免的。

背景background

background 是我们最常用的属性之一,但作为一个老前端,我也只能羞耻的说我目前并没有完全掌握这个属性。

background 是一个简写属性,可以包括多个属性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment。接下来我们一个个来看看这些属性的作用:

  • background-color 最常用的属性,默认不继承(background的所有属性都默认不继承),初始值为 transparent;有时候使用默认继承可以实现一些好玩的效果,比如倒影;
  • backgroundo-image 背景图片,可以逗号分割设置多个,可以是图片url或者渐变色;
  • background-clip 背景剪裁,可以逗号分割设置多个,值可以为 broder-box(初始值)、padding-box、content-box、text(新,将背景被文字剪裁);
  • background-origin 设置背景起始点的相对区域,搭配 background-position使用,可以逗号分割设置多个,值可以是border-box、padding-box(初始值)、content-box;
  • background-position 设置背景的起始点,可以逗号分割设置多个,值可以是 10px 20px 、center center 、left 10px bottom 20px等等,非常灵活;
  • background-size 设置背景的大小,可以逗号分割设置多个,值可以是数字值如30px 40px、auto auto(初始值)、conver、contain;background-repeat: repeat就是根据这个尺寸大小来重复的。
  • background-repeat 设置背景的重复方式,初始值为 repeat,常使用值的还有no-repeat;
  • background-attachment 设置背景图像的位置是在视口内固定,还是随着包含它的区块滚动。可以逗号分割设置多个,值有scroll(初始值)、local、fixed。详情查看MDN

简写时 background-size 只能紧接着 background-position 出现,以 / 分割,如: “center / 80%”。

半透明边框

  • 关键实现:background-clip
  • 具体分析:由于background属性默认会覆盖整个盒模型包括边框border,所以设置border-color: rgba(0, 0, 0, .5)时会透出背景色,达不到半透明边框的效果。css3增加了background-clip属性,定义背景填充的裁剪区域。设置padding-box便可以实现半透明边框:地址
  border: 10px solid rgba(255, 255, 255, .5);  background: white;  background-clip: padding-box;

半透明边框

灵活的背景定位

  • 关键实现:backgrond-position background-origin
  • 具体分析:我们都知道background-position可以定位背景图片等位置,但是都是相对padding-box的左上角开始等。css3 允许这样写:background-position: right 10px bottom 20px,同时 css3 还支持background-origin,其默认值如同其表现border-box,支持设为padding-box和content-box:地址
  height: 200px;  padding: 10px;  border: 5px solid cyan;  background: lightblue;  background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;  background-origin: content-box;

背景定位

background-position 设为百分比值较为复杂。百分比值实际上执行了以下的计算公式:

(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)

由计算公式可知:当值为0%时,实际偏移值为0px,此时图片的左边界(或上边界)和容器的左边界(或上边界)重合;当值为50%时,实际偏移值为容器减图片剩余空间的一半,图片左右边界(或上下边界)距离容器左右边界(或上下边界)相等,此时图片的中点和容器的中点重合。当值100%时,实际偏移值为容器减图片的剩余空间,所以此时图片的右边界(或下边界)和容器的右边界(或下边界)重合。二者之差为负值时同样有效。地址

背景定位

条纹背景

  • 关键实现:background-image
  • 实现分析:利用线性渐变实现多种颜色的交错重复,形成条纹背景。lienar-gradient的第一个参数是渐变的角度,可以是方向关键字to top(初始值,可忽略不写)等,也可以是角度90deg等;#fb3 50%指的是色标和终点位置值;这里linear-gradient的第二个位置值设置为0会被解析为前一个色标的位置值即50%,这样写更加符合DRY原则。
background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;

条纹背景

也可以设置为垂直条纹背景:

background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;

还可以设置为斜向条纹:

background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;

垂直条纹背景

斜向条纹需要设置四条条纹才能在平铺到时候做到无缝拼接。

更好的斜向条纹:(这里必须设置起始值#fb3 0)

background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);

更好的斜向条纹

网格

  • 关键实现:background-image、background-size
  • 给多个渐变设置不同的方向、大小,可以实现网格的效果。地址
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),  linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;

网格

更好的网格:

background: #58a;
background-image: linear-gradient(white 2px, transparent 0),  linear-gradient(to right, white 2px, transparent 0),  linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),  linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;

更好的网格

棋盘

  • 关键实现:background-image、background-size、background-position
  • 具体分析:给多个渐变设置不同的大小、位置,可以实现网格的效果。地址
  background: #eee;  background-image:  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

棋盘

折角

  • 关键实现:线性渐变
  • 具体分析:150deg 是为了形成30度角,方便利用勾股定理测出各种长度,其他的靠你自己看了~ 地址

折角

到这里 background 属性基本讲完了,光看无用,多动手实践吧。

波点

  • 关键实现:径向渐变
  • 具体分析:利用径向渐变实现一个个小圆点,按规律摆放即能生成波点 地址
  background:  radial-gradient(tan 30%, transparent 0),  radial-gradient(tan 30%, transparent 0);  background-color: #666;  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

波点

切角

  • 关键实现:clip-path、径向渐变
  • 具体分析:一般来说多边形的切角效果(其实还是不规则多边形)用clip-path都可以轻松实现,但是对于圆形的切角,使用径向渐变是最好的选择。但是如果有弧形的切角呢?radial-linear第一个参数指定渐变的起始点点(默认为中心点),同时可指定渐变类型是椭圆还是圆;地址
  background:  radial-gradient(circle at top left, transparent 15px, blue 0) top left,  radial-gradient(circle at top right, transparent 15px, cyan 0) top right,  radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,  radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;  background-size: 50% 50%;  background-repeat: no-repeat;

切角

饼图

  • 关键实现:锥形渐变
  • 具体分析:利用锥形渐变可以轻松实现多个扇区,所以 svg 的方法权当学习了一波 svg 用法吧。
  background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);

饼图

动画animation

animation 属性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state属性的一个简写属性形式。

  • animation-name 指定动画的名称,可以逗号分割设置多个(以下皆可);
  • animation-duration 指定动画运行的时间;
  • animation-delay 指定动画执行前的延时;
  • animation-timing-function 指定动画执行的速度函数,如linear、ease(默认)、ease-in-out等,也可用贝塞尔函数cubic-bezier();
  • animation-iteration-count 指定动画的运行的次数,默认为1,可以为Infinite无限次;
  • animation-direction 指定动画是否反方向播放,normal 正常的顺序,alternate 交替运行,reverse 反向运行,alternate-reverse 反向交替运行;
  • animation-fill-mode 设置CSS动画在执行之前和之后的样式,none 不设置,forwards 保留最后一帧动画的样式,backwards 立即应用第一个关键帧中定义的值,并在animation-delay期间保留此值,both 同时应用forwards和backwards的规则;
  • animation-play-state 定义一个动画是否运行或者暂停,值为running、paused。

回弹效果

如何给动画加上回弹效果呢?这里介绍一种最便利的方法:

  • 关键实现:cubic-bezier(x1, y1, x2, y2)
  • 具体分析:利用贝塞尔曲线的第二个控制锚点大于 1 时的特性实现回弹

回弹效果

上图图横轴为时间,纵轴为动画进度。图中贝塞尔曲线有两个控制手柄,x1, y1 控制第一个锚点,x2, y2控制第二个锚点。其中 x1 、x2 不能大于/小于 1,但是y1, y2 可以。当 y2 大于 1 时,就会产生提前到达终点,然后超过终点,然后再返回终点的效果,像回弹一样。地址

  animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);

transition 属性是 transition-property、transition-duration、transition-timing-function、transition-delay的一个简写属性。使用 transition 同样可以实现回弹效果:地址

p {  transform-origin: 1.4em -.4em;  transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}  input:not(:focus) + p {  transform: scale(0);  transition: transform 300ms; /*此处是为了缩小时重置transition-timing-function,不触发回弹*/
}

会动的背景

  • 关键实现:animation、background-position
  • 具体分析:将动画最后一帧的background-position设为100% 0%,动画便会将背景位置从最初的0% 0%向最后的100% 0%过度:地址
div {  width: 150px; height: 150px;  background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');  background-size: auto 100%;   animation: panoramic 10s linear infinite alternate;
}
div:hover {  animation-play-state: paused;
}  @keyframes panoramic {  to { background-position: 100% 0; }
}

环形路径移动的动画

  • 关键实现:animation transform-origin
  • 具体分析:设置旋转容器的transform-origin为大圆容器中心点,同时利用两个元素在向不同方向旋转时旋转角度互相抵消的原理,实现图像沿环形路径旋转同时保持自身角度的不变。注意小圆距离大圆的距离由大圆的padding属性控制,调整padding时需要调整小圆的旋转原点transform-origin以保持环形路径的正确:地址
@keyframes spin {  to { transform: rotate(1turn); }
}
.avatar {  animation: spin 3s linear 2s infinite;  transform-origin: 110px 110px;
}
.avatar > img {  animation: inherit;  animation-direction: reverse;
}

环形路径移动的动画

笔者推荐css文章

其实现在社区已经不乏介绍 css 技巧的好文,这里推荐几篇我觉得写的极好的css技巧文章(当然可能大家也看过,很惭愧我其实现在也没看完):

总结

总体来说,《css揭秘》这本书并没有给我带来太大惊喜,个人感觉不如阅读《css世界》带来的收获多。当然了,这本书属于纯技巧型的,并没有讲述很多原理知识,所以也不能苛责吧。有兴趣的同学可以跟着我学习一波 css世界,相信肯定会有更大的收获~感谢平台分享-http://bjbsair.com/2020-04-10/tech-info/53257.html

《css揭秘》中讲了47个css技巧,其中有很多日常编码中并不会用到,本文除了将书中部分实用技巧罗列出来之外,还尝试用帮助读者搞明白background、animation 等常用但是却掌握不牢固的知识点。所以阅读本文不仅可以学习一些实用技巧,也可以巩固自己的 css 基础知识。

实用小技巧

DRY原则

全名Don’t Repeat Yourself,该原则适用于所有编程语言而不限于css。

扩大可点击区域

  • 关键实现:伪元素
  • 具体分析:利用伪元素和定位达到鼠标移到边缘时候出现手型且可点击
.expand-range {  position: relative;
}
.expand-range:after {  content: '';  position: absolute;  top: -10px; right: -10px; bottom: -10px; left: -10px;
}

推荐使用scss:

@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {  position: $position;  &:after {  content: '';  position: absolute;  top: $top;  right: $right;  bottom: $bottom;  left: $left;  }
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }

巧用层叠上下文

  • 关键实现: 伪元素 层叠上下文
  • 具体分析: 利用层叠上下文和 z-index: -1 特性实现伪元素覆盖背景同时又不会遮挡文字(具体实现原理参考这里 )。这是一个非常常用又好用的技巧,善加利用可以达到很多意想不到的效果。地址
  position: absolute;  top: 0; right: 0; bottom: 0; left: 0;  z-index: -1;

层叠上下文

边框内圆角

  • 关键实现:伪元素 层叠上下文
  • 具体分析:利用伪元素实现圆角矩形并叠加在父元素的背景之上文字之下:地址

边框内圆角

clip-path

  • 关键实现: clip-path
  • 具体分析:css3 新属性 clip-path 可以实现区域裁剪,现在浏览器支持较好的有三个函数:clip-path: circle(50px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个半径 50px 的圆;clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px 的地方为圆心裁剪一个横向半径 30px,纵向半径 40px 的椭圆;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) 按照多个坐标剪裁一个多边形,此处是菱形。有了 clip-path,就可以轻易的实现任意多边形了:地址

clip-path

自适应的椭圆

  • 关键实现:border-radius
  • 具体分析:border-radius 竟然可以设置 8 个角的半径~ 其中水平方向(对角线上下有弧度的地方)和垂直方向(对角线左右有弧度的地方)各四个,可以用 / 分割。如果水平或垂直方向指定的值少于四个,则会按照和 margin、padding 一样的规则重复。如果只指定来水平方向的,那么垂直方向的跟水平方向的一样。
    border-radius: 5em 1em; /*相当于border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/

自适应的椭圆

自适应宽度

  • 关键实现:min-content关键字
  • 具体分析:如何实现一个元素的宽度根据后代元素的最大固定元素宽度自适应呢?绞尽脑汁,也只能利用 display: inline-block 的包裹特性实现一个不完全的版本:地址 这种方法的缺陷是文本脱离了文档流,高度未计入包含块。但是如果利用 min-content 关键字,可以一行代码实现且无副作用:地址
  width: min-content;

自适应宽度

投影模拟多重边框

  • 关键实现:box-shadow的inset
  • 具体分析:使用box-shadow可以模拟实现多重边框,但是由于阴影不占空间,所以无法触发点击事件,鼠标hover边框时无法出现小手,所以需要配合inset关键字使用:地址
  height: 200px;  background: cyan;  box-shadow: 0 0 0 5px #000 inset,  0 0 0 10px #555 inset,  0 0 0 15px #999 inset;

投影模拟多重边框

单侧投影

  • 关键实现:box-shadow
  • 具体分析:box-shadow 前两个参数指定阴影的x、y偏移量,注意若为正数时整体向右/向下偏移,那么相应的左方/上方会空出一部分来(可以用来隐藏模糊半径或扩张半径),负数相反;第三个参数是阴影模糊半径,即高斯模糊多增加出来的过度颜色;第四个参数是阴影扩张半径,表示阴影增加的尺寸,可以是负数,表示阴影缩短的尺寸:地址
  box-shadow: 0 5px 4px -4px black;

第二个参数使阴影整体下移 5px ,第三个参数使阴影四周多了 4px 的高斯模糊(注意由于整体下移了 5px,所以此时上方还是没有阴影露出的),第四个参数又把阴影整体缩小了 4px,,所以左右两边才没有出现模糊半径导致的高斯模糊阴影色,从而实现单侧投影。

单侧投影

还可以逗号分隔设置多个阴影色,比如下面的两侧投影效果:地址

  box-shadow: 5px 0 5px -5px black,  -5px 0 5px -5px black;

单侧投影

不规则投影

  • 关键实现:filter: drop-shadow()
  • 具体分析:box-shadow 不能透过透明背景显示出来,不能越过伪元素/子元素显示出来,而这些drop-shadow能做到。(但无论哪种投影都会被clip-path剪裁掉~~)地址
  filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));

不规则投影

滤镜的染色和褪色效果

前端开发大都了解糊滤的高斯模镜效果是filter: blur()实现的,但是却很少使用滤镜的其他几个调色效果。filter 的值有blur()、drop-shadow()、url()、brightness()、contrast()、grayscale()、hue-rotate()、invert()、opacity()、saturate()、sepia()~~可以使用复合形式如:filter: sepia(1) saturate(4)等。下面是filter属性值大集合:地址

滤镜的染色和褪色效果

饼图 svg

饼图的 css 实现方案非常奇怪,所以我忽略之。推荐使用 svg 的实现方案,非常简单,先来个基本教学吧~

先画个圆:

<svg width="100" height="100">  <circle r="25" cx="50" cy="50" />
</svg>

这里 r=“25” 是半径25, cx cy 分别表示圆心的 x y 坐标。

circle {  fill: yellowgreen;  stroke: #666;  stroke-width: 50;
}

这里给圆形定义了一个宽度 40 的描边:

饼图 svg

再把描边设为线段长度 20 间隔 10 的虚线:

circle {  ...  stroke-dasharray: 20 10;
}

当把虚线的间隔设定为大于等于圆周时,虚线的线段长度就是一个扇形区域(当线段长度等于圆周时扇区达到100%):

给 svg 设置圆角和背景色,并旋转 -90deg ,就可以实现一个饼图:地址(使用currentColor关键字和color: inherit 是为了实现DRY原则。)

但是这样的饼图其扇区大小是不易计算的,为了方便计算,可以让虚线的线段长度同时也是圆周无限接近100,这样就可以更方便的设置扇区的百分比。圆周是 2πr ,所以 100 = 2πr ,计算得出半径 r 近似值 16。再利用 svg 的 viewBox 属性,实现自适应容器大小的饼图:地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lDUVkup1-1586506405398)(http://p1.pstatp.com/large/pgc-image/789d130836aa4de89b5a9d5f33bdc4d6)]

这种方法有个弊端,就是当设置 stroke-dasharray: 100 100 时会有一条缝,这是取近似值无法避免的。

背景background

background 是我们最常用的属性之一,但作为一个老前端,我也只能羞耻的说我目前并没有完全掌握这个属性。

background 是一个简写属性,可以包括多个属性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment。接下来我们一个个来看看这些属性的作用:

  • background-color 最常用的属性,默认不继承(background的所有属性都默认不继承),初始值为 transparent;有时候使用默认继承可以实现一些好玩的效果,比如倒影;
  • backgroundo-image 背景图片,可以逗号分割设置多个,可以是图片url或者渐变色;
  • background-clip 背景剪裁,可以逗号分割设置多个,值可以为 broder-box(初始值)、padding-box、content-box、text(新,将背景被文字剪裁);
  • background-origin 设置背景起始点的相对区域,搭配 background-position使用,可以逗号分割设置多个,值可以是border-box、padding-box(初始值)、content-box;
  • background-position 设置背景的起始点,可以逗号分割设置多个,值可以是 10px 20px 、center center 、left 10px bottom 20px等等,非常灵活;
  • background-size 设置背景的大小,可以逗号分割设置多个,值可以是数字值如30px 40px、auto auto(初始值)、conver、contain;background-repeat: repeat就是根据这个尺寸大小来重复的。
  • background-repeat 设置背景的重复方式,初始值为 repeat,常使用值的还有no-repeat;
  • background-attachment 设置背景图像的位置是在视口内固定,还是随着包含它的区块滚动。可以逗号分割设置多个,值有scroll(初始值)、local、fixed。详情查看MDN

简写时 background-size 只能紧接着 background-position 出现,以 / 分割,如: “center / 80%”。

半透明边框

  • 关键实现:background-clip
  • 具体分析:由于background属性默认会覆盖整个盒模型包括边框border,所以设置border-color: rgba(0, 0, 0, .5)时会透出背景色,达不到半透明边框的效果。css3增加了background-clip属性,定义背景填充的裁剪区域。设置padding-box便可以实现半透明边框:地址
  border: 10px solid rgba(255, 255, 255, .5);  background: white;  background-clip: padding-box;

半透明边框

灵活的背景定位

  • 关键实现:backgrond-position background-origin
  • 具体分析:我们都知道background-position可以定位背景图片等位置,但是都是相对padding-box的左上角开始等。css3 允许这样写:background-position: right 10px bottom 20px,同时 css3 还支持background-origin,其默认值如同其表现border-box,支持设为padding-box和content-box:地址
  height: 200px;  padding: 10px;  border: 5px solid cyan;  background: lightblue;  background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;  background-origin: content-box;

背景定位

background-position 设为百分比值较为复杂。百分比值实际上执行了以下的计算公式:

(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)

由计算公式可知:当值为0%时,实际偏移值为0px,此时图片的左边界(或上边界)和容器的左边界(或上边界)重合;当值为50%时,实际偏移值为容器减图片剩余空间的一半,图片左右边界(或上下边界)距离容器左右边界(或上下边界)相等,此时图片的中点和容器的中点重合。当值100%时,实际偏移值为容器减图片的剩余空间,所以此时图片的右边界(或下边界)和容器的右边界(或下边界)重合。二者之差为负值时同样有效。地址

背景定位

条纹背景

  • 关键实现:background-image
  • 实现分析:利用线性渐变实现多种颜色的交错重复,形成条纹背景。lienar-gradient的第一个参数是渐变的角度,可以是方向关键字to top(初始值,可忽略不写)等,也可以是角度90deg等;#fb3 50%指的是色标和终点位置值;这里linear-gradient的第二个位置值设置为0会被解析为前一个色标的位置值即50%,这样写更加符合DRY原则。
background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;

条纹背景

也可以设置为垂直条纹背景:

background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;

还可以设置为斜向条纹:

background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;

垂直条纹背景

斜向条纹需要设置四条条纹才能在平铺到时候做到无缝拼接。

更好的斜向条纹:(这里必须设置起始值#fb3 0)

background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);

更好的斜向条纹

网格

  • 关键实现:background-image、background-size
  • 给多个渐变设置不同的方向、大小,可以实现网格的效果。地址
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),  linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;

网格

更好的网格:

background: #58a;
background-image: linear-gradient(white 2px, transparent 0),  linear-gradient(to right, white 2px, transparent 0),  linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),  linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;

更好的网格

棋盘

  • 关键实现:background-image、background-size、background-position
  • 具体分析:给多个渐变设置不同的大小、位置,可以实现网格的效果。地址
  background: #eee;  background-image:  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),  linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

棋盘

折角

  • 关键实现:线性渐变
  • 具体分析:150deg 是为了形成30度角,方便利用勾股定理测出各种长度,其他的靠你自己看了~ 地址

折角

到这里 background 属性基本讲完了,光看无用,多动手实践吧。

波点

  • 关键实现:径向渐变
  • 具体分析:利用径向渐变实现一个个小圆点,按规律摆放即能生成波点 地址
  background:  radial-gradient(tan 30%, transparent 0),  radial-gradient(tan 30%, transparent 0);  background-color: #666;  background-size: 30px 30px;  background-position: 0 0, 15px 15px;

波点

切角

  • 关键实现:clip-path、径向渐变
  • 具体分析:一般来说多边形的切角效果(其实还是不规则多边形)用clip-path都可以轻松实现,但是对于圆形的切角,使用径向渐变是最好的选择。但是如果有弧形的切角呢?radial-linear第一个参数指定渐变的起始点点(默认为中心点),同时可指定渐变类型是椭圆还是圆;地址
  background:  radial-gradient(circle at top left, transparent 15px, blue 0) top left,  radial-gradient(circle at top right, transparent 15px, cyan 0) top right,  radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,  radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;  background-size: 50% 50%;  background-repeat: no-repeat;

切角

饼图

  • 关键实现:锥形渐变
  • 具体分析:利用锥形渐变可以轻松实现多个扇区,所以 svg 的方法权当学习了一波 svg 用法吧。
  background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);

饼图

动画animation

animation 属性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state属性的一个简写属性形式。

  • animation-name 指定动画的名称,可以逗号分割设置多个(以下皆可);
  • animation-duration 指定动画运行的时间;
  • animation-delay 指定动画执行前的延时;
  • animation-timing-function 指定动画执行的速度函数,如linear、ease(默认)、ease-in-out等,也可用贝塞尔函数cubic-bezier();
  • animation-iteration-count 指定动画的运行的次数,默认为1,可以为Infinite无限次;
  • animation-direction 指定动画是否反方向播放,normal 正常的顺序,alternate 交替运行,reverse 反向运行,alternate-reverse 反向交替运行;
  • animation-fill-mode 设置CSS动画在执行之前和之后的样式,none 不设置,forwards 保留最后一帧动画的样式,backwards 立即应用第一个关键帧中定义的值,并在animation-delay期间保留此值,both 同时应用forwards和backwards的规则;
  • animation-play-state 定义一个动画是否运行或者暂停,值为running、paused。

回弹效果

如何给动画加上回弹效果呢?这里介绍一种最便利的方法:

  • 关键实现:cubic-bezier(x1, y1, x2, y2)
  • 具体分析:利用贝塞尔曲线的第二个控制锚点大于 1 时的特性实现回弹

回弹效果

上图图横轴为时间,纵轴为动画进度。图中贝塞尔曲线有两个控制手柄,x1, y1 控制第一个锚点,x2, y2控制第二个锚点。其中 x1 、x2 不能大于/小于 1,但是y1, y2 可以。当 y2 大于 1 时,就会产生提前到达终点,然后超过终点,然后再返回终点的效果,像回弹一样。地址

  animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);

transition 属性是 transition-property、transition-duration、transition-timing-function、transition-delay的一个简写属性。使用 transition 同样可以实现回弹效果:地址

p {  transform-origin: 1.4em -.4em;  transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}  input:not(:focus) + p {  transform: scale(0);  transition: transform 300ms; /*此处是为了缩小时重置transition-timing-function,不触发回弹*/
}

会动的背景

  • 关键实现:animation、background-position
  • 具体分析:将动画最后一帧的background-position设为100% 0%,动画便会将背景位置从最初的0% 0%向最后的100% 0%过度:地址
div {  width: 150px; height: 150px;  background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');  background-size: auto 100%;   animation: panoramic 10s linear infinite alternate;
}
div:hover {  animation-play-state: paused;
}  @keyframes panoramic {  to { background-position: 100% 0; }
}

环形路径移动的动画

  • 关键实现:animation transform-origin
  • 具体分析:设置旋转容器的transform-origin为大圆容器中心点,同时利用两个元素在向不同方向旋转时旋转角度互相抵消的原理,实现图像沿环形路径旋转同时保持自身角度的不变。注意小圆距离大圆的距离由大圆的padding属性控制,调整padding时需要调整小圆的旋转原点transform-origin以保持环形路径的正确:地址
@keyframes spin {  to { transform: rotate(1turn); }
}
.avatar {  animation: spin 3s linear 2s infinite;  transform-origin: 110px 110px;
}
.avatar > img {  animation: inherit;  animation-direction: reverse;
}

环形路径移动的动画

笔者推荐css文章

其实现在社区已经不乏介绍 css 技巧的好文,这里推荐几篇我觉得写的极好的css技巧文章(当然可能大家也看过,很惭愧我其实现在也没看完):

总结

总体来说,《css揭秘》这本书并没有给我带来太大惊喜,个人感觉不如阅读《css世界》带来的收获多。当然了,这本书属于纯技巧型的,并没有讲述很多原理知识,所以也不能苛责吧。有兴趣的同学可以跟着我学习一波 css世界,相信肯定会有更大的收获~

CSS揭破实用窍门总结相关推荐

  1. Silverlight实用窍门系列:71.Silverlight的Style

    此文章实例基于Silverlight实用窍门系列:68.Silverlight的资源字典ResourceDictionary,如有数据源疑问请参考该文章. 在Silverlight中的Style相当于 ...

  2. Silverlight实用窍门系列:59.多个中心点联动多线的可拖动控件扩展为拓扑图

    在本系列的第17篇文章中"Silverlight实用窍门系列:17.中心点联动多线的可拖动控件(绘制工程图.拓扑图基础) ",制作了基本的中心联动图标.有园友对此图的扩展不是很清晰 ...

  3. Windows 8实用窍门系列:10.Windows 8的基本变换和矩阵变换以及AppBar应用程序栏

    在Windows 8中有几种基本变换和矩阵变换和Silverlight中的使用方法都是一样. 包括: RotateTransform:旋转变换 ScaleTransform:缩放变换 SkewTran ...

  4. Silverlight实用窍门大集合+Silverlight 5 最全新特性【目录索引】

    在最近的几个月内整理出了Silverlight的一些相关的比较实用的功能讲解文章,并且随着Silverlight 5 beta版本的发布整理出的新特性系列文章,在这里做一个总的概括和索引,以方便大家观 ...

  5. 前端开发[html+css]的实用网站分享(一)

    目录 1.Glassmorphism 玻璃特效生成器 2卡片快速生成器 3.button按钮集合 1.Glassmorphism 玻璃特效生成器 Glassmorphism generator 玻璃特 ...

  6. CSS一些实用的技巧

    css 字体简写规则 当使用css定义字体时你可能会这样做: font-size: 1em; line-height: 1.5em; font-weight: bold; font-style: it ...

  7. html css js知识整理,Html+Css+Js实用知识汇总(持续更新中...)

    Html篇 基本概念: html:超文本标记语言(Hyper Text Markup Language) html5:下一代的html xhtml:更严谨更纯净的html 表头 网站标题 //页面编码 ...

  8. 有关html,css的实用知识点总结(一)

    1. 简述一下 src 与 href 的区别. src 用于替换当前元素, href 用于在当前文档和引用资源之间确立联系. src 是 source的缩写,指向外部资源的位置,指向的内容将会嵌入到文 ...

  9. Silverlight实用窍门系列:52.Silverlight中的MVVM框架极速入门(以MVVM Light Toolkit为例)...

    在本文将以MVVM Light Toolkit为例讲解MVVM框架在现实中的使用入门,首先我们在http://mvvmlight.codeplex.com/下载它的MVVM框架下来.也可以通过 htt ...

  10. Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地

    在Silverlight中我们可以捕捉视频设备以制作视频会议系统,或者通过视频设备截图功能上传头像等功能. 下面我们通过一个简单的实例来访问视频设备,并且截取图像下载该截图文件至本地. 一.在Silv ...

最新文章

  1. sql server 在占用服务器内存居高不下怎么办【转】
  2. SQL Server 2005数据库日志文件损坏的情况下如何恢复数据库
  3. 动环监控系统的组成都有什么呢?
  4. Session服务器配置指南与使用经验
  5. 订阅基础:RSS、ATOM、FEED、聚合、供稿、合烧与订阅
  6. vscode 配置php
  7. Properties常用方法
  8. SpringAop @Pointcut(“@annotation“)\@Aspect练习
  9. Java 在指定目录中创建文件
  10. go定时器 每天重复_Go 简单性的价值:来自对 Go 倍加青睐的谷歌软件工程师的自述...
  11. mosquitto鉴权插件的开发与说明(一)
  12. 计算机图形学笔记(第二周)
  13. 方法对头,报表模板维护其实很简单
  14. python实现MD5加密
  15. 零基础学python知乎-对于几乎是零基础的人,直接学 Python 编程合适吗?
  16. simpson积分模板
  17. 游戏策划笔记:工作感受感官引导
  18. 矩阵的特征值和特征向量
  19. BH1750 STM32 驱动程序
  20. 阿里云天池大赛赛题解析——深度学习篇

热门文章

  1. xp计算机怎么共享网络,xp系统手机usb共享网络上网,xp共享上网-
  2. IE无法浏览网页的常见原因及解决方法(转)
  3. python语言三角函数_python中三角函数_Python中的三角函数
  4. vue图片压缩不失真_压缩图片大小(像素)
  5. Elasticsearch系列:番外篇-Fielddata
  6. jdbc——mysql学习
  7. 虚拟主机服务需要备案吗?推荐使用哪种进行建站?
  8. python编程一球从100米_Python求解一个球从100米高度自由落下的问题
  9. 显示搜索dota2协调服务器,老司机教你处理搜索dota2游戏协调服务器中【操作流程】...
  10. python 读xlsx文件数据_Python读取xlsx文件的实现方法