侧边栏壁纸
博主头像
MicroMatrix 博主等级

明月别枝惊鹊,清风半夜鸣蝉

  • 累计撰写 116 篇文章
  • 累计创建 36 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

你不知道的CSS之包含块

David
2025-03-08 / 0 评论 / 0 点赞 / 8 阅读 / 0 字

什么是包含块?

包含块(containing block),顾名思义,就是一个包含其他元素的“块”。但它可不只是一个简单的容器哦!它不仅影响子元素的位置,还会影响到**宽度、长度、内外边距(padding、margin)、甚至定位(position)**等各种CSS属性的计算。

例如,像下图一样,很多时候我们看不见它的存在,但它正在幕后默默工作。它的作用,就是决定元素的尺寸和位置,特别是当我们使用百分比值时,计算依据就是包含块的尺寸

https://xiejie-typora.oss-cn-chengdu.aliyuncs.com/2022-08-14-142459.png

是不是感觉它像个隐藏的大boss,一切似乎都在它的掌控之中?


简单的例子,告诉你包含块怎么“作妖”!

好,让我们从一个简单的例子开始:

<body>
  <div class="container">
    <div class="item"></div>
  </div>
</body>
.container {
  width: 500px;
  height: 300px;
  background-color: skyblue;
}

.item {
  width: 50%;
  height: 50%;
  background-color: red;
}

根据上面的代码,你一定会说:div.item的宽度是250px,高度是150px。嗯,没错!但是你知道吗,这个答案虽然正确,但并不完全准确!真正的计算方式是这样的:

div.item的尺寸,实际上是通过它的包含块来计算的!

在这个例子里,div.item的包含块是 div.container,也就是它的父元素。因为 div.container的宽度是500px,所以50%的宽度就是250px;高度300px,所以50%就是150px。

所以,记住:百分比计算的依据是包含块的尺寸,而不是父元素的尺寸!


包含块的规则:绝对定位的奇妙之处

好,现在我们进入了包含块的“黑洞”——对于绝对定位元素,包含块是怎样计算的呢?看一下这个神秘的例子:

<body>
  <div class="container">
    <div class="item">
      <div class="item2"></div>
    </div>
  </div>
</body>
.container {
  width: 500px;
  height: 300px;
  background-color: skyblue;
  position: relative;
}

.item {
  width: 300px;
  height: 150px;
  border: 5px solid;
  margin-left: 100px;
}

.item2 {
  width: 100px;
  height: 100px;
  background-color: red;
  position: absolute;
  left: 10px;
  top: 10px;
}

你可能已经脑补了 div.item2的位置,但让我来帮你补充一下:div.item2的包含块是 div.container,而不是 div.item!因为 div.containerposition: relative;的属性,它是一个定位容器。

所以当你使用 position: absolute;时,包含块的计算会参照最近的定位祖先元素,而不是简单的父元素。这就是为什么 div.item2的包含块是 div.container的原因,而不是 div.item


一些更“迷”的例子:Transform与包含块

接下来,让我们来看看transform如何影响包含块的计算:

<body>
  <div class="container">
    <div class="item">
      <div class="item2"></div>
    </div>
  </div>
</body>
.container {
  width: 500px;
  height: 300px;
  background-color: skyblue;
  position: relative;
}

.item {
  width: 300px;
  height: 150px;
  border: 5px solid;
  margin-left: 100px;
  transform: rotate(0deg); /* 新增代码 */
}

.item2 {
  width: 100px;
  height: 100px;
  background-color: red;
  position: absolute;
  left: 10px;
  top: 10px;
}

这里,我们为 .item添加了 transform: rotate(0deg),看似没变化,但在实际渲染中,你会发现**div.item2的包含块变成了 div.item**,而不再是 div.container。原因就是:transform让 div.item变成了一个块容器,因此 div.item2的包含块就“变脸”了。


惊天大揭秘!包含块的实际应用

让我们总结一下吧!你已经掌握了最重要的几点:

  • 根元素html)的包含块就是浏览器的视口(viewport),大小等于屏幕可视区域。
  • 对于非根元素,包含块的计算主要基于其最近的定位父元素,如果该父元素是 position: relativeabsolutefixedsticky,那么包含块就由它决定。
  • 对于 absolute定位的元素,包含块是它最近的定位祖先元素的内边距区的边缘
  • 你还得知道:transformwill-change等属性也能改变包含块的行为。

最后再来看一些有趣的例子:

元素 包含块
html 初始包含块(视口)
body html
div1 body
p1 div1
p2 div1
em1 p2
strong1 p2

如果你对 div1进行了定位,比如加上 position: absolute;,那么它的包含块就会变成初始包含块,而不再是 body了。

0
css

评论区