css属性-contain

185 阅读4分钟

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>

效果截图

捕获.PNG

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>

效果截图

捕获.PNG

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;的效果

捕获.PNG

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>

效果截图

捕获.PNG

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>

效果截图

捕获.PNG

可以看到设置了contain: paint后,超出父元素的部分不会被绘制。