为什么这个技巧在动态高度 div 中垂直居中文本(以及它为什么会中断)?

Why this trick centers text vertically in dynamic height div (and why it breaks)?

我发现这个 Whosebug answer 非常有趣。它可以在任何高度的 div 中垂直居中放置任何长度的文本。基本上它在包含文本的节点前面直接使用一个空的 <span> 标记,并且

HTML:

<div>
    <span></span><p>This is really really long text but it will be centered vertically.</p>
</div>​

CSS:

div { 
    background: yellow; 
    color: red;
    width: 200px;
    text-align: center; /* horizontally center */
    height: 300px; /* any height */
    padding: 0 20px
}

div span:first-child {
    height: 100%;
    vertical-align: middle;
    display: inline-block; 
}

div p {
    margin: 0;        
    vertical-align: middle;
    display: inline-block; 
}

同样更有趣的是,如果您将结束跨度标记 (</span>) 和开始段落标记 (<p>) 分开在两行中,或者如果您在两者之间添加一个空格,绝招。

我的问题是 - 这个技巧是如何工作的?跨度如何帮助文本居中?为什么在关闭 </span> 标签和打开 <p> 标签之间的 HTML 中添加 newline/whitespace 时它会中断?

我创建了一个 fiddle 来证明这两点:https://jsfiddle.net/axRxE/385/

My question is - how does this trick work? How is span helping center the text?

既然你给出了跨度 inline-block 属性,那么跨度 继承了 它的 parent 高度(height: 100%) - 在你的例子中是 固定 300px。由于您还为 段落 提供了相同的 属性,因此这两个元素彼此相邻。看一个例子:

#parent {
  height: 300px;
}
span {
  height: 100%;
  display: inline-block;

  /* some width and background-color for demonstration */
  width: 5px;
  background-color: red;
}
p {
  margin: 0;
  display: inline-block;
}
<div id="parent">
  <span></span>
  <p>foobar</p>
</div>

并且您还把 vertical-align: middle(与 inline-block 一起使用)放在它们上面,这使它们对齐(您只需要将 属性 添加到 大一点的):

#parent {
  height: 300px;
}
span {
  height: 100%;
  display: inline-block;

  /* some width and background-color for demonstration */
  width: 5px;
  background-color: red;

  /* added vertical-align */
  vertical-align: middle;
}
p {
  margin: 0;
  display: inline-block;
}
<div id="parent">
  <span></span>
  <p>foobar</p>
</div>


And why does it break when a newline/whitespace is added in HTML between closing </span> tag and opening <p> tag?

很简单 - 当您使用 inline-block 时,总会有 a whitespace issue between them。并且由于您没有向 段落 添加一些宽度,它占用了它可以占用的所有 width,并且由于空白的额外宽度,段落 低于 span.

在你的例子中,你的 parent 有 120px widthspan 使用 0px,所以 paragraph 占用 parent 的所有宽度,即 120px。现在,有了额外的空白(大约 4px),因为她 paragraph 使用了所有宽度,空白不适合所以段落 "breaks" - 它低于跨度。


同时检查: