《CSS 知识总结》

203 阅读5分钟

1.浏览器渲染原理

[根据 HTML 和 CSS 输入构建了 DOM 树和 CSSOM 树,但因为它们都是独立的对象,分别网罗文档不同方面的信息,DOM树描述内容,CSSOM树则是描述需要对文档应用的样式规则。]

第一步是根据HTML构建HTML树(DOM)

第二步是根据CSS构建CSS树(CSSOM)

第三步是让浏览器将 DOM 和 CSSOM 合并成一个 “渲染树”[网罗网页上所有可见的 DOM 内容,以及每个节点的所有 CSSOM 样式信息。]

如图:html构建的DOM树,CSS构建的CSSOM树,两棵树合并构建成Render Tree渲染树(即用户要看到的那棵树)

为构建渲染树,浏览器大体上完成了下列工作:

  1. 从 DOM 树的根节点开始遍历每个可见节点。

    • 某些节点不可见(例如脚本标记、元标记等),因为它们不会体现在渲染输出中,所以会被忽略。
    • 某些节点通过 CSS 隐藏,因此在渲染树中也会被忽略,例如,上例中的 span 节点 --- 不会出现在渲染树中,--- 因为有一个显式规则在该节点上设置了 “display: none” 属性。
  2. 对于每个可见节点,为其找到适配的 CSSOM 规则并应用它们。

  3. 发射可见节点,连同其内容和计算的样式。

------------------------------------------------------------------------------------------------------------

第四步是Layout布局(文档流,盒模型,计算大小和位置)

布局流程的输出是一个 “盒模型”,它会精确地捕获每个元素在视口内的确切位置和尺寸:所有相对测量值都转换为屏幕上的绝对像素。

第五步是Paint绘制(把边框颜色,文字颜色,阴影画出来)

既然我们知道了哪些节点可见、它们的计算样式以及几何信息,我们终于可以将这些信息传递给最后一个阶段:将渲染树中的每个节点转换成屏幕上的实际像素。这一步通常称为 “绘制” 或 “栅格化”。

第六步是Compose合成(根据层叠关系展示画面)


  • “Layout” 事件在时间线中捕获渲染树构建以及位置和尺寸计算。
  • 布局完成后,浏览器会立即发出 “Paint Setup” 和 “Paint” 事件,将渲染树转换成屏幕上的像素。

执行渲染树构建、布局和绘制所需的时间将取决于文档大小、应用的样式,以及运行文档的设备:文档越大,浏览器需要完成的工作就越多;样式越复杂,绘制需要的时间就越长(例如,单色的绘制开销 “较小”,而阴影的计算和渲染开销则要 “大得多”)。

  • DOM 树与 CSSOM 树合并后形成渲染树。
  • 渲染树只包含渲染网页所需的节点。
  • 布局计算每个对象的精确位置和大小。
  • 最后一步是绘制,使用最终渲染树将像素渲染到屏幕上。

浏览器完成的步骤:

  1. 处理 HTML 标记并构建 DOM 树。
  2. 处理 CSS 标记并构建 CSSOM 树。
  3. 将 DOM 与 CSSOM 合并成一个渲染树。
  4. 根据渲染树来布局,以计算每个节点的几何信息。
  5. 将各个节点绘制到屏幕上。
如果 DOM 或 CSSOM 被修改,只能再执行一遍以上所有步骤,以确定哪些像素需要在屏幕上进行重新渲染。 优化关键渲染路径就是指最大限度缩短执行上述第 1 步至第 5 步耗费的总时间。 这样一来,就能尽快将内容渲染到屏幕上,此外还能缩短首次渲染后屏幕刷新的时间,即为交互式内容实现更高的刷新率。

2.CSS 动画的两种做法(transition 和 animation)

transition:

作用:补充中间帧

语法:

transition:属性名 时长 过渡方式 延迟

transition:left 200ms linear

可以用all代表所有属性

transition:all 200ms

过渡方式有:linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-start | step-end | steps

具体含义要靠数学知识

注意:并不是所有属性都能过渡

★ display:none ----->block 没法过渡

★ 一般改成visibility:hidden ------> visible

★display 和 visibility 的区别:

Note: 请注意 visibility: hiddendisplay: none 是不一样的。前者隐藏元素,但元素仍占据着布局空间(即将其渲染成一个空框),而后者 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分。

两个问题 ★background颜色可以过渡吗? ★opacity透明度可以过渡吗?

过渡必须要有起始 一般只有一次动画,或者两次

比如hover和非hover状态的过渡

中间点的两种办法

使用两次transform

.a===transform ===>.b

.b === transform ===>.c

如何知道到了中间点呢?

用setTimeout或者监听transitionend事件


animation:

缩写语法

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

★时长:1s或者1000ms

★过渡方式:跟transition取值一样,如linear

★次数:3或者2.4或者infinite

★方向:reverse|alternate|alternate-reverse

★填充模式:none|forwards|backwards|both

★是否暂停:paused|running

★以上所有属性都有对应的单独属性


@keyframes完整语法:

    @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%; }
 }

★transform·四个常用功能

✔ 位移translate

✔ 缩放scale

✔ 旋转rotate

✔ 倾斜skew

经验:

一般都需要配合transition过渡

inline元素不支持transform,需要先变成block


★transform之translate

 常用写法
 translateX ( <length-percentage>) translateY(<length-percentage> )
 translate(<length-percentage> , <length-percentage>? )
 translatez(<length>)且父容器perspective
 translate3d(x, y,z)

经验: 要学会看懂MDN的语法示例 translate(-50%,-50%)可做绝对定位元素的居中


★transform之scale常用写法

 scaleX( <number>)
 scaleY(<number>)
 scale(<number> , <number>? )

经验:用得较少,因为容易出现模糊


★transform之rotate·常用写法

rotate( [<angle> |<zero>])
rotateZ([<angle>|<zero>])
rotateX([<angle> i<zero>])
rotateY( [ <angle>|<zero>])

经验:—般用于360度旋转制作loading


★transform 之skew

  常用写法
   skewX( [ <angle>|<zero>])
   skewY( [<angle> |zero>])
   skew( [ <angle>| <zero>], [<angle>|<zero>]?)

经验:用得较少


transform 多重效果

组合使用

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