CSS新特性contain,控制页面的重绘与重排 - 博客园

文章推薦指數: 80 %
投票人數:10人

contain 为何? contain 属性允许我们指定特定的DOM 元素和它的子元素,让它们能够独立于整个DOM 树结构 ... 首页 新闻 博问 专区 闪存 班级 我的博客 我的园子 账号设置 简洁模式... 退出登录 注册 登录 ChokCoco 经不住流年似水,逃不过此间少年 CSS新特性contain,控制页面的重绘与重排 在介绍新的CSS属性contain之前,读者首先需要了解什么是页面的重绘与重排。

之前已经描述过很多次了,还不太了解的可以先看看这个提高CSS动画性能的正确姿势。

OK,下面进入本文正题, contain为何? contain属性允许我们指定特定的DOM元素和它的子元素,让它们能够独立于整个DOM树结构之外。

目的是能够让浏览器有能力只对部分元素进行重绘、重排,而不必每次都针对整个页面。

Thecontainpropertyallowsanauthortoindicatethatanelementanditscontentsare,asmuchaspossible,independentoftherestofthedocumenttree.Thisallowsthebrowsertorecalculatelayout,style,paint,size,oranycombinationofthemforalimitedareaoftheDOMandnottheentirepage. contain语法 看看它的语法: { /*Nolayoutcontainment.*/ contain:none; /*Turnonsizecontainmentforanelement.*/ contain:size; /*Turnonlayoutcontainmentforanelement.*/ contain:layout; /*Turnonstylecontainmentforanelement.*/ contain:style; /*Turnonpaintcontainmentforanelement.*/ contain:paint; /*Turnoncontainmentforlayout,paint,andsize.*/ contain:strict; /*Turnoncontainmentforlayout,andpaint.*/ contain:content; } 除去none,取值还有6个,我们一个一个来看看。

contain:size contain:size:设定了contain:size的元素的渲染不会受到其子元素内容的影响。

Thevalueturnsonsizecontainmentfortheelement.Thisensuresthatthecontainingboxcanbelaidoutwithoutneedingtoexamineitsdescendants. 我开始看到这个定义也是一头雾水,光看定义很难明白到底是什么意思。

还需实践一番: 假设我们有如下简单结构: .container{ width:300px; padding:10px; border:1pxsolidred; } p{ border:1pxsolid#333; margin:5px; font-size:14px; } 并且,借助jQuery实现每次点击容器添加一个

Coco

结构: $('.container').on('click',e=>{ $('.container').append('

Coco

') }) 那么会得到如下结果: 可以看到,容器.container的高度是会随着元素的增加而增加的,这是正常的现象。

此刻,我们给容器.container添加一个contain:size,也就会出现上述说的:设定了contain:size的元素的渲染不会受到其子元素内容的影响。

.container{ width:300px; padding:10px; border:1pxsolidred; +contain:size } 再看看会发生什么: 正常而言,父元素的高度会因为子元素的增多而被撑高,而现在,子元素的变化不再影响父元素的样式布局,这就是contain:size的作用。

contain:style 接下来再说说contain:style、contain:layout、contain:paint。

先看看contain:style。

截止至本文书写的过程中,contain:style暂时被移除了。

CSSContainmentModuleLevel1:Droptheat-risk“stylecontainment”featurefromthisspecification,moveitLevel2。

嗯,官方说辞是因为存在某些风险,暂时被移除,可能在规范的第二版会重新定义吧,那这个属性也暂且放一放。

contain:paint contain:paint:设定了contain:paint的元素即是设定了布局限制,也就是说告知UserAgent,此元素的子元素不会在此元素的边界之外被展示,因此,如果元素不在屏幕上或以其他方式设定为不可见,则还可以保证其后代不可见不被渲染。

Thisvalueturnsonpaintcontainmentfortheelement.Thisensuresthatthedescendantsofthecontainingboxdon’tdisplayoutsideitsbounds,soifanelementisoff-screenorotherwisenotvisible,itsdescendantsarealsoguaranteedtobenotvisible. 这个稍微好理解一点,先来看第一个特性: 设定了contain:paint的元素的子元素不会在此元素的边界之外被展示 设定了contain:paint的元素的子元素不会在此元素的边界之外被展示 这个特点有点类似与overflow:hidden,也就是明确告知用户代理,子元素的内容不会超出元素的边界,所以超出部分无需渲染。

简单示例,假设元素结构如下:

Coco

.container{ contain:paint; border:1pxsolidred; } p{ left:-100px; } 我们来看看,设定了contain:paint与没设定时会发生什么: CodePenDemo--contain:paintDemo 设定了contain:paint的元素在屏幕之外时不会渲染绘制 通过使用contain:paint,如果元素处于屏幕外,那么用户代理就会忽略渲染这些元素,从而能更快的渲染其它内容。

contain:layout contain:layout:设定了contain:layout的元素即是设定了布局限制,也就是说告知UserAgent,此元素内部的样式变化不会引起元素外部的样式变化,反之亦然。

Thisvalueturnsonlayoutcontainmentfortheelement.Thisensuresthatthecontainingboxistotallyopaqueforlayoutpurposes;nothingoutsidecanaffectitsinternallayout,andviceversa. 启用contain:layout可以潜在地将每一帧需要渲染的元素数量减少到少数,而不是重新渲染整个文档,从而为浏览器节省了大量不必要的工作,并显着提高了性能。

使用contain:layout,开发人员可以指定对该元素任何后代的任何更改都不会影响任何外部元素的布局,反之亦然。

因此,浏览器仅计算内部元素的位置(如果对其进行了修改),而其余DOM保持不变。

因此,这意味着帧渲染管道中的布局过程将加快。

存在的问题 描述很美好,但是在实际Demo测试的过程中(截止至2021/04/27,Chrome90.0.4430.85),仅仅单独使用contain:layout并没有验证得到上述那么美好的结果。

设定了contain:layout的指定元素,改元素的任何后代的任何更改还是会影响任何外部元素的布局,点击红框会增加一条

Coco

元素插入到container中: 简单的代码如下:

Coco

... 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:1pxsolidred; } .g-test{ width:150px; height:150px; border:1pxsolidgreen; } CodePenDemo--contain:layoutDemo 目前看来,contain:layout的实际作用不那么明显,更多的关于它的用法,你可以再看看这篇文章:CSS-tricks-contain contain:strict|contain:content 这两个属性稍微有点特殊,效果是上述介绍的几个属性的聚合效果: contain:strict:同时开启layout、style、paint以及size的功能,它相当于contain:sizelayoutpaint contain:content:同时开启layout、style以及paint的功能,它相当于contain:layoutpaint 所以,这里也提一下,contain属性是可以同时定义几个的。

CaniUse--CSSContain 截止至2021-04-27,CaniUse上的CSSContain兼容性,已经可以开始使用起来: 参考文献 CSSContainmentModuleLevel1 CSScontainment CSSContainmentinChrome52 最后 好了,本文到此结束,希望对你有帮助😃 更多精彩CSS技术文章汇总在我的Github--iCSS,持续更新,欢迎点个star订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

posted@ 2021-05-0610:00  ChokCoco  阅读(1677)  评论(5)  编辑  收藏  举报 刷新评论刷新页面返回顶部 Copyright©2022ChokCoco Poweredby.NET6onKubernetes



請為這篇文章評分?