CSS层叠上下文, BFC

581 阅读4分钟

问题

1:浏览器渲染合成层和css层叠上下文的关系?渲染合成层(composite)是如何进行性能优化的?

2:BFC和css层叠上下文有很多重叠的特性,两者有关系吗?浏览器会为BFC创建图层吗?

3: opacity:0, visibilite:hidden, display:none,的优势和适用

概念:


1.1 :什么是css层叠上下文?

简单来说就是dom元素在z轴的顺序,在文档流上的层级。

1.2:那哪些元素会具有层叠上下文呢?

  • 文档根元素()
  • position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
  • position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
  • z-index值不为auto的flex项(父元素display:flex|inline-flex)
  • 元素的opacity值不是1
  • 元素的transform值不是none
  • 元素mix-blend-mode值不是normal
  • 元素的filter值不是none
  • will-change指定的属性值为上面任意一个
  • 元素的-webkit-overflow-scrolling设为touch

1.3:什么是浏览器合成层?

  • 在渲染时“DOM Tree”和“css层叠样式表”合并得到DOM tree的节点样式,在遍历DOM Tree计算(Layout)每个dom节点的尺寸位置得到RenderTree。
  • 生成的RenderTree会将具有“css层叠上下文”属性的dom节点,单独提成一个图层。
  • 具有单独图层的dom节点,在浏览器渲染的时候会有单独的合成层,并拥有单独的“绘图上下文”,

1.4:渲染合成层(composite)是如何进行性能优化的?

  • 因为“合成层”拥有独立“绘图上下文”,当图层内的样式改变,不会触发整个RenderTree回流和重绘。并且针对当前图层生成的“绘制指令”会交给“GPU进行栅格化生成位图”(CPU也会开启多进程),将位图合并成图片交给浏览器进程挂载。(也就是具有单独图层的dom节点在进行渲染,可以提高性能)。

2.1:什么是BFC?

简单来说就是“块级格式化上下文”,

2.2:那“块级格式化上下文”有什么特性呢?

“块级格式化上下文”具有独立的渲染区域,与其他DOM元素互不干扰。

2.3:怎样才能形成BFC呢?

  • 文档根元素()
  • 定位元素(元素的 position 为 absolute 或 fixed)
  • 浮动元素(元素的 float 不是 none)
  • displayinline-block, table-cell, table-caption, flex, inline-flex其中的一项
  • overflowautoscrollhidden

2.4:思考问题:具有‘定位的元素’和‘根HTML元素’都能形成BFC和css层叠上下文,那两者之间有什么关系吗?

应该是没有关系的

1:“BFC”主要是表明元素能形成单独的“块级格式化上下文”,强调的是与其他元素在布局上不产生互相干扰。

1:“css层叠上下文”主要是表明当前的DOM元素具有“层叠上下文”,强调的是在文档流上的层级。表面当前层叠元素在z轴上的距离


3.1:opacity:0, visibilite:hidden, display:none,的优势和适用

表现层面的异同点:

  • opacity:0;与 visibilite:hidden;

相同点:都占据文档流中的位置。

不同点:visibilite:hidden不能绑事件,opacity:0可以绑定事件

  • display:none。

不占据文档流

渲染层面异同点

  • Opacity: 0; (由上面的问题1.2可以得到opacity不为1,会创建层叠上下文)

因为有了“层叠上下文”,浏览器会为opacity:0;元素创建单独的“图层”具有独立的“绘图上下文”,在opacity改变时不会触发RenderTree的“回流”和“重绘”。同时会开启CPU加速进行“栅格化生成位图”,并合并位图成图片交给浏览器进程挂载。

  • visibilite:hidden;

在隐藏和显示时,dom元素的位置和尺寸不会改变,此时不会触发“RenderTree”重新计算dom元素的位置,因此只会触发“重绘”。

  • display:none;
  • 在隐藏和显示时会触发dom元素的位置改变,因此会触发“RenderTree”从新计算dom的大小和位置,会触发“回流”。

所以从渲染性能上讲:

Opacity: 0; > visibilite:hidden;> display:none;