이 문서에서는 새로운 CSS 기능 포함을 소개하고 페이지 다시 그리기 및 리플로우를 제어하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
새로운 CSS 속성 contain
을 도입하기 전에 독자는 먼저 페이지 다시 그리기와 리플로우가 무엇인지 이해해야 합니다. contain
之前,读者首先需要了解什么是页面的重绘与重排。
OK,下面进入本文正题。
contain
为何?contain
属性允许我们指定特定的 DOM 元素和它的子元素,让它们能够独立于整个 DOM 树结构之外。目的是能够让浏览器有能力只对部分元素进行重绘、重排,而不必每次都针对整个页面。
The contain property allows an author to indicate that an element and its contents are, as much as possible, independent of the rest of the document tree. This allows the browser to recalculate layout, style, paint, size, or any combination of them for a limited area of the DOM and not the entire page.
contain
语法看看它的语法:
{ /* No layout containment. */ contain: none; /* Turn on size containment for an element. */ contain: size; /* Turn on layout containment for an element. */ contain: layout; /* Turn on style containment for an element. */ contain: style; /* Turn on paint containment for an element. */ contain: paint; /* Turn on containment for layout, paint, and size. */ contain: strict; /* Turn on containment for layout, and paint. */ contain: content; }
除去 none
,取值还有 6 个,我们一个一个来看看。
contain: size: 设定了 contain: size
的元素的渲染不会受到其子元素内容的影响。
The value turns on size containment for the element. This ensures that the containing box can be laid out without needing to examine its descendants.
我开始看到这个定义也是一头雾水,光看定义很难明白到底是什么意思。还需实践一番:
假设我们有如下简单结构:
<div> </div>
.container { width: 300px; padding: 10px; border: 1px solid red; } p { border: 1px solid #333; margin: 5px; font-size: 14px; }
并且,借助 jQuery 实现每次点击容器添加一个 <p>Coco</p>
结构:
$('.container').on('click', e => { $('.container').append('<p>Coco</p>') })
那么会得到如下结果:
可以看到,容器 .container
的高度是会随着元素的增加而增加的,这是正常的现象。
此刻,我们给容器 .container
添加一个 contain: size
,也就会出现上述说的:设定了 contain: size
的元素的渲染不会受到其子元素内容的影响。
.container { width: 300px; padding: 10px; border: 1px solid red; + contain: size }
再看看会发生什么:
正常而言,父元素的高度会因为子元素的增多而被撑高,而现在,子元素的变化不再影响父元素的样式布局,这就是 contain: size
的作用。
接下来再说说 contain: style
、contain: layout
、contain: paint
。先看看 contain: style。
截止至本文书写的过程中,contain: style
暂时被移除了。
CSS Containment Module Level 1: Drop the at-risk “style containment” feature from this specification, move it Level 2。
嗯,官方说辞是因为存在某些风险,暂时被移除,可能在规范的第二版会重新定义吧,那这个属性也暂且放一放。
contain: paint:设定了 contain: paint
的元素即是设定了布局限制,也就是说告知 User Agent,此元素的子元素不会在此元素的边界之外被展示,因此,如果元素不在屏幕上或以其他方式设定为不可见,则还可以保证其后代不可见不被渲染。
This value turns on paint containment for the element. This ensures that the descendants of the containing box don’t display outside its bounds, so if an element is off-screen or otherwise not visible, its descendants are also guaranteed to be not visible.
这个稍微好理解一点,先来看第一个特性:
contain: paint
的元素的子元素不会在此元素的边界之外被展示contain: paint
的元素的子元素不会在此元素的边界之外被展示这个特点有点类似与 overflow: hidden
,也就是明确告知用户代理,子元素的内容不会超出元素的边界,所以超出部分无需渲染。
简单示例,假设元素结构如下:
<div> <p>Coco</p> </div>
.container { contain: paint; border: 1px solid red; } p{ left: -100px; }
我们来看看,设定了 contain: paint
포함
왜죠? contain
속성을 사용하면 특정 DOM 요소와 해당 하위 요소를 지정하여 전체 DOM 트리 구조와 독립적일 수 있습니다. 그 목적은 매번 전체 페이지를 대상으로 삼을 필요 없이 일부 요소만 다시 그리고 재배열할 수 있는 기능을 브라우저에 제공하는 것입니다. contain 속성을 사용하면 작성자는 요소와 그 내용이 문서 트리의 나머지 부분과 최대한 독립적임을 나타낼 수 있습니다. 이를 통해 브라우저는 레이아웃, 스타일, 페인트, 크기 등을 다시 계산할 수 있습니다. 전체 페이지가 아닌 DOM의 제한된 영역에 대한 조합입니다.
contain
구문구문을 살펴보세요: <div>
<p>Coco</p>
...
</div>
<div></div>
Remove 없음
, 6개의 값이 더 있습니다. 하나씩 살펴보겠습니다.
contain: size
로 설정된 요소의 렌더링은 하위 요소의 콘텐츠에 영향을 받지 않습니다. 🎜값은 요소의 크기 제한을 활성화합니다. 이렇게 하면 하위 항목을 검사할 필요 없이 포함 상자를 배치할 수 있습니다.🎜처음 이 정의를 봤을 때 혼란스러웠습니다. 정의가 정확히 무엇을 의미하는지 파악하기 어렵습니다. 아직 연습이 필요합니다. 🎜🎜다음과 같은 간단한 구조가 있다고 가정해 보겠습니다. 🎜
html, body { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; flex-direction: column; gap: 10px; } .container { width: 150px; padding: 10px; contain: layout; border: 1px solid red; } .g-test { width: 150px; height: 150px; border: 1px solid green; }rrreee🎜그리고 jQuery의 도움으로 컨테이너를 클릭할 때마다
<p>Coco</p>
구조가 추가되었습니다: 🎜rrreee🎜 그러면 다음과 같은 결과를 얻게 됩니다: 🎜🎜🎜🎜요소가 증가함에 따라 컨테이너 .container
의 높이가 증가하는 것을 볼 수 있습니다. 이는 정상적인 현상입니다. 🎜🎜이 시점에서 컨테이너 .container
에 contain: size
를 추가하면 위에서 언급한 내용이 나타납니다. Set contain: size가 포함된 요소의 렌더링은 하위 요소의 콘텐츠에 영향을 받지 않습니다
. 🎜rrreee🎜무슨 일이 다시 일어나는지 확인하세요: 🎜🎜🎜🎜일반적으로 하위 요소의 증가로 인해 상위 요소의 높이가 증가합니다. 그러나 이제 하위 요소의 변경은 더 이상 상위 요소의 스타일 레이아웃에 영향을 미치지 않습니다. 이것이 입니다. 포함 : 크기의 역할
. 🎜contain: 스타일
, contain: 레이아웃
및 contain: 페인트
에 대해 이야기해 보겠습니다. . 먼저 contain: 스타일을 살펴보겠습니다. 🎜🎜이 글을 쓰는 시점에서 contain: style
이 일시적으로 제거되었습니다. 🎜CSS 봉쇄 모듈 레벨 1🎜: 삭제 - 이 사양의 위험 "스타일 억제" 기능을 레벨 2로 이동합니다.🎜글쎄요, 공식적으로는 특정 위험으로 인해 일시적으로 제거되었다는 것입니다. 사양의 두 번째 버전에서 재정의될 수 있으므로 이 속성은 당분간 그대로 유지됩니다. 🎜
contain: 페인트
가 있는 요소는 레이아웃 제한을 갖도록 설정됩니다. 이는 사용자 에이전트에게 이 요소의 하위 요소가 요소는 이 요소의 경계 외부에서 렌더링되지 않습니다. 따라서 요소가 화면 밖에 있거나 다른 방식으로 표시되지 않는 경우 해당 하위 요소도 표시되지 않고 렌더링되지 않습니다. 🎜이 값은 요소에 대한 페인트 포함을 활성화합니다. 이렇게 하면 포함 상자의 하위 항목이 경계 외부에 표시되지 않으므로 요소가 화면 밖에 있거나 표시되지 않는 경우 해당 하위 항목도 표시됩니다.🎜첫 번째 기능을 먼저 살펴보겠습니다. 🎜
contain: Paint
가 설정된 요소의 하위 요소는 표시되지 않습니다. 이 요소에 포함된 요소는 이 요소의 경계 외부에 표시됩니다.contain: Paint
가 설정된 요소의 하위 요소는 이 요소의 경계 외부에 표시되지 않습니다. overflow:hidden
과 다소 유사합니다. 즉, 하위 요소의 콘텐츠가 오버플로의 경계를 초과하지 않음을 사용자 에이전트에 명확하게 알립니다. 요소이므로 초과 부분을 렌더링할 필요가 없습니다. 🎜🎜간단한 예, 요소 구조가 다음과 같다고 가정: 🎜rrreeerrreee🎜contain: 페인트
가 설정되었는지 여부를 살펴보겠습니다. 🎜🎜🎜🎜🎜🎜CodePen Demo -- contain: 페인트 데모 🎜🎜contain: paint
的元素在屏幕之外时不会渲染绘制通过使用 contain: paint
, 如果元素处于屏幕外,那么用户代理就会忽略渲染这些元素,从而能更快的渲染其它内容。
contain: layout:设定了 contain: layout
的元素即是设定了布局限制,也就是说告知 User Agent,此元素内部的样式变化不会引起元素外部的样式变化,反之亦然。
This value turns on layout containment for the element. This ensures that the containing box is totally opaque for layout purposes; nothing outside can affect its internal layout, and vice versa.
启用 contain: layout
可以潜在地将每一帧需要渲染的元素数量减少到少数,而不是重新渲染整个文档,从而为浏览器节省了大量不必要的工作,并显着提高了性能。
使用 contain:layout
,开发人员可以指定对该元素任何后代的任何更改都不会影响任何外部元素的布局,反之亦然。
因此,浏览器仅计算内部元素的位置(如果对其进行了修改),而其余DOM保持不变。因此,这意味着帧渲染管道中的布局过程将加快。
描述很美好,但是在实际 Demo 测试的过程中(截止至2021/04/27,Chrome 90.0.4430.85),仅仅单独使用 contain:layout
并没有验证得到上述那么美好的结果。
设定了 contain: layout
的指定元素,改元素的任何后代的任何更改还是会影响任何外部元素的布局,点击红框会增加一条 <p>Coco</p>
元素插入到 container
中:
简单的代码如下:
<div> <p>Coco</p> ... </div> <div></div>
html, body { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; flex-direction: column; gap: 10px; } .container { width: 150px; padding: 10px; contain: layout; border: 1px solid red; } .g-test { width: 150px; height: 150px; border: 1px solid green; }
CodePen Demo -- contain: layout Demo
目前看来,contain: layout
的实际作用不那么明显,更多的关于它的用法,你可以再看看这篇文章:CSS-tricks - contain
这两个属性稍微有点特殊,效果是上述介绍的几个属性的聚合效果:
contain: strict
:同时开启 layout、style、paint 以及 size 的功能,它相当于 contain: size layout paint
contain: content
:同时开启 layout、style 以及 paint 的功能,它相当于 contain: layout paint
所以,这里也提一下,contain 属性是可以同时定义几个的。
截止至 2021-04-27,Can i Use 上的 CSS Contain 兼容性,已经可以开始使用起来:
好了,本文到此结束,希望对你有帮助 :)
原文地址:https://segmentfault.com/a/1190000039950464
作者:chokcoco
更多编程相关知识,请访问:编程入门!!
위 내용은 새로운 CSS에 페이지 다시 그리기 및 리플로우 제어 기능이 포함된 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!