CSS 知识总结

165 阅读3分钟

一、浏览器渲染原理

浏览器渲染过程

步骤

  1. 根据 HTML 构建 HTML 树 (DOM) —— 描述内容
  2. 根据 CSS 构建 CSS 树 (CSSOM) —— 描述需要应用的样式规则
  3. 将两棵树合并成一棵渲染树 (render tree) —— 只包含渲染网页所需的节点
  4. Layout 布局 (文档流、盒模型、计算每个对象的精确位置和大小) —— 所有相对测量值都转换为屏幕上的绝对像素
  5. Paint 绘制 (把边框颜色、文字颜色、阴影等画出来) —— 将像素渲染到屏幕上
  6. Composite 合成 (根据层叠关系展示画面)

三棵树图像

image.png

构建渲染树

  1. 从 DOM 树的根节点开始遍历每个可见节点。
    • 某些节点不可见(如脚本标记、元标记等),因为它们不会体现在渲染输出中。
    • 某些节点通过CSS隐藏,因此渲染树会忽略这些被隐藏的节点。
  2. 对于每个可见节点,找到适配的 CSSOM 规则并应用。
  3. 发射可见节点,包括其内容和计算样式。 (注意 visibility: hiddendisplay: none 的区别:前者隐藏元素,但该元素仍然占据着布局空间,只是被渲染成了一个空框而已;而后者则是将元素从渲染树中完全移除,元素不再是布局的组成部分。)

如何更新样式

  1. 一般用JS来更新样式
  2. 有三种不同的渲染方式
    • JS / CSS > 样式 > 布局 > 绘制 > 合成 image.png
    • JS / CSS > 样式 > 绘制 > 合成 image.png
    • JS / CSS > 样式 > 合成 image.png

CSS 触发器 查询更改 CSS 属性将触发上述哪个版本

二、CSS 动画

transform

四个常用功能

  1. 位移 translate
    • translateX(<length-percentage>)
    • translateY(<length-percentage>)
    • translate(<length-percentage>,<length-percentage>?)
    • translateZ(<length>) 且父容器 perspective
    • translate3d(x,y,z)

绝对定位元素的居中:

position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
  1. 缩放 scale

    • scaleX(<number>)
    • scaleY(<number>)
    • scale(<number>,<number>?)
    • 用的较少,容易出现模糊
  2. 旋转 rotate

    • rotate([<angle> | <zero>])
    • rotateZ([<angle> | <zero>])
    • rotateX([<angle> | <zero>])
    • rotateY([<angle> | <zero>])
    • rotate3d
    • 一般用于 360 度旋转制作 loading
  3. 倾斜 skew

    • skewX([<angle> | <zero>])
    • skewY([<angle> | <zero>])
    • skew([<angle> | <zero>], [<angle> | <zero>]?)
  4. 组合使用

    • transform: scale(0.5) translate(-100%, -100%);
    • transform: none; 取消所有

经验

  • 一般都需要配合 transition 过渡
  • inline 元素不支持transform,需要先变成 block

transition 过渡

作用

  • 补充中间帧

语法

  • transition: 属性名 时长 过渡方式 延迟
  • transition: left 200ms linear
  • 可以用逗号分隔两个不同属性 transition: left 200ms, top 400ms
  • 可以用 all 代表所有属性 transition: all 200ms
  • 过渡方式有: linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-end | steps
  • 不是所有属性都能过渡
    • display: none => block 没法过渡
    • 一般改成 visibility: hidden => visible

过渡必须要有起始,一般只有一次动画或者两次,比如 hover 和非 hover 状态的过渡

如果有中间点

  1. 使用两次 transform
    • .a === transform ===> .b
    • .b === transform ===> .c
    • 如何判断中间点:用 setTimeout 或者监听 transitionend 事件
  2. 使用animation
    • 声明关键帧
    • 添加动画

animation

@keyframes 完整语法

  1. 一种是 from to (没有办法设置中间点)
  2. 一种是百分数
@keyframes slidein {
  from {
      transform: translateX(0%);
  }
  to {
      transform: translateX(100%);
  }
}
@keyframes identifier {
    0% {top: 0; left:0;}
    30% {top: 50px;}
    68%, 72% {left: 50px;}
    100% {top: 100px; left: 100%;}
}

如何让动画停在最后一帧:forwards

#demo.start{
  animation: xxx 1.5s forwards;
}

@keyframes xxx {
  0% {
    transform: none;
  }
  66.66%{
    transform: translateX(200px);
  }
  100%{
    transform: translateX(200px) translateY(100px);
  }
}

animation 缩写语法

animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名;

  • 时长:s or ms
  • 过渡方式:同 transition 取值,如 linear
  • 次数:3 or 2.4 or infinite
  • 方向: reverse | alternate | alternate-reverse
  • 填充模式: none | forwards | backwards | both
  • 是否暂停: paused |running
  • 以上所有属性都有对应的单独属性,查询 MDN

参考文章

渲染树构建、布局及绘制

渲染性能

使用transform来实现动画