浮动元素的对齐不一致



摘要

浮动元素表现出与相邻非浮动元素不一致的垂直对齐,这种可变性受容器或父元素的border-top-width值和overflow值的影响。什么给?


背景

我在练习涉及<img>元素的布局时遇到了这种情况。我上个月刚开始自己学习HTML/CSS,所以如果这是由于我掩盖的一些基本原因,请给我讲课。

<div>容器中有一个浮动元素和一个非浮动块元素。

浮动元素 (p1) 具有固定宽度和 0 边距。它以左/右方向浮动。它是起始浮动元件(即第一个浮动到包含框一侧

的元素)。相邻元素 (p2) 是环绕 p1 的非浮动块。请注意,此处特意为 p2 指定了一个非零边距值,以表明 p1 和 p2 在下面解释的场景之一下未对齐。

包含元素<div>的填充为 0。

通过这种设置,我发现浮动元素(p1)至少有两种方式可以相对于border-top-widthoverflow定位自己:

  1. 浮动元素 (p1) 与相邻的非浮动元素 (p2) 对齐(即 p1 框的上边框与 p2 框的上边框对齐)。

    CSS 规则:
    div {border-top-width: 0px;}

    div {overflow: visible;}

  2. 浮动元素 (p1) 改为与 的上边框对齐 包含框或父元素。

    CSS 规则:
    div {border-top-width: non-0px;}

    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>


问题

  1. 起始浮动元素相对于其包含元素(在我们的例子中为<div>块)的位置究竟是如何确定的?

  2. border-top-width属性与凝视浮动元素的"锚定"有什么关系?

  3. overflow属性相同。在属性方面,overflow如何影响容器箱的"结构"?

  4. 在上述两种方案中,哪个显示了起始浮动元素的"默认"位置(如果有的话)?

  5. 在一个不同但相关的笔记上。如果我在左浮动的 p1 浮动元素周围放置边距,则其左边距会随着相邻 p2 非浮动元素的左边距而折叠。这是标准行为吗?我读到浮动元素的边距不会折叠,所以我不确定我是否正确理解了这个概念。

这是我关于stackoverflow的第一篇文章,所以感谢您阅读我的问题!我对Web开发很陌生,我期待着阅读您的答案。

  1. 浮动框将与未浮动时框的位置垂直放置。在此示例中,它是其容器中的第一个元素,其顶部边缘与其容器的内容框顶部重合。(您看到的效果差异是div 容器的内容框上下移动。

  2. 在最初的情况下,p1 是浮动的,因此不流动,因此没有什么可以阻止 p2 的垂直边缘与其祖先一起坍缩。非 0 宽度边框顶部的存在意味着 p2 的上边距不再与div 元素的上边距相邻(即它们被边框隔开),因此边距不能一起折叠。

  3. overflow:auto的副作用是它会导致div 建立块格式上下文。块格式上下文的后代的边距不会随建立块格式上下文的元素的边距而折叠。使div 建立块格式上下文的一种更直接但更新的方法是为其设置display:flow-root

  4. 默认情况入块框的相邻垂直边距折叠。因此,p 元素 (p2) 的默认上边距随div 和正文元素的上边距一起折叠,从而增加div 元素内容框顶部上方的边距,从而将浮动元素推得更低。

  5. 折叠边距
  6. 会影响垂直边距。对于水平边距,您看到的不是边距崩溃,而是不同的效果。P1 和 P2 相互重叠。P2 并不完全环绕 P1,它的内容却是。发生的情况是 p2 由一堆行框组成。与 p1 相邻的每个行框的左边缘与 p1 的右边距边缘重合。P2 的左边距仍然接触包含div 的内容框的左边缘,就像 P1 根本不存在一样,因此它不会影响这些行框的左边缘位置,除非 P2 的左边距、边框和填充大于 P1 的边距框的宽度。

试图根据Alochi的回答回答我自己的问题,看看我的想法是否正确。谢谢你,阿洛奇!

  1. 本质上,如果浮动框是其 容器,其垂直对齐的行为就像其非浮动一样 对应方将在其容器中(减去边距崩溃)。即 的外上边缘 浮动框(取决于其marginborder),重合 与包含块的内容边缘(即父元素)。

  2. border-top-width值是否为 0 的情况下, 浮动框的位置实际上是一致的,因为它 外上边缘与其包含的内容边缘重合 块。区别在于:1)周围没有边框 包含块(其border-top-width为 0),边距 与浮动块相邻的非浮动块(在我们的例子中为 P2), 随包含块的边距折叠,而不考虑 容器margin是否为 0,留下视觉对象 印象是无边距浮动块与其对齐 相邻的非浮动元件;2)border-top-width为非 0 在包含块周围,非浮动的上边距边缘 块与包含块的顶部内容边缘重合, 由于容器周围存在边界将其分开 与其后代的边缘,留下视觉印象 无边距浮动块与容器对齐, 而不是与相邻的非浮动块。

感谢您的澄清。这也是我最初尝试合理化对齐行为的方式。此后,我深入研究并在这里找到了管理浮点定位的规则。规则#8规定"浮动盒子必须放置尽可能高",而规则#4规定"浮动盒子的外顶部不得高于其包含块的顶部"。

  1. overflow的情况下,如果它的值是不可见的,则 为元素的布局创建块格式上下文 子项(根据这些格式上下文规则),边距 位于顶部的任何子元素可能不会折叠 容器的(根据保证金折叠规则),如 如果前者包含在容器的内容边缘中。

感谢您提供有关块格式上下文的提示!我不知道这个概念。我想知道在块格式化发生之前格式化上下文是什么,如果有的话?

  1. 由于大多数块元素默认情况下没有边框(例如<html><body><div>,因为它们的overflow是可见的。 默认情况下,"默认"方案是浮动框 似乎与相邻的非浮动块对齐,因为 无论后者具有什么边际,都会随着 包含块。

  2. 浮动元素
  3. 不与任何其他非浮动元素一起流动 元素在其容器内,因此任何相邻的非浮动 块定位自身,就好像浮动元素不存在一样。 只有非浮动块的内容,其位置为 静态或相对,环绕浮动块。

最新更新