当没有内容时,块级元素的基线移位

时间:2013-11-08 15:38:36

标签: html css

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

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

DEMO jsFiddle

UPDATE :这是一个新的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;
}

2 个答案:

答案 0 :(得分:1)

我认为在深入研究W3C规范之后,我已经找到了原因。以下是规范中的三个关键项,可以解释这种行为:

  1. 不包含文字的行框,没有保留的空格,没有非零边距的内嵌元素,填充或边框,也没有其他插播内容(例如图片,内嵌)块和内联表),并且不以保留的换行结束必须被视为零高度线框,以确定其中任何元素的位置,并且必须被视为不存在出于任何其他目的。“
    • 删除文字后,<p>元素不再是 in-flow
  2. “'内联块'的基线是正常流程中最后一个行框的基线,,除非它没有流入的行框或者它的'溢出'属性具有除“可见”以外的计算值,在这种情况下,基线是底部边距。“
    • 由于父div中没有​​ in-flow 元素,因此基线成为底部边距。
  3. 由于div设置为display: inline-block,因此其默认垂直对齐方式为“基线”
  4. 因为其他div具有 in-flow 元素(<p>标记),所以它们的基线设置为文本基线。
  5. 这就是为什么空盒子的底部边距与其他div中<p>标签的基线一致。

答案 1 :(得分:0)

元素的基线正在移动,因为<p>内的文字阻止了基线高度:

  

在内联格式化上下文中,框是水平布局的,一个   在另一个之后,从包含块的顶部开始。   这些之间会考虑水平边距,边框和填充   框。盒子可以以不同的方式垂直对齐:它们   底部或顶部可以对齐,或其中的文本基线   可能是对齐的。

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

  

计算行框中每个内联级别框的高度。对于   替换元素,内联块元素和内联表元素,   这是他们边缘盒子的高度;对于内联盒,这是   他们的行高&#39;。

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

  

CSS假定每种字体都有指定a的字体指标   高于基线的特征高度和低于基线的深度。在这   我们使用A来表示该高度(对于给定的给定字体)   尺寸)和D的深度。我们还定义AD = A + D,距离   从上到下。

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

因此,此块为inline-block,并且基于line-height计算基线,该<p>由不同的字体类型计算。由于此line-height: 0;没有字体/文本,因此无法定位基线。

放置所有{{1}},您会看到没有文字/字体的那个没有像其他人那样做出反应:

<强> jsFiddle

那么为什么另外两个元素会在其中包含文字?
好吧,因为文本中有两行文字。文本的边距更大并且使用更多空间,因此基线被进一步推进