contain属性用于将元素及其子元素独立于文档的其他部分,和bfc比较类似
其取值可以是:
none 按照默认方式渲染
size 父元素的大小计算与子元素大小无关
inline-size 父元素的横向大小计算与子元素无关
layout 从页面的其余部分中隔离出元素的内部布局。此值意味着元素外的任意内容和元素内部布局互不影响
style 对于可在元素及其后代外产生影响的属性,其影响将不会逃离包含元素。计数器和引号的作用域被限制为元素及其内容
paint 元素后代不在元素边界外显示
strict 等同于 contain: size layout paint style
content 等同于 contain: layout paint style
size
测试代码
body{
display: flex;
gap: 200px;
flex-direction: column;
}
.card {
width: fit-content;
min-width: 100px;
min-height: 100px;
border: black solid thin;
}
.child {
width: 200px;
height: 200px;
background: rgba(100, 149, 237, 0.3);
}
<div class="card" style="contain: size;">
<div class="child"></div>
</div>
<div class="card" style="">
<div class="child"></div>
</div>
效果截图
card类设置父元素的最小宽度和最小高度为100px,child设置子元素的宽度和高度为200px。当我们对第一个父元素设置contain:size后,父元素的大小并不会因为子元素比父元素大而被撑大,而第二个父元素我们没有设置contain:size,可以看到父元素的大小被撑大到可以包含子元素。
inline-size
inline-size和size的效果类似,只不过inline-size只是在横向上不会被撑大,纵向上还是会被撑大
layout
测试代码
.card {
width: fit-content;
min-width: 100px;
min-height: 100px;
border: black solid thin;
}
.child1 {
width: 20px;
height: 20px;
margin-top: 100px;
float: left;
background: rgba(100, 149, 237, 0.3);
}
.child2 {
width: 20px;
height: 20px;
position: fixed;
top: 0;
right: 0;
background: rgba(218, 16, 76, 0.3);
}
<div class="card">
<div class="child1"></div>
<div class="child2">2</div>
</div>
<div>test</div>
<div class="card" style="contain: layout;margin-top: 100px">
<div class="child1"></div>
<div class="child2">1</div>
</div>
<div>test</div>
效果截图
card类的父元素的最小宽度和最小高度都是100px,子元素child1是一个浮动元素,子元素child2是一个fixed的元素,第一个父元素没有其他设置,第二个父元素设置为contain: layout。
可以明显看到第一个父元素的child1浮动元素影响到了下面的布局,并且child2的定位是以屏幕的为准。但是第二个父元素有点类似bfc,浮动元素不会影响外面的内容,而是把父元素撑高了,并且其child2的定位以父元素为准。
上面我们说layout是将元素从页面的其余部分中隔离出元素的内部布局。此值意味着元素外的任意内容和元素内部布局互不影响,但是在测试中,第二个明显把父元素撑高了,还是会影响后面的元素,这其实是因为父元素我们并没有设置固定的宽高,而是设置的最小宽高。这里的不影响是指得该元素里面的子元素不会影响外面,并不是该元素本身不影响外面,所以这里浮动元素设置margin后会导致父元素的大小被撑高,进而影响外面,如果将 min-width: 100px; min-height: 100px;修改为width: 100px;height: 100px;就会看出区别,此时父元素便不会被撑高。
修改成width: 100px; height: 100px;的效果
style
style主要影响css中的quotes和计数器,这个比较简单,不再详述
测试代码
body {
counter-reset: list-items;
}
li::before {
counter-increment: list-items;
content: counter(list-items) ":";
}
<ul>
<li>元素甲</li>
<li>元素乙</li>
<li style="contain: style">元素丙</li>
<li>元素丁</li>
<li>元素戊</li>
</ul>
效果截图
paint
paint和overflow: hidden效果一致,超出父元素的部分不会被绘制
测试代码
body{
display: flex;
flex-direction: column;
gap: 200px;
}
.card {
width: 100px;
height: 100px;
border: black solid thin;
}
.child {
width: 200px;
height: 200px;
background: rgba(100, 149, 237, 0.3);
}
<div class="card">
<div class="child"></div>
</div>
<div class="card" style="contain: paint;">
<div class="child"></div>
</div>
效果截图
可以看到设置了contain: paint后,超出父元素的部分不会被绘制。