简体   繁体   English

内部没有内容时,块级元素的基线移动

[英]Baseline shifts for block-level element when no content inside

I'm working through a CSS problem at http://www.codecademy.com/courses/web-beginner-en-jNuXw/0/1?curriculum_id=50579fb998b470000202dc8b (actually, just helping a friend learn HTML/CSS) and came across a curious issue. 我正在通过http://www.codecademy.com/courses/web-beginner-en-jNuXw/0/1?curriculum_id=50579fb998b470000202dc8b解决CSS问题(实际上只是在帮助朋友学习HTML / CSS),遇到一个奇怪的问题。 If you erase the content in any of the <p> tags within a <div> , the div shifts upward. 如果擦除<div>中任何<p>标记中的内容,则div会向上移动。 For example, delete the word 'Mom' without deleting the <p> . 例如,删除单词'Mom'而不删除<p> As best as I can figure out, this is because the element is set to vertical-align: baseline and for some reason the baseline is changing. 尽我所能,这是因为该元素设置为vertical-align: baseline并且由于某种原因基线发生了变化。 I just can't figure out exactly why it's changing or what is causing it to change. 我只是无法弄清楚它为什么会改变或导致它改变的原因。

To be clear, I'm not asking for help to get the div's to align. 需要明确的是,我并不是在寻求帮助以使div保持一致。 That's simply a matter of setting their vertical-align to 'top'. 只需将其垂直对齐设置为“顶部”即可。 I'm just trying to understand how the document flow is calculated. 我只是想了解文档流是如何计算的。 The specific question is: why does the empty div shift upwards? 具体问题是:为什么空div会向上移动?

DEMO : jsFiddle 演示jsFiddle

UPDATE : Here is a new jsFiddle - http://jsfiddle.net/tonicboy/2DtTw/3/ which removes a lot of rules to boil the problem down to a simplified use case. 更新 :这是一个新的jsFiddle- http://jsfiddle.net/tonicboy/2DtTw/3/ ,它删除了很多规则,可以将问题简化为一个简化的用例。 From this, we can see that when a <p> tag has text in it, the baseline of the parent <div> is set at the baseline of the text. 由此可见,当<p>标记中包含文本时,父<div>的基线设置为文本的基线。 When you remove the text, the baseline of the parent <div> is set to the bottom of the <div> . 当您删除文本,父的基线<div>设置为在底部<div> Why is that? 这是为什么?

HTML: 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: 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;
}

I think I've mostly figured out the reason, after digging through W3C specs. 在仔细研究W3C规范之后,我认为我基本上已经找到了原因。 Here are three key items from the spec which may explain this behavior: 这是规范中的三个关键项,可以解释此行为:

  1. " Line boxes that contain no text , no preserved white space, no inline elements with non-zero margins, padding, or borders, and no other in-flow content (such as images, inline blocks or inline tables), and do not end with a preserved newline must be treated as zero-height line boxes for the purposes of determining the positions of any elements inside of them, and must be treated as not existing for any other purpose." 线框,其中不包含任何文本 ,没有保留的空白,没有具有非零边距,填充或边框的内联元素,并且没有其他流入内容(例如图像,内联块或内联表),并且没有结束保留保留换行符的行必须被视为零高度行框,以便确定其中任何元素的位置,并且出于其他任何目的, 必须被视为不存在 。”
    • When you delete the text, the <p> element is no longer in-flow . 删除文本时, <p>元素不再流入
  2. "The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge ." “'inline-block'的基线是正常流中其最后一个线框的基线, 除非它没有流入流线框或如果其'overflow'属性具有除'visible'以外的计算值, 在这种情况下,基线是底部边缘 。”
    • Because there are no in-flow elements within the parent div, the baseline becomes the bottom margin. 由于父div内没有流入元素,因此基线将成为底部边距。
  3. Because the div's are set to display: inline-block , their default vertical alignment is 'baseline' 因为div设置为display: inline-block ,所以它们的默认垂直对齐方式是'baseline'
  4. Because the other div's have in-flow elements (the <p> tags), their baseline is set to the text baseline. 由于其他div具有流入元素( <p>标记),因此它们的基线设置为文本基线。

And that is why the empty box's bottom margin aligns with the baseline of the <p> tags in the other div's. 这就是为什么空白框的底部边距与其他div中<p>标签的基线对齐的原因。

The baseline of the element is shifting because the text inside the <p> determs the baseline height: 元素的基线正在移动,因为<p>文本确定基线高度:

In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. 在内联格式设置上下文中,框从一个包含块的顶部开始以一个接一个的水平排列。 Horizontal margins, borders, and padding are respected between these boxes. 这些框之间应注意水平边距,边框和填充。 The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. 这些框可以以不同的方式垂直对齐:它们的底部或顶部可以对齐, 或者其中的文本基线可以对齐。

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

The height of each inline-level box in the line box is calculated. 计算行框中每个行内框的高度。 For replaced elements, inline-block elements, and inline-table elements, this is the height of their margin box; 对于替换的元素,内联块元素和内联表元素,这是它们的边距框的高度。 for inline boxes, this is their 'line-height'. 对于嵌入式盒,这是它们的“行高”。

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

CSS assumes that every font has font metrics that specify a characteristic height above the baseline and a depth below it. CSS假定每种字体都有字体指标,这些指标指定基线以上的特征高度和基线以下的深度。 In this section we use A to mean that height (for a given font at a given size) and D the depth. 在本节中,我们用A表示高度(对于给定大小的给定字体),D表示深度。 We also define AD = A + D, the distance from the top to the bottom. 我们还定义AD = A + D,即从顶部到底部的距离。

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

So with this block being a inline-block and baseline is calculted based on the line-height which is calcuted by different font types. 因此,将此块作为inline-block并根据由不同字体类型计算出的line-height计算基线。 Because this <p> has no font/text the baseline will not be positioned. 因为此<p>没有字体/文本,所以将不会定位基线。

place all the line-height: 0; 放置所有的line-height: 0; and you will see that the one with no text/font doesn't react like the other does: 并且您会看到一个没有文本/字体的响应不像另一个响应:

jsFiddle 的jsfiddle

So why are the other two elemets shifting that have text in them? 那么,为什么其他两个带有文字的电子元件却在移动呢?
Well it's because the text excist of two lines of text. 好吧,因为该文本存在两行文本。 The margin of the text is bigger and uses more space, thus the baseline is pushed further 文本的边距更大并且使用更多的空间,因此基线被进一步推高

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM