1. 引言
    1. web标准
      1. 标准制定过程
      2. 浏览器前缀
        1. 自动添加浏览器前缀的工具
    2. CSS编码技巧
      1. 尽量减少代码重复
        1. 当某些值相互依赖时,应该把他们的相互关系用代码表达出来
        2. 代码维护VS代码量少
        3. currentcolor
          1. CSS有史以来的第一个变量
        4. 继承
      2. 相信你的眼睛,而不是数字
        1. 设计要顺应错觉产生的偏差
      3. 关于响应式网页设计
        1. 每个媒体查询都会增加成本
        2. 实现弹性可伸缩的布局,并在媒体查询的各个断点区间内指定相应的尺寸
          1. 使用em单位
          2. 使用百分比(或者视口单位)长度来取代固定长度
          3. 使用max-width
          4. 为替换元素(比如img、object、video、iframe等)设置一个max-width,值为100%
          5. 背景图片需要完整的铺满一个容器,使用background-size: cover
          6. 当图片(或其他元素)以行列式进行布局时,让视口的宽度来决定列的数量
          7. 使用多列文本时,指定column-width
      4. 合理使用简写
        1. 展开式写法不会清空所有相关的其他属性,可能会干扰呈现效果
      5. CSS预处理器
        1. 原生特性通常比预处理器提供的版本要强大得多
        2. 在每个项目开始时使用纯 CSS, 只有当代码开始变得无法保持DRY时,才切换到预处理器的方案
  2. 背景与边框
    1. 半透明边框
      1. 默认情况下,背景会延伸到边框所在的区域下层
      2. background-clip
        1. 初始值是border-box,意味着背景会被元素的border box(边框的外沿边框)剪裁掉
        2. padding-box意味着浏览器会用内边距的外沿来把背景剪裁掉
    2. 多重边框
      1. box-shadow方案
        1. box-shadow第四个参数(称作扩张半径)通过指定正值或者负值,可以让投影面积加大或者减小
        2. 一个正值的扩张半径加上两个为零的偏移量以及为零的模糊值,得到的投影其实像一道实线边框
        3. 用box-shadow的好处在于,它支持逗号分隔语法,可以用来创建任意数量的投影
      2. outline方案
        1. 先设置一层常规边框,再设置一层outline属性来产生外层的边框
        2. 边框样式比较灵活,可以模拟虚线边框的效果,还可以通过outline-offset属性来控制它跟元素边缘之间的间距
        3. 只适用于双层边框的场景
    3. 灵活的背景定位
      1. background-position的扩展语法方案
        1. background-position属性允许指定背景图片距离任意角的偏移量,只要在偏移量前面指定关键字。background-position: right 20px bottom 10px;
      2. background-origin方案
        1. 当偏移量与容器内边距一致的时候,可以用background-origin,让偏移量自动跟着内边距走
        2. background-origin属性其默认值是padding box,改成content-box后background-position的偏移量以content-box为准
      3. calc()方案
        1. background-position : calc(100% - 20px) calc(100% - 10px);
    4. 边框内圆角
      1. outline并不会跟着元素的圆角走,但是box-shadow会,两者叠加到一起,box-shadow刚好填补描边和容器圆角之间的空隙
      2. 扩张半径取圆角半径的一半,并且描边的宽度要比圆角半径的一半要小
    5. 条纹背景
      1. 多个色标具有相同的位置,它们会产生一个无限小的过度区域,颜色会在那个位置突然变化,linear-gradient(#fb3 50%, #58a 50%);
      2. 如果第二个色标的位置值设为0,那它的位置就总会被浏览器调整为前一个色标的位置值
      3. 垂直条纹
        1. inear-gradient()要在 开头加上一个额外的参数来指定渐变的方向:linear-gradient(to right, #fb3 50%, #58a 0)
      4. 斜向条纹
        1. 单个贴片中包含四条条纹,才有可能无缝拼接成斜向条纹
        2. 条纹宽度要和垂直条纹宽度一样时,条纹宽度需要通过勾股定理计算
      5. 更好的斜向条纹
        1. repeating-linear-gradient()
        2. 使用repeating-radial-gradient()可以随意改变斜纹的角度,而且代码中的长度直接表示条纹自身宽度
      6. 同色系条纹
        1. 用hsla()控制颜色
    6. 复杂的背景图案
      1. 网格
        1. 把水平和垂直的条纹叠加起来,让它们透过彼此的透明区域显现
      2. 波点
        1. 径向渐 变能够创建的最简单的图案是圆点的阵列
        2. 生成两层 圆点阵列图案,并把它们的背景定位错开,第二层背景的偏移定位值必须是贴片宽高的一半
      3. 棋盘
        1. 用两个直角三角形来拼合出方块
    7. 伪随机背景
      1. 一种颜色作为底色,另三种颜色作为条纹
      2. 把平铺间距最大的贴片安排在最顶层
      3. background-size尽量选择质数
    8. 连续的图像边框
      1. border-image工作原理是把图片分成9块,然后把他们应用到元素边框的边和角
      2. 两层背景分别设置不同的background-clip值,并且background-origin设置为border-box,这样使得背景图片在border-box范围内平铺
  3. 形状
    1. 自适应椭圆
      1. 自适应椭圆
        1. border-radius可以单独指定水平和垂直半径,只要用/分隔两个值即可
        2. border-radius不仅可以接受长度值,还可以接受百分比
        3. 高宽不等时,border-radius: 50%;可以实现自适应椭圆
      2. 半椭圆
        1. border-radius是简写,对应的展开式属性为:border-top-left-radius、border-top-right-radius、border-bottom-right-radius、border-bottom-left-radius
        2. 可以向border-radius一次性提供空格分隔的多个值。如果传了4个值,这4个值分别从左上角开始以顺时针顺序应用到元素的各个拐角;如果传了3个值,意味着第四个值与第二个值相同;如果传了2个值,意味着第三个值与第一个相同
        3. 可以为所有四角提供完全不同的水平半径和垂直半径:斜杠前指定1~4个值,斜杠后指定1~4个值
      3. 四分之一椭圆
        1. border-radius: 100% 0 0 0;
    2. 平行四边形
      1. 嵌套元素方案
        1. 用skew()变形属性对矩形进行斜向拉伸
        2. 直接用skew()拉伸内容也会拉伸,此时可以对内容再用一次反向skew()变形
        3. 需要额外的HTML元素包裹内容
      2. 伪元素方案
        1. 所有样式(背景、边框等)应用到伪元素上,内容不包含在伪元素中,然后再对伪元素进行变形
    3. 菱形图片
      1. 基于变形的方案
        1. 需要把图片用一个 <div> 包裹起来, 然后对其应用相反的 rotate() 变形样式
        2. max-width: 100%会被解析为容器的边长
        3. 要显示为菱形,图片的宽度要与容器的对角线相等,通过scale()变形样式缩放图片
        4. 通过scale()变形样式缩放图片时,是以它的中心点进行缩放的。通过width属性来放大图片时,只会以它的左上角为原点进行缩放
      2. 裁切路径方案
        1. clip-path属性可以把元素剪裁成任何形状
        2. polygon()是多边形函数,可以用一系列坐标点来指定任意的多边形,使用百分比时会解析为元素自身的尺寸
        3. 只要使用同一种形状函数并且点的数量相同,clip-path属性可以参与动画
    4. 切角效果
      1. 切角效果
        1. linear-gradient可以接受一个角度作为方向,色标的位置信息也可以是绝对的长度值
        2. 四角切角效果需要把background-repeat关掉,防止四层渐变背景相互覆盖
      2. 弧形切角
        1. 用径向渐变来替代线性渐变
      3. 内联SVG与border-image方案
        1. 使用 border-image ,并通过一个内联的 SVG 图像 来产生切角效果
        2. SVG可以实现与尺寸完全无关的缩放
        3. background-clip属性避免背景色蔓延到边框区域
      4. 裁切路径方案
        1. clip-path属性中可以同时使用百分比数值和绝对长度
        2. 不仅可以对任意类型的背景进行裁剪,甚至对替换元素(比如图片)进行裁剪,而且还支持动画效果
        3. 当内边距不够宽时,这个方案会裁剪掉文本
    5. 梯形标签页
      1. 用transform中的3D旋转函数:perspective() 和rotateX()
      2. 用伪元素生成一个矩形,对矩形进行变形
      3. 当没有设置transform-origin属性时,应用变形效果会让这个元素以它自身的中心线为轴进行空间上的旋转,因此元素投射到2D屏幕上的尺寸会发生变化。指定transform-origin: bottom;,当元素在3D空间中旋转时,可以把它的底边固定住
    6. 简单的饼图
      1. 基于transform的解决方案
        1. 用伪元素覆盖上去,通过旋转决定露出多大扇形区
        2. 伪元素背景元素与宿主元素保持一致,比率超过50%时改成棕色
        3. 可以用负的动画延时来直接跳至动画中的任意时间点,并且定格在那里,以此来实现按照比率来显示饼图
      2. SVG解决方案
        1. stroke和stroke-width属性用来描边
        2. stroke-dasharray: 20 10;是为虚线描边而准备的,20是虚线线段长度,10是间隙长度
        3. SVG描边时总会把一半绘制在元素外部,另一半绘制在元素内部
  4. 视觉效果
    1. 单侧投影
      1. 单侧投影
        1. box-shadow的绘制过程
        2. box-shadow中,没有任何投影绘制在元素的下层
        3. text-shadow中,文字下层的投影不会被剪裁
        4. box-shadow还有第四个长度参数—扩张半径,这个参数会根据指定的值去扩大或者缩小投影尺寸
        5. 应用一个负的扩张半径,而它的值刚好等于模 糊半径,那么投影的尺寸就会与投影所属元素的尺寸完全一致。将完全看不见任何投影
      2. 邻边投影
        1. 扩张半径设为模糊半径相反值的一半,并且偏移量的值需要大于或者等于模糊半径的一半
      3. 双侧投影
        1. 设置两块投影(运用两次单侧投影)以实现双侧投影的效果
    2. 不规则投影
      1. 使用filter滤镜属性,该属性只需要一些函数,就可以指定滤镜效果,比如blur()、grayscale()、drop-shadow()等
      2. drop-shadow()带有的参数和box-shadow属性一样,但是不包括扩张半径,不包括insert关键字,也不支持逗号分隔的多层投影语法
      3. 何非透明的部分都会被打上投影,如果文字被搭上投影,不能用text-shadow: none去除
    3. 染色效果
      1. 基于滤镜的方案
        1. sepia()滤镜会给图片增加一种降饱和度的橙黄色染色效果,几乎所有像素的色相值都会被收敛到35~40
        2. saturate()滤镜可以给每个像素提升饱和度
        3. hue-rotate()滤镜把每个像素的相色以指定的度数进行偏移
      2. 基于混合模式的方案
        1. luminosity混合模式会保留上层元素的HSL亮度信息,并从下层吸取色相的饱和度信息
        2. background-blend-mode: luminosity;可以为每层背景单独指定混合模式,不用<img>元素,而是用<div>元素,把这个元素的第一层背景设置为要染色的图片,并把第二层颜色设置成想要的主色调
        3. mix-blend-mode: luminosity;可以为整个元素设置混合模式,需要把图片包裹在一个容器中,并把容器的背景色设置成想要的主色调
        4. 混合模式不可以加动画
        5. 把背景图片和一个透明背景混合,此时不会出现任何混合效果
    4. 毛玻璃效果
      1. blur()会使整个元素都会模糊
      2. 对一个伪元素进行应用和<body>一样的背景,然后将其定位到元素下层,它的背景将会无缝匹配<body>的背景
    5. 折角效果
      1. 45°折角的解决方案
        1. 切角效果的矩形和渐变生成的小三角形重合
        2. 如果要保留水平和垂直方向上的2em长度, 就要用切角渐变的角标位置值除以√2
      2. 其他角度的解决方案
        1. 通过三角函数计算三角形的尺寸
        2. 折角三角形需要旋转偏移
  5. 字体排印
    1. 连字符断行
      1. hyphens属性有三个值:none、manual、auto。manual为默认值,它允许任何时候手工插入软连字符(&shy;)来实现断词折行的效果
      2. hyphens属性会优先处理软连字符,再去计算其他可以断词的地方
      3. hyphens属性的auto值可以比较好的实现连字符断行,不过需要在在HTML标签的lang属性中指定合适的语言
    2. 插入换行
      1. \A在Unicode中代表换行,可以用它来作为 ::after伪元素的内容,并将其添加到每个 <dd>元素的尾部
      2. 设置white-space: pre; 保留源代码中 的空白符和换行
      3. dd + dt
      4. 如果你的结构代码在多个连续的 <dd>之间包含了(未加 注释的)空白符,那么逗号前面会有一个空格,可以利用负外边距修复这个问题
    3. 文本行的斑马条纹
      1. 可以在 CSS 中用渐变直接生成背景图像,用 em 单位来设定背景尺寸,这样背景就可以自动适应 font-size 的变化了
      2. background-size需要设置为line-height的两倍,因为每个背景贴片需要覆盖两行代码
      3. 通过background-origin让背景自动跟着内边距的宽度走
    4. 调整tab的宽度
      1. tab-size属性接受一个数字(表示字符数)或者一个长度值(这个不那么实用)来调整tab缩进尺寸
    5. 连字
      1. font-variant-ligatures专门用来控制连字效果的开启和关闭
      2. 启用所有可能的连字:font-variant-ligatures: common-ligatures discretionary-ligatures historical-ligatures;
      3. 如果要把font- variant-ligatures属性复位为初始值,应该使用normal而不是none
    6. 华丽的&符号
      1. 在 font-family 声明中如果某款字体可用,但仅包括某几个字符,那它就只会用 来显示这几个字符;而在显示其他字符时,浏览器就会回退到其他字体
      2. 创建一种只包含 & 字形的 Web 字体, 通过 @font-face 将其引 入网页,然后把它排在字体队列中的第一位
      3. @font-face 规则中的 src 描述符还可以接受 local() 函数,用于指定本地字体的名称
      4. unicode-range描述符只在@font-face规则内部生效,它可以把字体作用的字符范围限制在一个子集内。它对本地字体和远程字体都是有效的
      5. 如果想用unicode-range指定一个字符区间,还是要加上U+前缀
    7. 自定义下划线
      1. 使用background-image及其相关属性生成下划线。可以设置两层与背景色相同的text-shadow来模拟下划线在遇到字母时会自动断开避让的效果
    8. 现实中的文字效果
      1. 凸版印刷效果
        1. 出现在底部的浅色投影(或者出现在顶部的暗色投影)会让人 产生物体是凹进平面内的错觉
        2. 出现在底部的暗色投影(或者出现在 顶部的浅色投影)会让人产生物体从平面上凸起的错觉
      2. 空心字效果
        1. 使用多个 text-shadow ,分别为这些投影加上不同方向的少量偏移
        2. 重叠多层轻微模糊的投影来模拟描边。这种方法不需要设置偏移量,但是性能较差,因为使用了模糊算法
        3. SVG方案,用stroke描边
      3. 文字外发光效果
        1. 通过几层重叠的 text-shadow,通过text-shadow的模糊半径来实现,不需要考虑偏移,但是依赖 text-shadow 来实现文字显示的做法无法实现平稳退化
        2. 使用 CSS 滤镜来实现文字的模糊效果
      4. 文字凸起效果
        1. 使用一长串累加的投影, 不设模糊并以 1px 的跨度逐渐错开,使颜色逐渐变暗,然后在底部加一层强 烈模糊的暗投影,从而模拟完整的立体效果
    9. 环形文字
      1. 用一个 <textPath> 元素来包裹住文本, 再把它们装进一个<text>元素中,并通过xlink:href属性来把它 链接到这个圆上
      2. 给 SVG 元素应用 overflow: visible 样式, 这样就不会把内容的溢出部分裁切掉了
  6. 用户体验
    1. 选择合适的鼠标光标
      1. 提示禁用状态
        1. cursor : not-allowed;
      2. 隐藏鼠标光标
        1. cursor: none;
    2. 扩大可点击区域
      1. 为按钮设置一圈透明边框
        1. 鼠标对元素边 框的交互也会触发鼠标事件
        2. 通过background-clip属性把背景限制在原本的区域之内
        3. 可以用box-shadow来模拟出一道(实色)边框
      2. 通过伪元素代表其宿主元素来响应鼠标交互
    3. 自定义复选框
      1. 可以基于复选框的勾选状态借助组合选择符来给其他元素设置样式
      2. 把<label>元素与复选框关联,让它起到触发开关的作用,为它添加生成性内 容(伪元素),并基于复选框的状态来为其设置样式。把真正 的复选框隐藏起来,再 把生成性内容美化一番,用来顶替原来的复选框
      3. 开关式按钮
    4. 通过阴影来弱化背景
      1. 配合HTML实现
        1. 需要增加额外的HTML,.overlay负责把这个关键元素背后的所有东西调暗
      2. 伪元素方案
        1. 用伪元素来消除额外的 HTML 元素
        2. 可以防止用户的 鼠标与页面的其他部分发生交互
      3. box-shadow方案
        1. box-shadow 的扩张参数可以把元素的投影向各个方 向延伸放大。可以生成一个巨大的投影,不偏移也不模糊,模拟出遮罩层的效果
        2. 视口单位 vmax
        3. 无法阻止鼠标交互
      4. backdrop方案
        1. 想 引 导 用 户 关 注 的 元 素 就 是 一 个 模 态 的 <dialog> 元 素 ( <dialog> 元素可以由它的 showModal() 方法显示出来),那么根据浏览器 的默认样式,它会自带一个遮罩层。借助 ::backdrop 伪元素,这个原生的 遮罩层也是可以设置样式的
    5. 通过模糊来弱化背景
      1. 通过额外的html元素把主要内容包裹起来,同时还作为添加样式的钩子
      2. 每当弹出一个 对话框,都需要给 <main> 元素增加一个类,以便对它应用模糊滤镜
      3. CSS 滤镜是可以设置动画的
      4. 使用 brightness() 和 / 或 contrast() 滤镜能把两种弱化背景的手法(阴影和模糊)结合起来
    6. 滚动提示
      1. background-attachment属性有三个值:scroll、fixed、local。scroll是默认值,背景图像会随着页面其余部分的滚动而移动。fixed表示页面的其余部分滚动背景图像不会移动。local表示背景相对于元素的内容固定。如果一个元素拥有滚动机制,背景将会随着元素的内容滚动, 并且背景的绘制区域和定位区域是相对于可滚动的区域而不是包含他们的边框。
      2. 需要用两层背景,一层用来生成阴影,另一层基本上就是一个用来遮挡阴影的白色矩形,其作用类似于遮罩层。生成阴影的那 层背景将具有默认的 background-attachment值(scroll),因为我们希望 它总是保持在原位。 我们把遮罩背景的background-attachment属性设置 为local,这样它就会在我们滚动到最顶部时盖住阴影,在向下滚动时跟着 滚动,从而露出阴影
    7. 交互式的图片对比控件
      1. CSS resize方案
        1. resize属性控制元素是否能被用户缩放
        2. 超出图片宽度只要这样设置max-width: 100%
        3. 调节手柄可以通过伪元素覆盖在调节手柄之上
      2. 范围输入控件方案
        1. 将原生的滑块控件覆盖在图片上,通过js脚本将滑块移动和<div>的宽度联系起来,实现用控件控制的效果
        2. 通过混合模式、滤镜和变形来优化控件
  7. 结构与布局
    1. 自适应内部元素
      1. width和height属性有一个新的关键字: min-content,这个关键字将解析为这个容器内部最大的不可断行元素的宽度
    2. 精确控制表格列宽
      1. table-layout属性有auto和fixed两个值。auto的行为模式被称为自动表格布局算法,会根据内容自动调整表格宽度;fixed表示表和列宽度由表和元素的宽度或第一行单元格的宽度来设置。后续行中的单元格不会影响列宽度
      2. 需要为表格元素指定一个宽度
    3. 根据兄弟元素的数量来设置样式
      1. :only-child可以用来定义只有一个子元素时的样式
      2. :last-child相当于:nth-last-child(1)
      3. li:first-child:nth-last-child(4)表示一个正好有四个列表项的列表中的第一个列表项
      4. 通过:first-child:nth-last-child()找到特定数量列表中的第一项,然后可以使用兄弟选择器~来命中它之后的所有兄弟元素,这样就达到了选定特定数量列表项中每个元素的目的
    4. 根据兄弟元素的数量范围来匹配元素
      1. :nth-child()中的参数不仅可以是数字还可以是an+b这样的表达式。如果参数是n+b这样的表达式,不论n取何值,这个表达式无法产生小于b的值,因此n+b这个表达式可以选择从第b个元素开始的所有子元素
      2. n+b这个表达式也可以用在:nth-last-child ()上,这样可以在列表总数是b或者更多时选中所有列表项
      3. -n+b表达式可以选中开头的b个元素。这样可以在列表总数是b或者更少时选中所有列表项
    5. 满幅的背景,定宽的内容
      1. calc()函数允许在css中直接进行简单的算式来指定属性的值
    6. 垂直居中
      1. 基于绝对定位的解决方案
        1. 先把这个元素的左上角放置在视 口(或最近的、具有定位属性的祖先元素)的正中心,然后再利用负外边距 把它向左、向上移动(移动距离相当于它自身宽高的一半),从而把元素的 正中心放置在视口的正中心。
        2. 借助calc()函数可以简化代码
        3. 在 translate() 变形函数中使用百分比值时,是以这个元素自身的宽度和高度 为基准进行换算和移动的
      2. 基于视口单位的解决方案
        1. 通过margin属性的百分比值来控制元素左上角位于容器的中心,然后再用translate()技巧来把元素以其自身高度宽高的一半为距离进行移动
        2. margin的百分比是以父元素的宽度作为解析基准的
        3. 这个方案只适合在视口中居中的场景
      3. 基于Flexbox的解决方案
        1. 先给这个待居中元素的父元素设置display: flex,再给这个元素自身设置margin: auto
        2. Flexbox 的另一个好处在于,它还可以将匿名容器(即没有被标签包裹 的文本节点)垂直居中
    7. 紧贴底部的页脚
      1. 固定高度的解决方案
        1. 计算出页脚所占高度和大标题与最顶部的距离,然后让内容的最小高度为(视口高度-页脚所占高度-大标题与最顶部的距离)
        2. 这套方案不仅要求我们确保页脚内的文本永远不会折行, 而且每当我们改变页脚的尺寸时,都需要跟着调整min-height值
      2. 更灵活的解决方案
        1. 对父元素设置display: flex,当父元素获得这个属性之后,就可以对其 子元素触发“伸缩盒布局模型”
        2. flex-flow设置为column, 让子元素排放在一列上
        3. 把父元素的min-height属性指 定为100vh,这样它就至少会占据整个视口的高度
        4. 只要给子元素的flex属性指定一个大于 0 的值(比如 1 即可),内容区块的高度应该可以自动伸展并占满所有的可用空间
  8. 过渡与动画
    1. 缓动效果
      1. 弹跳动画
        1. 所有过渡和动画都是跟一条曲线(缓动曲线)有关的,这条曲线指定了动画过程在整段时间中是如何推进的
        2. 下落方向上的调速函数是加速的(ease- out),而弹起方向上是减速的(ease-in)
        3. CSS 提供了cubic-bezier()函数,允许我们指定自定义的调速函数。它接受四个参数,分别代表两个控 制锚点的坐标值, 我们通过这两个控制锚点来指定想要的贝塞尔曲线。
      2. 弹性过渡
        1. 曲线的控制锚点可以在垂直方向上突破 0~1 区间,从而让过渡达到低于0或高于100%的程度。它表示如果我们要从 scale(0) 的变形程度过渡到 scale(1) ,就还将经历一个比最终值更大的状 态,比如 scale(1.1)
        2. 鼠标不聚焦时,需要覆盖过渡的持续时间和缓动曲线
        3. 颜色不适合做弹性过渡动画
        4. 当我们在transition简写属性中不指定任何属性时,transition-property就会得 到它的初始值:all。这意味着只要是可以过渡的属性,都会参与过渡。
    2. 逐帧动画
      1. steps()会根据你指定的步进数量(在这个例子中就是动画的帧数),把整个动画切分为多帧,而且整个动画会在帧与帧之间硬切,不会做任何插值处理
      2. steps()还接受可选的第二个参数, 其值可以是start或end(默认值)。这个参数用于指定动画在每个循环周期的什么位置发生帧的切换动作
    3. 闪烁效果
      1. 通过修改关键帧,让状态切换发生在每个循环周期的中间
      2. animation-direction的唯一作用就是反转每一个循环周期(reverse),或第偶数个循环周期(alternate),或第奇数个循环周期(alternate-reverse)
      3. 动画循环的次数翻倍,把animation-duration减半
      4. 如果使用steps()函数实现,调整动画的关键帧, 让切换动作发生在 50% 处
    4. 打字动画
      1. 让容器的宽度成为动画的主体:把所有文本包裹在这个容 器中,然后让它的宽度从 0 开始以步进动画的方式、一个字一个字地扩张到 它应有的宽度
      2. 需要用white-space: nowrap;来阻止文本折行
      3. 用overflow: hidden;, 裁切超出宽度的文本
      4. 用steps()来达到动画逐字呈现的效果
      5. ch表示“0” 字形的宽度
      6. 用一个伪元素来生成光标,并通过opacity属性来实现光标闪烁效果,也可以用右边框来模拟光标效果
    5. 状态平滑的动画
      1. 让背景的background-position属性值从原本的0 0一直变化到100% 0
      2. animation-play-state实现暂停动画
    6. 沿环形路径平移的动画
      1. 需要两个元素的解决方案
        1. 嵌套的两层变形会相互抵消
        2. animation-direction属性的reverse值得到原始动画的反向版本
      2. 单个元素的解决方案
        1. 每 个transform-origin都是可以被两个translate()模拟出来的