3

我正在通过http://www.codecademy.com/courses/web-beginner-en-jNuXw/0/1?curriculum_id=50579fb998b470000202dc8b解决 CSS 问题(实际上,只是帮助朋友学习 HTML/CSS)然后来了遇到一个奇怪的问题。如果您擦除 a 中任何<p>标签中的内容<div>,则 div 会向上移动。例如,删除单词“妈妈”而不删除<p>. 据我所知,这是因为元素设置为vertical-align: baseline并且由于某种原因基线正在更改。我只是无法确切地弄清楚它为什么会发生变化或导致它发生变化的原因。

需要明确的是,我不是在寻求帮助以使 div 对齐。这只是将它们的垂直对齐设置为“顶部”的问题。我只是想了解如何计算文档流。具体问题是:为什么空的div会向上移动?

演示jsFiddle

更新:这是一个新的 jsFiddle - http://jsfiddle.net/tonicboy/2DtTw/3/,它删除了许多规则,将问题归结为一个简化的用例。由此我们可以看出,当一个<p>标签里面有文本时,父级<div>的基线设置在文本的基线上。删除文本时,父项的基线<div>设置为 <div>. 这是为什么?

HTML:

<div class="friend" id="best_friend"><p>Arthur</p></div>
<div class="friend"><p>Batmanuel</p></div>
<div class="friend"><p>Captain Liberty</p></div>
<div class="friend"><p>The City</p></div>
<div class="friend"><p>Justice</p></div>
<div class="family"><p></p></div>
<div class="family"><p>Dad</p></div>
<div class="family"><p>Bro</p></div>
<div class="family"><p>Sis</p></div>
<div class="family"><p>Rex</p></div>
<div class="enemy"><p>Baron Violent</p></div>
<div class="enemy"><p>The Breadmaster</p></div>
<div class="enemy"><p>The Deadly Nose</p></div>
<div class="enemy"><p>Dinosaur Neil</p></div>
<div class="enemy" id="archnemesis"><p>Chairface</p></div>

CSS:

div {
    position: relative;
    display: inline-block;
    height: 100px;
    width: 100px;
    border-radius: 100%;
    border: 2px solid black;
    margin-left: 5px;
    margin-top: 5px;
    text-align: center;
}

div p {
    position: relative;
    margin-top: 40px;
    font-size: 12px;
}

.friend {
    border: 2px dashed green;
}

.family {
    border: 2px dashed blue;
}

.enemy {
    border: 2px dashed red;
}

#best_friend {
    border: 4px solid #00C957;
}

#archnemesis {
    border: 4px solid #cc0000;
}
4

2 回答 2

2

在深入研究 W3C 规范之后,我想我已经大致弄清楚了原因。以下是规范中的三个关键项目,可以解释这种行为:

  1. "不包含文本、不保留空白、不包含非零边距、填充或边框的内联元素,以及不包含其他流入内容(例如图像、内联块或内联表)且不结束的行框为了确定其中任何元素的位置,必须将保留的换行符视为零高度行框,并且出于任何其他目的 必须将其视为不存在。”
    • 当您删除文本时,该<p>元素不再是in-flow
  2. “'inline-block' 的基线是它在正常流中最后一个行框的基线,除非它没有流入行框,或者它的 'overflow' 属性具有除 'visible' 以外的计算值,在这种情况下,基线是底部边缘边缘。”
    • 因为父 div 中没有流入元素,所以基线成为下边距。
  3. 因为 div 设置为display: inline-block,所以它们的默认垂直对齐方式是 'baseline'
  4. 因为其他 div 有流入元素(<p>标签),所以它们的基线设置为文本基线。

这就是为什么空框的下边距与<p>其他 div 中标签的基线对齐的原因。

于 2013-11-08T18:59:43.730 回答
0

元素的基线正在移动,因为里面的文本<p>决定了基线高度:

在行内格式化上下文中,框从包含块的顶部开始水平排列,一个接一个。这些框之间会考虑水平边距、边框和填充。这些框可以以不同的方式垂直对齐:它们的底部或顶部可以对齐,或者它们中文本的基线 可以对齐。

来源:http ://www.w3.org/TR/CSS2/visuren.html#block-formatting

计算行框中每个行内级框的高度。对于替换元素、inline-block 元素和 inline-table 元素,这是它们的边距框的高度;对于内联框,这是它们的“行高”。

来源:http ://www.w3.org/TR/CSS2/visudet.html#line-height

CSS 假设每种字体都有字体度量,指定基线上方的特征高度和基线下方的深度。在本节中,我们使用 A 表示高度(对于给定大小的给定字体)和 D 表示深度。我们还定义了 AD = A + D,即从顶部到底部的距离。

来源:http ://www.w3.org/TR/CSS2/visudet.html#inline-box-height

因此,当这个块为 a 时inline-block,基线是根据line-height不同字体类型计算的。因为这<p>没有字体/文本,所以不会定位基线。

放置所有的line-height: 0;,你会看到没有文本/字体的那个不会像另一个那样做出反应:

jsFiddle

那么为什么另外两个元素会发生变化呢?
那是因为文本存在两行文本。文本的边距更大,占用更多空间,因此基线被推得更远

于 2013-11-08T19:37:49.857 回答