CSS新特性contain,控制页面的重绘与重排 - 微信开放社区- 腾讯

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

contain 为何? contain 属性允许我们指定特定的DOM 元素和它的子元素,让它们能够独立于整个DOM 树结构之外。

目的 ... 评论置顶CSS新特性contain,控制页面的重绘与重排精选热门@xy2021-05-08302浏览1评论在介绍新的CSS属性contain之前,读者首先需要了解什么是页面的重绘与重排。

在介绍新的CSS属性contain之前,读者首先需要了解什么是页面的重绘与重排。

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

更多精彩CSS技术文章汇总在我的http://github.crmeb.net/u/yi ,持续更新,欢迎点个star订阅收藏。

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:sizecontain: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:paintcontain: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:layoutcontain: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-containcontain:strict|contain:content这两个属性稍微有点特殊,效果是上述介绍的几个属性的聚合效果:contain:strict:同时开启layout、style、paint以及size的功能,它相当于contain:sizelayoutpaintcontain:content:同时开启layout、style以及paint的功能,它相当于contain:layoutpaint所以,这里也提一下,contain属性是可以同时定义几个的。

CaniUse--CSSContain截止至2021-04-27,CaniUse上的CSSContain兼容性,已经可以开始使用起来:参考文献CSSContainmentModuleLevel1CSScontainmentCSSContainmentinChrome52作者:chokcoco更多精彩CSS技术文章汇总在我的http://github.crmeb.net/u/yi ,持续更新,欢迎点个star订阅收藏。

最后一次编辑于  2021-05-08  点赞0收藏分享 扫描小程序码分享复制链接删除文章后,文章内容和评论将一并被删除,且不可恢复。

删除取消评论关闭请选择投诉理由广告内容违法违规恶意灌水内容其他1个评论qiang2021-05-10加粗标红插入代码插入链接插入图片上传视频 请登录后发表内容 关闭新增或编辑超链接链接地址确认取消关闭插入视频视频链接确认取消发表瞎抄袭,也不标注一下原创,害人不浅!你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

待楼主反馈2021-05-10赞同回复关闭请选择投诉理由广告内容违法违规恶意灌水内容其他加粗标红插入代码插入链接插入图片上传视频 请登录后发表内容 关闭新增或编辑超链接链接地址确认取消关闭插入视频视频链接确认取消关闭关注“微信开放社区”公众号关注后,可在微信内接收相应的重要提醒。

请使用微信扫描二维码关注“微信开放社区”公众号作者介绍关注文章标签关于腾讯运营规范文档中心辟谣中心客服中心Copyright©2012-2022Tencent.AllRightsReserved.



請為這篇文章評分?