前言
本文是总结《CSS揭秘》书中教述的一些CSS技巧,并呈现了对应的代码和效果,和一些本人对CSS理解补充,非常感谢作者 Lea Verou 编写此书,受益匪浅,一起体会CSS的乐趣
注意
本文不考虑兼容问题,只适用于大部分浏览器和情况,如需考虑兼容,或自行找回退方案,或看《CSS揭秘》本书寻找回退方案
编码追求
- DRY
- Don`t Repeat Yourself,不应该重复你做的事情
- 反义即WET(Write Everything Twice)
- 可维护
- 灵活性
- 轻量级
- 尽可能符合标准
1. CSS编码技巧
可维护性最大的要素:尽量减少改动编辑的地方
当某些值依赖时, 应该把它们的相互关系用代码表达出来
- 根据字号大小改变元素其他属性大小
- 用hsl()改变颜色 ```html
[点击查看【codepen】](https://codepen.io/hegangshi/embed/KKMEVrZ)
<a name="FE7Dp"></a>
## 代码易维护 vs. 代码量少
有时候, **代码易维护和代码量少不可兼得** :
- 为元素添加10px宽的边框, **但左侧不加边框**
```css
/* no good */
/* 改动边框长需要改动3处*/
border-width: 10px 10px 10px 0;
/* good */
/* 改动1处,且可读性更高 */
border-width: 10px;
border-left-width: 0;
currentColor
CSS中有史以来的第一个变量,一直被解析为 color
- 自动与文本颜色保持一致
currentColor
本身就是很多CSS颜色属性的初始值,比如border-color
、outline-color
、text-shadow
、box-shadow
继承
inherit
普通元素继承父元素,伪元素继承宿主元素
字体设定为与页面的其他部分相同
input, select, button{ font: inherit; }
a { color: inherit; }
伪元素的背景色继承
.inherit::before {
background: inherit; /* important*/
border: inherit;
}
相信你的眼睛,而不是数字(对于设计而言)
垂直居中,物体从几何中心点再稍微向上挪一点,才能取得理想的视觉效果
- 圆形和矩形相比,会看起来小一点
关于响应式设计
请参考bootstrap的媒体查询尺寸
一些建议
- 尽量使用百分比长度来取代固定尺寸。实在做不到,也应该尝试与视图相关单位
vw、vh、vmin、vmax
- 需要在较大分辨率下得到固定尺寸,使用
max-width
而不是width
- 不要忘了为替换元素(例如
img、object、video、iframe
等)设置一个max-width
,值为100% - 行列式布局时,让视口的宽度来决定列的数量。
Flexbox
加上常规的文本折行行为可以实现。 - 使用多列文本时,指定
column-width
列宽,而不是指定column-count
列数,在较小的屏幕上自动显示为单列布局
合理使用简写
合理使用简写是一种良好的防卫性编码方式,可以抵御未来的风险
- 这两行CSS代码不等价 ```css background: rebeccapurple;
background-color: rebeccapurple;
前者是简写,确保得到纯色背景;但后者有可能是其他效果,因为可能会有 `background-image`
展开式写法并不会清空所有相关的其他属性,从而可能会干扰你想要达到的效果。
展开式写法是为了 **明确覆盖某个具体的展开式属性**
- 展开式属性与简写属性的配合使用
**如果只为某个属性提供一个值,那它就会扩散并应用到列表中的每一项**
```css
/* no good */
background: url("/3.png") no-repeat top right / 2em 2em,
url("/23.png") no-repeat bottom right / 2em 2em,
url("/23.png") no-repeat bottom right / 2em 2em;
/* good */
background: url("3.png") top right,
url("3.png") bottom right,
url("3.png") bottom right;
background-size: 2em 2em;
background-repeat: no-repeat;
预处理器
优点:大型项目中代码更加灵活
缺点:
- CSS的 文件体积 和 复杂度 可能会失控
- 调试难度会增加
- 打包时间增加
- 团队的学习时间增加
- 抽象泄露法则, 它们有它们自己的bug
颜色
hsla()
H是色度,取值在0度~360度之间,0度是红色,120度是绿色,240度是蓝色。360度也是红色。
S是饱和度,是色彩的纯度,是一个百分比的值,取值在0%~100%,0%饱和度最低,100%饱和度最高
L是亮度,也是一个百分比值,取值在0%~100%,0%最暗,100%最亮。
A是不透明度,取值在0.0~1.0,0.0完全透明,1.0完全不透明
HSL是一种圆柱坐标系,其坐标系图如下:
2. 背景与边框
多重边框
box-shadow
- 支持逗号语法,可以创建任意数量的投影,第一个在最上层
- 可以实现多重边框
- 受border-radius影响
和border区别,不占空间(可以用外边距或内边距(inset)来模拟),不会响应事件(可以用inset)
box-shadow: 0 0 0 10px #655,
0 0 0 20px deeppink,
0 2px 5px 25px rgba(0,0,0,.6);
outline
描边样式十分灵活
可以实现虚线,
box-shadow
实现边框不行可以通过
outline-offset
,控制和元素边缘之间的间距,接受负值border: 20px solid brown;
outline: 2px dashed white;
outline-offset: -10px;
只适用于双层背景,多层背景要使用box-shadow
- outline不一定会贴合border-radius,CSS工作组认为是一个bug,未来有可能会改
背景定位
background-clip
指定 背景 绘制区域
- border-box (default)
- padding-box
- content-box
background-origin
指定 背景图片 绘制区域
- border-box
- padding-box (default)
- content-box
点击查看【codepen】padding: 20px;
border: 20px solid rgba(0,0,0,.2);
background: yellowgreen url(https://www.baidu.com/img/flexible/logo/pc/result.png) no-repeat;
background-origin: content-box;
background-clip: padding-box;
background-position扩展语法
指定 背景图片 距离任意角的偏移量 ```css background-position: right 20px bottom 10px;
/ calc()方案 / background-position: calc(100% - 20px) calc(100% - 10px);
<a name="OvWJ8"></a>
## 边框内圆角
box-shadow的扩展距离 = border-radius的一半
```css
border-radius: .8em;
padding: 1em;
box-shadow: 0 0 0 .4em #655;
outline: .6em solid #655;
线性渐变、条纹背景
// 普通渐变
.stripe{
width: 200px;
height: 200px;
border: 2px dashed;
background: linear-gradient(#fb3,#58a);
}
// 控制背景大小
.stripe2{
background: linear-gradient(#fb3 50%,#58a 50%);
background-size: 100% 100px;
}
// 控制背景大小,不重复
.stripe3{
background: linear-gradient(#fb3 50%,#58a 50%) no-repeat;
background-size: 100% 100px;
}
// 控制背景渐变颜色位置
.stripe4{
background: linear-gradient(#fb3 0, #fb3 20%, #58a 0, #58a 50%,transparent 0,transparent 100%);
}
// 斜向条纹 repeating-linear-gradient
.sliant-stripe{
background:repeating-linear-gradient(60deg,#fb3,#fb3 15px,#58a 0,#58a 30px);
}
// 同色系条纹
.similar-stripe{
background: #58a;
background-image: repeating-linear-gradient(30deg,hsla(0,0%,100%,.1),hsla(0,0%,100%,.1) 10px,transparent 0,transparent 30px);
}
.dot-stripe{ background: tan; background-image: radial-gradient(#655 30%,transparent 0),radial-gradient(#655 30%,transparent 0); background-size: 33px 33px; background-position: 0 0, 15px 15px; }
.checker { background:#eee; background-image:linear-gradient(45deg,#bbb 25%,transparent 0),linear-gradient(45deg,transparent 75%,#bbb 0),linear-gradient(45deg,#bbb 25%,transparent 0),linear-gradient(45deg,transparent 75%,#bbb 0); background-position: 0 0,15px 15px,15px 15px,30px 30px; background-size: 30px 30px; }
[点击查看【codepen】](https://codepen.io/hegangshi/embed/vYKPbjg)
- 还可以做弧形切角
<a name="NADyU"></a>
## 伪随机背景条纹
- 背景贴片的尺寸实际上是所有background-size的最小公倍数
- 蝉原则:通过质数来增加随机真实性
- background-size尽量选质数
```css
.random {
width: 1000px;
height: 100px;
background: hsla(20, 40%, 90%);
background: linear-gradient(90deg,#fb3 11px,transparent 0),
linear-gradient(90deg,#ab4 23px,transparent 0),
linear-gradient(90deg,#fab4 41px,transparent 0);
background-size: 41px 100%,61px 100%,83px 100%;
}
点击查看【codepen】
蝉原则可以用于涉及有规律重复的情况:
- 伪随机旋转效果
- 生成随机时长的循环动画
- …
3. 图形
border-radius
- 可以设置8个值,前四个是水平半径,后四个是垂直半径,以
/
分开 - 省略不写则用前面的值,垂直半径全不写则和水平半径相同 ```css // 两者等效 border-rabius: 1px / 20px 5px; border-radius: 1px 1px 1px 1px / 20px 5px 20px 5px;
// 半椭圆 border-radius: 50% / 100% 100% 0 0 border-radius: 100% 0 100% 0 / 50%;
![image.png](https://cdn.nlark.com/yuque/0/2020/png/2453125/1605601622027-c4782b26-d19b-4902-a43c-e9aa84027ff3.png#align=left&display=inline&height=128&margin=%5Bobject%20Object%5D&name=image.png&originHeight=276&originWidth=660&size=15081&status=done&style=none&width=307)
<a name="jlKSp"></a>
## 图像边框
border-image效果不够好
```css
background: linear-gradient(white, white) padding-box,
url(xxx.jpg) border-box
0 0 /cover;
蚂蚁行军
.marching-ants{
width: 100px;
height: 200px;
padding: 1em;
border: 1px solid transparent;
background: linear-gradient(white,white) padding-box,
repeating-linear-gradient(-45deg,black 0,black 25%,white 0, white 50%) 0 / .6em .6em;
animation: ants 12s linear infinite;
}
@keyframes ants{
to {
background-position:100%;
}
}
图形变换:平行四边形
skew()
嵌套元素方案
.button {
width: 100px;
height:50px;
line-height: 50px;
text-align: center;
background: tan;
transform: skewX(-45deg);
}
.button > div {
transform: skewX(45deg);
}
✨伪元素方案
- 伪元素作为背景,进行变换
- 适用于其他任何线性样式,而不想影响内容时
图形变换:菱形图片
clip-path
使用裁剪方式创建元素的可显示区域。区域内的部分显示,区域外的隐藏。
clip-path: ploygon(50% 0,100% 50%,50% 100%,0 50%);
- 此方法可以实现多边形裁切
图形变换:矩形
transform: scaleY(1.3) perspective(.5em) rotatex(5deg);
transform-origin: bottom;
饼状图
animation
```css // 核心 animation: spin 3s linear infinite; animation: bg 6s step-end infinite;
@keyframe spin { to { transform: rotate(.5turn) } }
@keyframe bg { 50% { background: #655; } }
<a name="1T3XM"></a>
### animation-delay
值可以为负,实际效果就是 **动画跳过指定时间而从中间开始播放了**
<a name="oIOXb"></a>
### animation-play-state
paused 暂停
```html
<div class="pie" style="animation-delay:-30s">50</div>
<style>
.pie {
float: left;
position: relative;
width: 100px;
margin: 40px;
line-height: 100px;
border-radius: 50%;
background: yellowgreen;
background-image: linear-gradient(to right, transparent 50%, #655 0);
color: transparent;
text-align: center;
}
@keyframes spin {
to {
transform: rotate(0.5turn);
}
}
@keyframes bg {
50% {
background: #655;
}
}
.pie::before {
content: "";
position: absolute;
top: 0;
left: 50%;
width: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
animation: spin 50s linear infinite, bg 100s step-end infinite;
animation-play-state: paused;
animation-delay: inherit;
}
</style>
3. 视觉效果
投影
box-shadow
支持逗号多值创造多层投影,先写的在上层
// 单侧投影
box-shadow: 2px 5px 4px -4px rgba(0,0,0,.5);
绘制过程:
- 画出一个rgba(0,0,0,.5)的矩形
- 把它向右移2px,向下移3px
- 使用高斯模糊,进行4px的模糊处理, 阴影色和纯透明色之间的颜色过渡长度近似于模糊半径的两倍 (这里是8px)
- 缩小投影4px,即宽度和高度各减小4px
- 原始元素的交集部分会被切除掉, 没有任何投影绘制在元素的下层
问题:
- box-shadow不能给伪元素或者透明、半透明元素加阴影,可以使用drop-shadow
filter: drop-shadow()
drop-shadow的参数基本和box-shadow差不多,但不包括扩张半径,不包括inset关键字,也不支持逗号分割的多层投影语法。
// 两者等价
box-shadow: 2px 2px 10px rgba(0,0,0,.5);
filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));
问题:
- 任何非透明的部分都会被一视同仁地打上投影,包括文本
染色效果
解决图片颜色变化,需要设计出多张图片
其他方案:
- 透明层覆盖图片
- javaScript置入
✨contrast()
调整图像的对比度。值是0%的话,图像会全黑。值是100%,图像不变。值可以超过100%,意味着会运用更低的对比
✨brightness()
控制亮度,如果值是0%,图像会全黑。值是100%,则图像无变化。值超过100%也是可以的,图像会比原来更亮
✨invert()
反转输入图像。值定义转换的比例。100%的价值是完全反转。值为0%则图像无变化
sepia()
将图像转换为深褐色,相当于褪色的效果,值为100%则完全是深褐色的,值为0%图像无变化
saturate()
转换图像饱和度,值为0%则是完全不饱和,值为100%则图像无变化。超过100%的值是允许的,则有更高的饱和度
hue-rotate()
给图像应用色相旋转,和hsla中hue一样,超过360deg的值相当于又绕一圈
具体和其他请看菜鸟联盟的filter介绍
filter: sepia(1) saturate(4) hue-rotate(295deg);
混合模式
mix-blend-mode
元素的直系父元素的内容和元素的背景如何混合,为整个元素设置混合模式
<div class="img">
<img src="https://www.baidu.com/img/flexible/logo/pc/result.png" alt="">
</div>
<style>
.img{
display: inline-block;
background: hsl(335,100%,50%);
}
.img > img{
mix-blend-mode: luminosity;
}
</style>
background-blend-mode
为每层背景元素单独指定混合模式(图片与颜色)
<div class="blend"></div>
<style>
.blend {
width: 290px;
display: inline-block;
height: 69px;
background-size: 290px 69px;
background-repeat:no-repeat;
background-image: linear-gradient(to right, green 0%,white 100%), url('https://www.baidu.com/img/flexible/logo/pc/result.png');
background-blend-mode: color-dodge;
}
</style>
混合模式的动画
只有一个背景图片以及一个透明背景色,不会出现任何混合效果
background-color: hsl(335, 100%, 50%);
transition: .5s background-color;
background-color: transparent;
具体参数详情可看这里
毛玻璃效果
<div class="blur">
<div class="blur-item">长夜将至,我从今开始守望,至死方休。我将不娶妻、不封地、不生子。我将不戴宝冠,不争荣宠。我将尽忠职守,生死于斯</div>
</div>
<style>
// 使用伪元素作为背景
.blur{
margin: 40px;
width: 300px;
height: 300px;
display: flex;
align-items: center;
justify-content: center;
// 要点二:使父元素变为层叠上下文
position: relative;
z-index:0;
&,.blur-item::before{
background: url('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3774887219,31394809&fm=26&gp=0.jpg') 0 / cover fixed;
}
.blur-item{
width: 200px;
height: 200px;
padding: 20px;
position: relative;
background: hsla(0,0%,100%,.3);
overflow: hidden; // 要点二
&::before{
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index:-1;
filter: blur(20px);
margin: -30px; // 要点一
}
}
}
</style>
- 要点一: 模糊效果会消减消减实色像素所能覆盖的范围,消减半径正是模糊半径的长度,所以要相对于宿主元素的尺寸再向外扩大至少模糊半径,margin:-30px可以达到效果,但会有一圈模糊效果超出容器,所以加overflow: hidden;
不加margin和不加overflow效果:
- 要点二:
形成层叠上下文
4. 字体排版
连字符断行
hyphens
- none
- manual (defualt) 手工插入软连字符()
- auto
.text-justify{
display: inline-block;
text-align: justify;
hyphens: auto;
}
插入换行
伪元素换行
::after{
content: '\A';
white-space: pre; // 只会作用于伪元素
}
文本行的斑马纹
背景颜色加斑马纹
padding: .5em;
line-height: 1.5;
background: beige;
background-size: auto 3em;
background-origin:content-box;
background-image: linear-grandient(rgba(0,0,0,.2) 50%,transparent 0);
调整tab宽度
white-space: pre;
tab-size: 2;
修改单独字符
@font-face {
font-family: Ampersand;
src: local('xxx'),
local('xxx'),
local('xxx');
unicode-range: U+26; // 十六进制
}
自定义下划线
// 通常方案
text-decoration: underline; // 不够灵活
border-bottom: 1px solid gray; // 文本之间空隙很大,会阻止正常文本换行
box-shadow: 0 -1px gray inset; // 同上
// 最佳方案
background-image: linear-gradient(gray, gray) no-repeat;
background-size: 100% 1px;
background-position: 0 1.15em;
text-shadow: .05em 0 white, -.05em 0 white; // 为了使字母降部(如p和y)下划线可以自动避让
// 极为灵活,虚线下划线
background-image: linear-gradient(90deg, gray 66%,transparent 0) repeat-x;
background-size: .2em 2px;
background-position: 0 1em;
// 波浪下划线,两次径向渐变
现实的文字效果
凸版印刷效果
尤其适用 背景和文字对比度高 的场景,只要文字不是黑色并且背景纯白或纯黑就行
原理:
- 人们习惯 光源总是悬在头顶 ,凸起物的下方会产生阴影,而凹陷的底部边缘会被打亮
- 底部浅色投影 或 顶部暗色投影 产生凹进平面的错觉
- 底部暗色投影 或 顶部的浅色投影 产生平面上凸起的错觉
浅背景+深文字, 底部加上浅色投影通常效果最佳
background: hsl(210, 13%, 60%);
color: hsl(210, 13%, 30%);
text-shadow: 0 0.03em 0.03em hsla(0, 0%, 100%, 0.8);
空心字
background: pink;
color:white;
text-shadow: 1px 1px black, -1px -1px black,1px -1px black, -1px 1px black;
注意: 当text-shadow宽度增加时候,效果并不好,可以用svg来实现
文字外发光
background: #203;
color: #ffc;
text-shadow: none;
transition: text-shadow 500ms linear;
文字凸起效果
text-shadow: 0 1px hsl(0, 0%, 85%), 0 2px hsl(0, 0%, 85%),
0 3px hsl(0, 0%, 85%), 0 4px hsl(0, 0%, 85%), 0 5px hsl(0, 0%, 85%),
0 5px 10px black;
环形文字
用SVG实现
6. 用户体验
选用合适的鼠标光标
具体可看鼠标光标
扩大可点击区域
Fitts法则
- 人类 移动到某个目标区域所需的最短时间 是由 目标距离 与 目标宽度 之比所构成的对数函数
可点击区域(热区)向外扩张 往往也可以带来可用性的提升
// border方案
border: 10px solid transparent; // 扩张边缘
box-shadow: 0 0 0 1px rgba(0,0,0,.3) inset; // 加边框
background-clip: padding-box;
// ✨伪元素方案
xxx::before{
content: '';
position: absolute;
top: -10px; right: -10px; bottom: -10px; left: -10px; // 比宿主元素大出10px
}
自定义单/复选框
// 使用<label>元素与复选框关联之后,也可以起到触发开关的作用
<input type="checkbox" id="awesome">
<label for="awesome">Awesome!</label>
<style>
#awesome[type="checkbox"] + label::before{
content:'\a0'; /*不换行空格*/
display: inline-block;
vertical-align: .2em;
width: 0.8em;
height: 0.8em;
margin-right: 0.2em;
border-radius: .2em;
background: silver;
text-indent: .15em;
line-height: .4;
}
#awesome[type="checkbox"]:checked + label::before{
content:'\2713';
background: yellowgreen;
}
</style>
通过阴影来弱化背景
HTML方案
.overlay {
// 遮挡元素
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0,0,0,.8);
}
.lightbox {
// 突出元素
postion: absolute;
z-index: 1;
}
伪元素方案
// 不好控制层级
body .dimed::before{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
background: rgba(0,0,0,.8);
}
box-shadow方案
// 滚动页面时,遮罩层的边缘就漏出来了,无法产生交互
box-shadow: 0 0 0 50vmax rgba(0,0,0,.8);
backdrop方案
// 浏览器对它支持有限
dialog::backdrop {
background: rgba(0,0,0,.8);
}
通过阴影+模糊来弱化背景
filter: blur(3px) contrast(.8) brightness(.8);
滚动提示
<style>
.scroll-wrap{
margin: 100px;
width: 200px;
height: 500px;
border: 1px solid #ccc;
overflow-y: scroll;
padding: .3em 1em 0;
background: linear-gradient(white 30%, transparent), radial-gradient(at top, rgba(0,0,0,.2), transparent 70%), linear-gradient(0deg,white 30%, transparent), radial-gradient(at bottom, rgba(0,0,0,.2), transparent 70%);
background-repeat: no-repeat;
background-size: 100% 50px,100% 15px;
background-position: 0 0,0 0,100% 100%,100% 100%;
background-attachment: local, scroll,local,scroll;
}
</style>
对比控件
resize
- none (default)
- horizontal
- vertical
点击查看【codepen】overflow: hidden; resize: horizontal;
7. 结构与布局
自适应内部元素
fill-available、max-content、min-content、fit-content
具体请看链接
其中最有用的是min-content
内部元素最小宽度值最大的那个元素的宽度作为最终容器的宽度。如果是图片的话最小宽度值就是图片所呈现的宽度,如果是汉字就是一个字的宽度,如果是英文就是单词的宽度。 ```html八百标兵奔北坡,炮兵并排北边跑
![image.png](https://cdn.nlark.com/yuque/0/2020/png/2453125/1605865055964-03d1491a-1ac3-4b0f-ab66-ecb7f07fb8a0.png#align=left&display=inline&height=126&margin=%5Bobject%20Object%5D&name=image.png&originHeight=196&originWidth=284&size=20471&status=done&style=none&width=183)
<a name="D4Pn9"></a>
## 根据兄弟元素的数量设置样式
```css
// 只有一个节点,两者相等
xxx:first-child:nth-last-child(1)
xxx:only-child
// 当列表正好包含四项时
:first-child:nth-last-child(4)
// 当列表至少包含四项时
:first-child:nth-last-child(n+4)
// 当列表最多包含四项时
:first-child:nth-last-child(-n+4)
// 当列表包含2~6项时
:first-child:nth-last-child(n+2):nth-last-child(-n+6)
//【限制范围】选择第6个到第9个,取两者的交集
:nth-child(-n+9):nth-child(n+6){}
满幅的背景,定宽的内容
// 得到450px居中内容
padding: 1em calc(50% - 450px)
垂直居中
绝对定位优化版
// no good
main{
position: absolute;
width: 18em;
height: 6em;
top: 50%;
left: 50%;
margin-top: -3em;
margin-left: -9em;
}
// good
main{
position: absolute;
top: calc(50% - 3em);
left: calc(50% - 9em);
}
// better
main{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
视口单位
main{
margin: 50% auto 0; // 基于父元素
margin: 50vh auto 0; // 基于视口
transform: translateY(-50%);
}
Flexbox方案
father{
display: flex;
}
main{
margin: auto; // 普通盒子中只会水平居中,flexitem会整体居中
}
main{
display: flex;
align-items: center;
justify-content: center;
}
页脚布局
body{
display: flex;
flex-flow: column;
min-height: 100vh;
}
main{
flex: 1;
}
footer{
...
}
8. 过渡与动画
缓动效果
cubic-bezier
定义了一个贝塞尔曲线(Cubic Bezier)。
贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义。P0 和 P3 是曲线的起点和终点。P0是(0,0)并且表示初始时间和初始状态,P3是(1,1)并且表示最终时间和最终状态
具体可见 菜鸟联盟介绍 和 模拟演示
transition: .5s cubic-bezier(.25,.1,.3,.1.5); // 大于1的时候可以产生【越过】效果
逐帧动画
steps()
animation: loader 1s infinite steps(8); // 8帧动画
闪烁效果
animation-direction
- normal (default)
- alternate
- reverse
- alternate-reverse ```css @keyframes blink-smooth{ to { color: transparent } }
.heightlight{ animation: .5s blink-smooth 6 alternate; } ```
沿环形路径平移的动画
可以看这篇文章,非常有意思
2020年11月22日