CSS Block Formatting Context是怎么工作的?

CSS2.1规范指出,在挡路格式化上下文中,框是垂直布局的,从顶部开始.即使有浮动元素挡住go 路,也会发生这种情况,除非挡路框建立了新的挡路格式上下文.我们知道,当浏览器在挡路格式化上下文中呈现挡路框时,会省略浮动元素,为什么要建立新的挡路格式化上下文呢?

盒子(挡路盒子和内联盒子)在正常流程中是如何布局的?

我在某个地方读到过,块元素生成块框,但当用户代理绘制块框并在填充内容时将其考虑在内时,浮动元素会被忽略.虽然浮动元素将与框中其他元素的边界重叠,但解决方案是使用overflow:hidden为重叠元素建立新的块格式上下文.

"新的挡路格式化上下文还是挡路格式化",所以在画方框的时候,也会把浮动元素当作不存在一样对待.是这样吗?还是我误解了"新的挡路格式化环境?"

更新:更多问题

通过说"正是这种行为对列式布局有用.然而,它的主要用途是停止浮动,比如在"main content"div中,实际上清除浮动的边列,即源代码中较早出现的浮动."

我不明白意思,我举个例子,也许你会明白我的意思.

.content {
  background: #eee;
  color #000;
  border: 3px solid #444;
  width: 500px;
  height: 200px;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: right;
}
p {
  background: #444;
  color: #fff;
}
<div class="content">
  <h3>This is a content box</h3>
  <p>It contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float. This is normal behaviour.</p>
  <div class="float">floated box</div>
</div>

我认为浮动盒子应该浮到content级的容器顶部.此外,如果浮动框出现在标记的前面,那么它将显示我认为应该显示的内容.

.content {
  background: #eee;
  color #000;
  border: 3px solid #444;
  width: 500px;
  height: 200px;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: right;
}
p {
  background: #444;
  color: #fff;
}
<div class="content">
  <div class="float">floated box</div>
  <h3>This is a content box</h3>
  <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p>
</div>

我们怎么解释呢?我们可以用"块格式上下文和内联格式上下文"来解释它吗?

推荐答案

100

浮动,绝对定位 元素、挡路容器(如 行内块、表格单元格和 表-标题)不是挡路 包装盒和挡路包装盒中的"溢出" 而不是‘可见’(除非当 值已传播到 视口)establish new block formatting contexts用于它们的内容.

以我的大胆,establish位才是最重要的

这意味着您使用的元素overflow(除可见之外的任何元素)、floatinline-block..等将负责其子元素的布局.然后"包含"的是子元素,无论是浮点还是折叠边距,它们都应该完全包含在它们的绑定父元素中.

在挡路格式化上下文中,每个 长方体的左侧外缘与左侧接触 包含挡路的边缘(用于 从右到左的格式,右边缘 touch )

What the above line means:

由于长方体只能是矩形,而不是不规则形状,这意味着两个浮动之间(甚至在一个浮动旁边)的新块格式上下文将不会环绕相邻的侧浮动.内部的子框只能延伸到其父框的左侧(或RTL中的右侧)边缘.这种行为对于柱状样式的布局非常有用.然而,它的主要用途是停止浮动,比如在"main content"div中,实际上清除浮动的边列,即源代码中较早出现的浮动.


100

在正常情况下,浮点应该清除所有以前的浮动元素,这些元素以前是在整个源代码中浮动的,而不仅仅是您显示的"列". "浮动净空规格"中的引语很有说服力:

此属性指示

假设您有一个三列布局,其中左列和右列分别向左和向右浮动,侧列现在处于新的挡路格式上下文中,因为它们是浮动的(请记住,Float也是建立新bfc的属性之一),因此您可以愉快地浮动它们内部的列表元素,并且它们只清除它们以前在源代码中不再关心的侧列内的浮点数


要不要让主要内容成为新的挡路格式化语境?

现在,您可以简单地将中间列从两侧留出空白处,使其看起来整齐地位于两侧浮动列之间,并采用剩余宽度,如果中间列是"流动的",这是获得所需宽度的常用方法-除非您需要在content div中使用浮动/间隙(对于那些使用"clearfix"技巧或包括它们的模板的人来说,这是一种常见的情况).

请看下面这个非常简单的代码:

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  margin: 0 200px;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated">this a floated box</div>
</div>

它会产生以下结果:

在此处输入图像描述

一般来说,这是很好的,特别是如果你没有背景 colored颜色 或内部(在主要内容中)浮动-请注意,浮动是好的(还没有清除),他们所做的很可能是你除了but他们,H3的上边距和p的下边距实际上并不包含在内容div(浅灰色背景)中.

因此,对于上面代码的相同简单边距场景,请添加:

.clear-r {clear: right;}

将第二个HTML浮动框更改为:

<div class="floated clear-r"> this a floated cleared box</div>

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  margin: 0 200px;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
.clear-r {
  clear: right;
}
<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated clear-r">this a floated cleared box</div>
</div>

这一次您会得到这样的结果:

在此处输入图像描述

第二个浮点是清除右侧,但它清除的是右侧列的整个高度.右列在源代码中的前面是浮动的,所以它会如前所述地将其清除!不过,可能不是想要的效果,还要注意h3p的边距仍然是折叠的(不包含).


让它建立一个挡路格式化的上下文,为了子元素!

最后,让主内容列对其内容负责(become a Block Formatting Context):从主内容CSS中删除margin: 0 200px;,从主内容CSS中删除ADD overflow: hidden;,您将得到以下结果:

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  overflow: hidden;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
.clear-r {
  clear: right;
}
<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated clear-r">this a floated cleared box</div>
</div>

在此处输入图像描述

这可能更像你预期的情况,请注意,现在浮动被包含,它们正确地清除,忽略右侧列,h3p页边距也被包含,而不是折叠.

随着近来重置的广泛使用,边距就不那么明显了(IE仍然不能很好地理解它们)然而,中心"主要内容"刚刚发生的事情是,它变成了一个挡路格式上下文,现在负责它自己的子(后代)元素.它实际上非常类似于微软早期的hasLayout概念,它使用相同的属性display: inline-blockfloatoverflow(除了可见之外),当然表单元格总是有布局.然而,它是没有虫子的;)

希望这会有一点帮助,任何问题都可以随便问!


更新:我们正在讨论更多信息:

当您说"但是浮动元素在用户代理绘制框时被忽略,并在它们填写内容时将它们考虑在内."

是的,彩车通常会覆盖它们的容器箱,这就是您所说的父边界吗?当绘制挡路元素并且它包含浮点数时,挡路父元素本身被绘制为浮点数下的一个矩形,其他子元素的"内联匿名框"或简单的"行框"被缩短以为浮点数腾出空间

以下面的代码为例:

#content {
  background: #eee;
  color #000;
  border: 3px solid #444;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: left;
  margin: 10px;
}
p {
  background: #444;
  color: #fff;
}
<div id="content">
  <div class="float">floated box</div>
  <h3>This is a content box</h3>
  <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p>
</div>

这就产生了:

浮点如何工作

您可以看到,父元素实际上并不包含float,因为它没有完全包装它..浮点数仅仅是内容上方的floating——如果你继续向div添加内容,它最终会包裹在浮点数下方,因为p元素的(匿名)"行框"不再需要缩短.

我给段落元素上色,这样你就可以看到它实际上也在浮动下面,深灰色的背景是段落开始的地方,白色文本是"匿名线框"开始的地方-只有它们才能为浮动"腾出空间",除非你另有说明(即你改变了上下文).

再次参考上图,如果你要在p元素的左边留边距,是的,它会停止在浮动底部的文本包装,因为"行框"(白色文本)只会接触容器的左边缘,你会将p元素的彩色背景移到右边,远离浮动,但你不会改变p的格式化上下文的行为.如上图中的中柱;)

Css相关问答推荐

如果父元素跨越所有网格列,子元素是否可以与网格一起工作?

如何使一组元素的行为像字符串一样?

不了解重复-线性-渐变 colored颜色 停止

靴子,为什么我不能让任何东西正确地排好队?

如何让 v-col 变成可滚动的?

如何向 Highcharts 迷你图添加具有淡入淡出效果的线性渐变?

React Tabs 在 Tabs 之间垂直渲染标签内容

Bootstrap 5 - 更改列顺序时出现问题

用户代理必须处理(或表现得好像他们这样做)每个链接就好像链接指向单独的样式表这句话是什么意思?

如何让我的注册按钮在我的网站上像球一样 skip ?

CSS动画移动divs upwords

JavaFX TreeTableView Css for unfocused selected line

CSS 常量()用于什么?

如何制作一个居中的标题样式,其中换行符将最长的行排列在底部

如何使单选按钮看起来像切换按钮

表格的边框半径没有按预期工作

Bootstrap:在列之间添加边距/填充空间

透明的空心或切出的圆圈

如何在 CSS 中绘制一个圆形扇区?

如何在 Flexbox 中禁用等高列?