浮动元素对齐不一致
Inconsistent alignment of a Floating Element
摘要
浮动元素与相邻的非浮动元素的垂直对齐方式不一致,这种变化取决于容器或父元素的 border-top-width
值和 overflow
值。给出了什么?
背景
我在练习涉及 <img>
元素的布局时遇到了这种情况。我上个月才开始自学 HTML/CSS,所以如果这是因为我忽略了一些基本知识,请教我一些。
详情
<div>
容器中有一个浮动元素和一个非浮动块元素。
浮动元素 (p1) 具有固定宽度和 0 边距。它在任一 left/right 方向上浮动。它是起始浮动元素(即第一个浮动到包含框的一侧)。
相邻元素 (p2) 是环绕 p1 的非浮动块。请注意,这里特意为 p2 指定了非零边距值,以表明 p1 和 p2 在下面解释的一种情况下未对齐。
包含元素 <div>
的填充为 0。
通过这个设置,我发现浮动元素 (p1) 至少有两种方式可以相对于 border-top-width
和 overflow
:
定位自己
- The floating element (p1) aligns with the adjacent non-floating element (p2) (i.e. the top-border of p1 box lines up with the top-border of p2 box).
CSS Rules:
div {border-top-width: 0px;}
and
div {overflow: visible;}
The floating element (p1) instead aligns with the top border of
the containing box or parent element.
CSS Rules:
div {border-top-width: non-0px;}
or
div {overflow: auto/hidden/scroll/}
请注意,在情况 2 中,任一规则本身都足以启用对齐。
代码
代码,过于简化,看起来像这样:
HTML
<div>
<img src="example.jpg">
<p>Random text</p>
</div>
CSS
img {
float: left;
}
/* floating element aligns with adjacent element */
div {
border: none;
overflow: visible;
}
或
/* floating element aligns with top border of container */
div {
border-top-width: 1px;
overflow: auto;
}
我在 jsfiddle 上举了一个例子:https://jsfiddle.net/tLumj9x7/
或者您可以使用以下代码片段进行检查:
/* <body>, <div> margin set to 0 to avoid interference */
body {
margin: 0px;
}
div {
margin: 0px;
}
/* border drawn above the paragraphs to denote top border of 2nd <div> */
.div1 {
border-bottom: 1px solid;
}
p {
border: 1px solid;
}
/* floating paragraph: margin set to 0 to highlight unusual alignment */
.p1 {
float: left;
margin: 0px;
width: 400px;
}
/* note that a <p> element has a default margin of 1em, so this declaration is just for demonstration */
.p2 {
margin: 16px;
}
input#border:checked~div.div2 {
border-top: 0.02px solid transparent;
}
input#overflow:checked~div.div2 {
overflow: auto;
}
<form>
<input type="checkbox" name="border" id="border" />container border-top-width: non-0<br />
<input type="checkbox" name="overflow" id="overflow" />container overflow: auto / hidden/ scroll<br />
<div class="div1">
</div>
<div class="div2">
<p class="p1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
<p class="p2">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</form>
问题
起始浮动元素相对于其包含元素(在我们的例子中是 <div>
块)的位置究竟是如何确定的?
border-top-width
属性和凝视浮动元素的"anchoring"有什么关系?
同上 overflow
属性。在属性方面,overflow
如何影响容器框"structurally"?
在上面的两个场景中,如果有的话,显示 "default" 定位起始浮动元素?
关于不同但相关的说明。如果我在向左浮动的 p1 浮动元素周围放置边距,它的左边距会与相邻的 p2 非浮动元素的左边距重叠。这是标准行为吗?我读到浮动元素的边距不会折叠,所以我不确定我是否理解正确。
这是我在 Whosebug 上的第一个 post,感谢您阅读我的问题!我是 Web 开发的新手,期待阅读您的回答。
浮动框将垂直放置,与框未浮动时的位置水平。在这种情况下,它是其容器中的第一个元素,其上边缘与其容器内容框的顶部重合。 (您看到的效果差异是 div 容器的内容框上下移动。)
在最初的情况下,p1 是浮动的,因此不在流中,所以没有什么可以阻止 p2 的垂直边距与其祖先一起折叠。非 0 宽度边框顶部的存在意味着 p2 的上边距不再与 div 元素的上边距相邻(即它们被边框分开),因此边距不能折叠在一起.
overflow:auto
的副作用是它会导致 div 建立块格式化上下文。块格式化上下文的后代边距不会与建立块格式化上下文的元素的边距重叠。使 div 建立块格式化上下文的更直接但更新的方法是为其设置 display:flow-root
.
默认情况下,流入块框的相邻垂直边距会折叠。因此 p 元素 (p2) 的默认上边距与 div 和 body 元素的上边距折叠,增加 div 元素内容框顶部上方的边距,从而推动浮动元素较低。
Collapsing Margins 影响垂直边距。对于水平边距,您看到的不是边距塌陷,而是不同的效果。 p1 和 p2 相互重叠。 p2 并不完全包围 p1,它的内容确实如此。发生的情况是 p2 由一堆线框组成。 p1 旁边的每个行框的左边缘与 p1 的右边距重合。 p2 的左边距仍然触及包含 div 的内容框的左边缘,就像 p1 根本不存在一样,所以它不会影响那些行框左边缘的位置,除非 p2 的左边margin、border 和 padding 大于 p1 的 margin box 的宽度。
尝试根据 Alochi 的回答回答我自己的问题,看看我的想法是否正确。谢谢你,阿洛奇!
本质上,如果一个浮动框是它的第一个元素
容器,它的垂直对齐行为就像它的 non-floating
对方将在其容器中(减去保证金崩溃)。也就是说,
浮动框(取决于其 margin
、border
)重合
包含块的内容边缘(即 parent 元素)。
在border-top-width
是否为0值的情况下,
浮动框的定位实际上是一致的,因为它
外部上边缘与其包含的内容边缘重合
堵塞。不同之处在于: 1) 周围没有边框
包含块(其 border-top-width
为 0),
non-floating 与浮动块相邻的块(在我们的例子中是 p2),
与包含块的边距一起折叠,无论
容器margin
是否为0,留下视觉
margin-less 浮动块与其对应的印象
相邻 non-floating 元素; 2) border-top-width
非 0
在包含块周围,non-floating 的上边距边缘
块与包含块的顶部内容边缘重合,
因为容器周围的边界将其分开
与其后代的边缘,留下视觉印象
margin-less 浮动块与容器对齐,
而不是相邻的 non-floating 块。
感谢您的澄清。这也是我最初试图使对齐行为合理化的方式。从那以后,我深入挖掘并找到了控制浮动定位的规则 here。规则 #8 规定 "a floating box must be placed as high as possible",而规则 #4 规定 "a floating box's outer top may not be higher than the top of its containing block."
- 在
overflow
的情况下,如果它的值为non-visible,那么
为元素的布局创建块格式化上下文
children(根据这些 formatting context rules),边距
位于顶部的任何 children 元素的
容器的那个(根据 margin collapsing rules),如
如果前者包含在容器的内容边缘内。
感谢您提供有关块格式化上下文的提示!我不知道这个概念。我想知道在块格式化发生之前格式化上下文是什么,如果有的话?
由于大多数块元素默认没有边框(比如
<html>
、<body>
、<div>
,因为他们的 overflow
是可见的
默认情况下,"default" 场景是一个浮动框
似乎与相邻的 non-floating 块对齐,因为
后者的任何边距都会随着
包含块。
浮动元素未与任何其他元素一起流动non-floating
容器内的元素,以及任何相邻的 non-floating
块定位自己,就好像浮动元素不存在一样。
只有 non-floating 块的内容,其位置是
静态或相对,环绕浮动块。
摘要
浮动元素与相邻的非浮动元素的垂直对齐方式不一致,这种变化取决于容器或父元素的 border-top-width
值和 overflow
值。给出了什么?
背景
我在练习涉及 <img>
元素的布局时遇到了这种情况。我上个月才开始自学 HTML/CSS,所以如果这是因为我忽略了一些基本知识,请教我一些。
详情
<div>
容器中有一个浮动元素和一个非浮动块元素。
浮动元素 (p1) 具有固定宽度和 0 边距。它在任一 left/right 方向上浮动。它是起始浮动元素(即第一个浮动到包含框的一侧)。
相邻元素 (p2) 是环绕 p1 的非浮动块。请注意,这里特意为 p2 指定了非零边距值,以表明 p1 和 p2 在下面解释的一种情况下未对齐。
包含元素 <div>
的填充为 0。
通过这个设置,我发现浮动元素 (p1) 至少有两种方式可以相对于 border-top-width
和 overflow
:
- The floating element (p1) aligns with the adjacent non-floating element (p2) (i.e. the top-border of p1 box lines up with the top-border of p2 box).
CSS Rules:
div {border-top-width: 0px;}
and
div {overflow: visible;}
The floating element (p1) instead aligns with the top border of the containing box or parent element.
CSS Rules:
div {border-top-width: non-0px;}
or
div {overflow: auto/hidden/scroll/}
请注意,在情况 2 中,任一规则本身都足以启用对齐。
代码
代码,过于简化,看起来像这样:
HTML
<div>
<img src="example.jpg">
<p>Random text</p>
</div>
CSS
img {
float: left;
}
/* floating element aligns with adjacent element */
div {
border: none;
overflow: visible;
}
或
/* floating element aligns with top border of container */
div {
border-top-width: 1px;
overflow: auto;
}
我在 jsfiddle 上举了一个例子:https://jsfiddle.net/tLumj9x7/
或者您可以使用以下代码片段进行检查:
/* <body>, <div> margin set to 0 to avoid interference */
body {
margin: 0px;
}
div {
margin: 0px;
}
/* border drawn above the paragraphs to denote top border of 2nd <div> */
.div1 {
border-bottom: 1px solid;
}
p {
border: 1px solid;
}
/* floating paragraph: margin set to 0 to highlight unusual alignment */
.p1 {
float: left;
margin: 0px;
width: 400px;
}
/* note that a <p> element has a default margin of 1em, so this declaration is just for demonstration */
.p2 {
margin: 16px;
}
input#border:checked~div.div2 {
border-top: 0.02px solid transparent;
}
input#overflow:checked~div.div2 {
overflow: auto;
}
<form>
<input type="checkbox" name="border" id="border" />container border-top-width: non-0<br />
<input type="checkbox" name="overflow" id="overflow" />container overflow: auto / hidden/ scroll<br />
<div class="div1">
</div>
<div class="div2">
<p class="p1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
<p class="p2">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</form>
问题
起始浮动元素相对于其包含元素(在我们的例子中是
<div>
块)的位置究竟是如何确定的?border-top-width
属性和凝视浮动元素的"anchoring"有什么关系?同上
overflow
属性。在属性方面,overflow
如何影响容器框"structurally"?在上面的两个场景中,如果有的话,显示 "default" 定位起始浮动元素?
关于不同但相关的说明。如果我在向左浮动的 p1 浮动元素周围放置边距,它的左边距会与相邻的 p2 非浮动元素的左边距重叠。这是标准行为吗?我读到浮动元素的边距不会折叠,所以我不确定我是否理解正确。
这是我在 Whosebug 上的第一个 post,感谢您阅读我的问题!我是 Web 开发的新手,期待阅读您的回答。
浮动框将垂直放置,与框未浮动时的位置水平。在这种情况下,它是其容器中的第一个元素,其上边缘与其容器内容框的顶部重合。 (您看到的效果差异是 div 容器的内容框上下移动。)
在最初的情况下,p1 是浮动的,因此不在流中,所以没有什么可以阻止 p2 的垂直边距与其祖先一起折叠。非 0 宽度边框顶部的存在意味着 p2 的上边距不再与 div 元素的上边距相邻(即它们被边框分开),因此边距不能折叠在一起.
overflow:auto
的副作用是它会导致 div 建立块格式化上下文。块格式化上下文的后代边距不会与建立块格式化上下文的元素的边距重叠。使 div 建立块格式化上下文的更直接但更新的方法是为其设置display:flow-root
.默认情况下,流入块框的相邻垂直边距会折叠。因此 p 元素 (p2) 的默认上边距与 div 和 body 元素的上边距折叠,增加 div 元素内容框顶部上方的边距,从而推动浮动元素较低。
Collapsing Margins 影响垂直边距。对于水平边距,您看到的不是边距塌陷,而是不同的效果。 p1 和 p2 相互重叠。 p2 并不完全包围 p1,它的内容确实如此。发生的情况是 p2 由一堆线框组成。 p1 旁边的每个行框的左边缘与 p1 的右边距重合。 p2 的左边距仍然触及包含 div 的内容框的左边缘,就像 p1 根本不存在一样,所以它不会影响那些行框左边缘的位置,除非 p2 的左边margin、border 和 padding 大于 p1 的 margin box 的宽度。
尝试根据 Alochi 的回答回答我自己的问题,看看我的想法是否正确。谢谢你,阿洛奇!
本质上,如果一个浮动框是它的第一个元素 容器,它的垂直对齐行为就像它的 non-floating 对方将在其容器中(减去保证金崩溃)。也就是说, 浮动框(取决于其
margin
、border
)重合 包含块的内容边缘(即 parent 元素)。在
border-top-width
是否为0值的情况下, 浮动框的定位实际上是一致的,因为它 外部上边缘与其包含的内容边缘重合 堵塞。不同之处在于: 1) 周围没有边框 包含块(其border-top-width
为 0), non-floating 与浮动块相邻的块(在我们的例子中是 p2), 与包含块的边距一起折叠,无论 容器margin
是否为0,留下视觉 margin-less 浮动块与其对应的印象 相邻 non-floating 元素; 2)border-top-width
非 0 在包含块周围,non-floating 的上边距边缘 块与包含块的顶部内容边缘重合, 因为容器周围的边界将其分开 与其后代的边缘,留下视觉印象 margin-less 浮动块与容器对齐, 而不是相邻的 non-floating 块。
感谢您的澄清。这也是我最初试图使对齐行为合理化的方式。从那以后,我深入挖掘并找到了控制浮动定位的规则 here。规则 #8 规定 "a floating box must be placed as high as possible",而规则 #4 规定 "a floating box's outer top may not be higher than the top of its containing block."
- 在
overflow
的情况下,如果它的值为non-visible,那么 为元素的布局创建块格式化上下文 children(根据这些 formatting context rules),边距 位于顶部的任何 children 元素的 容器的那个(根据 margin collapsing rules),如 如果前者包含在容器的内容边缘内。
感谢您提供有关块格式化上下文的提示!我不知道这个概念。我想知道在块格式化发生之前格式化上下文是什么,如果有的话?
由于大多数块元素默认没有边框(比如
<html>
、<body>
、<div>
,因为他们的overflow
是可见的 默认情况下,"default" 场景是一个浮动框 似乎与相邻的 non-floating 块对齐,因为 后者的任何边距都会随着 包含块。浮动元素未与任何其他元素一起流动non-floating 容器内的元素,以及任何相邻的 non-floating 块定位自己,就好像浮动元素不存在一样。 只有 non-floating 块的内容,其位置是 静态或相对,环绕浮动块。