CSS新特性contain,控制页面的重绘与重排
在介绍新的 CSS 属性 contain 之前,读者首先需要了解什么是页面的重绘与重排。
之前已经描述过很多次了,还不太了解的可以先看看这个提高 CSS 动画性能的正确姿势。
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 containment for layout, style, paint, and size. */
contain: strict;
/* Turn on containment for layout, style, and paint. */
contain: content;
/* 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;
}
除去 none,取值还有 6 个,我们一个一个来看看。
contain: size
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 class="container">
</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: 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:设定了 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 class="container">
<p>Coco</p>
</div>
.container {
contain: paint;
border: 1px solid red;
}
p{
left: -100px;
}
我们来看看,设定了 contain: paint 与没设定时会发生什么:
CodePen Demo -- contain: paint Demo
设定了 contain: paint 的元素在屏幕之外时不会渲染绘制
通过使用 contain: paint, 如果元素处于屏幕外,那么用户代理就会忽略渲染这些元素,从而能更快的渲染其它内容。
contain: layout
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 class="container">
<p>Coco</p>
...
</div>
<div class="g-test"></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
Can i Use -- CSS Contain
截止至 2021-04-27,Can i Use 上的 CSS Contain 兼容性,已经可以开始使用起来:
参考文献
最后
好了,本文到此结束,希望对你有帮助
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
CSS新特性contain,控制页面的重绘与重排的更多相关文章
- 2017 css新特性
2017年要学习的三个CSS新特性 这是翻译的一篇文章,原文是:3 New CSS Features to Learn in 2017,翻译的不是很好,如有疑问欢迎指出. 新的一年,我们有一系列新的东 ...
- 浏览器渲染详细过程:重绘、重排和 composite 只是冰山一角
https://juejin.im/entry/590801780ce46300617c89b8 渲染 这张很经典的图许多人都看过,其中的概念大家应该都很熟悉,也就是这么几个步骤:js修改dom结构或 ...
- 关于重绘and重排
在研究CSS3动画性能的时候,看到了重排两个字. 突然想到自己虽然听说过这么个东东,但一直也没深入研究之. 趁着当下正好有研究的劲头,所以一不做二不休,把这个point也给学习了. 同样是一番查找资料 ...
- HTML页面的重绘(repaint)和重流(reflow)
重流(Reflow)是指布局引擎为frame计算图形的过程. frame是一个矩形,拥有宽高和相对父容器的偏移.frame用来显示盒模型(content model), 但一个content mode ...
- DOM的回流和重绘(重排、重绘)
什么是DOM回流? 页面渲染时,我们对HTML结构简单的增删查改时,浏览器会对所有的dom进行重新排序,这就i是DOM回流,严重影响浏览器性能 DOM的回流和重绘: **DOM的回流**:当页面中元素 ...
- 2017年学习的三个CSS新特性
这是翻译的一篇文章,原文是:3 New CSS Features to Learn in 2017,翻译的不是很好,如有疑问欢迎指出. 新的一年,我们有一系列新的东西要学习.尽管CSS有很多新的特性, ...
- 【译】2017年要学习的三个CSS新特性
这是翻译的一篇文章,原文是:3 New CSS Features to Learn in 2017,翻译的不是很好,如有疑问欢迎指出. 新的一年,我们有一系列新的东西要学习.尽管CSS有很多新的特性, ...
- 2017年要学习的三个CSS新特性
这是翻译的一篇文章,原文是:3 New CSS Features to Learn in 2017,翻译的不是很好,如有疑问欢迎指出. 新的一年,我们有一系列新的东西要学习.尽管CSS有很多新的特性, ...
- CSS新特性之2D转换transform
transform是css3中具有颠覆性特征之一,可以实现元素的位移.旋转.缩放等效果 1.位移translate 1.1语法 transform: translate(x,y);//x,y分别表示x ...
随机推荐
- 5G时代,为什么NoSQL和SQL存在短板?
01 介绍 当今的通信服务提供商(CSP)需要能够在处理海量复杂的数据的同时,不会下降或者减慢网路响应速度和可靠性.5G时代,设备和用户数量呈指数级增长,这对业务支持服务(BSS)提出了新需求,也成为 ...
- 六. SpringCloud网关
1. Gateway概述 1.1 Gateway是什么 服务网关还可以用Zuul网关,但是Zuul网关由于一些维护问题,所以这里我们学习Gateway网关,SpringCloud全家桶里有个很重要的组 ...
- Redis工具收费后新的开源已出现
作者:三十三重天 博客: zhouhuibo.club 引言 Redis工具哪家强,中国山东找蓝翔.哎呀,串台了. 众所周知,开源的最终还是收费. Reids Desktop 秉承了这一理念,苦逼的程 ...
- [HDU5592] ZYB's Premutation
[HDU5592] ZYB's Premutation 题目大意:一个由\([1,n]\)组成的数列,但不知道具体排列,但给出每个前缀的逆序对数目,让你还原排列 Solution 创造一颗\([1,n ...
- 递归函数初步理解---python实现(汉诺塔问题)
递归常被用来描述以自相似的方法重复事物的过程,在程序中指的是在函数定义中使用函数自身的方法. 递归是一个树结构,分为递推和回归的过程,当递推到达底部时,就会开始回归. 问题描述:A比B大两岁,B比C大 ...
- elf.h
1 /* This file defines standard ELF types, structures, and macros. 2 Copyright (C) 1995-2019 Free So ...
- java中ReentrantLock核心源码详解
ReentrantLock简介 ReentrantLock是一个可重入且独占式的锁,它具有与使用synchronized监视器锁相同的基本行为和语义,但与synchronized关键字相比,它更灵活. ...
- Git - 使用命令和P4Merge进行diff
P4Merge P4Merge是Git的一个第三发Diff和Merge工具(可视化冲突解决工具). 下载地址: https://www.perforce.com/downloads/visual-me ...
- IT培训有哪些坑(一)?
IT行业资薪很高,每年都有很多同学冲着高薪去,去各个培训机构学习,期望将来能找个高薪的工作,有个好的出路.我们先不说你选多好,多靠谱的机构,我先来告诉大家有哪些不靠谱,不能选,选了就入坑了的. IT培 ...
- Spring的循环依赖
本文简要介绍了循环依赖以及Spring解决循环依赖的过程 一.定义 循环依赖是指对象之间的循环依赖,即2个或以上的对象互相持有对方,最终形成闭环.这里的对象特指单例对象. 二.表现形式 对象之间的循环 ...