【问题标题】:Why does inline-block cause this div to have height?为什么 inline-block 会导致这个 div 有高度?
【发布时间】:2013-11-20 20:33:50
【问题描述】:

jsFiddle Demo

我似乎无法弄清楚为什么使用display:inline-block 会导致这个<div> 元素在其包含元素被隐藏时以某种方式获得高度。 display:block 不会发生这种情况。

html:

<div style="display:inline-block;"><input type="hidden" /></div>
<div>Gap above created by inline-block</div>
<div style="display:block;"><input type="hidden" /></div>
<div>No gap above if using block</div>

为什么display:inline-block 会导致此处描述的差距?

【问题讨论】:

  • 这个问题好像类似:A Space between Inline-Block List Items
  • @RocketHazmat - 也许相似,但重复?当然不。如果它们都在同一行,则行为是相同的。
  • 我认为“差距”是因为&lt;div&gt; 内没有数据。看看这个:jsfiddle.net/FE3Gy/17
  • &lt;span&gt;inline,而不是 inline-block :-)
  • 我猜这与“内联级元素是源文档中不形成新内容块的元素;内容按行分布”没有内容仍然意味着它分布一行有关(空行)-w3.org/TR/CSS2/visuren.html

标签: html css


【解决方案1】:

创建display:inline-block 时发生的一件事是line-height 的计算会发生变化:

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

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

计算line box中每个inline-level box的高度。为了 替换元素、行内块元素和行内表元素, 这是他们的边距框的高度;对于内联框,这是 他们的“线高”。

来源: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

所以行高将根据它们的字体类型来定义。但是,当inline-block 为空时,它将具有基本的line-height。然而,它仍然尝试使用字体生成他的line-height

为了快速解决这个问题,您可以使用一个包装器,它定义了没有字体的排他性,所以没有 line-height 导致没有高度:

.wrapper
{
    font-size: 0;
}

您可以在inline-block 中重置此属性:

.wrapper div
{
    font-size: medium;
}

font-size 的默认值为 medium。

jsFiddle

这样您仍然可以使用inline-block 中的内容而不会出现间隙。


更新

本次更新是因为Kevin Wheelers comment

...我很困惑,它仍然没有说空的 inline-block 元素的高度是多少。 ...

我要说明的是,我没有找到任何关于此的官方文档,尽管通过测试我发现了常见的模式。


短版:

只需将其视为inline-block 期望内容并根据已知的line-height 保留最小行空间。


更多见解:

JsFiddle as a more clear example

如您所见,inline-block 的高度是基于 line-height,我们在第一篇文章中已确定。

现在这个line-height 来自哪里?

它是从确定line-height 的第一个元素继承而来的:&lt;body&gt; 元素。

您可以测试我更改的font-sizefont-family&lt;body&gt; 元素的line-height

所以它为它的内容保留了一个line-box。根据W3 specs of inline-formatting,您可以看到它完全可见,这很奇怪:

不包含文本、不保留空白、不包含非零边距、填充或边框的内联元素,以及不包含其他流入内容(例如图像、内联块或内联表格)的行框,并且不以保留的换行符结尾必须被视为零高度行框,以便确定其中任何元素的位置,并且必须被视为不存在用于任何其他目的。

它对inline-block 内的每个其他元素都这样做,但它似乎总是保留最小的行空间。

【讨论】:

  • 我相信这是一个比所选答案更好的答案,因为它不仅准确地显示了问题发生的原因,而且还显示了如何解决问题。我知道最初的问题并没有问如何解决它,但我相信这是他们想要的,并且当他们发现这个问题时,肯定会成为其他人想要知道的。谢谢:)
  • @GazB - 虽然我确实赞成这个答案包含有关内联块的正确信息,但不幸的是它没有解决问题中的问题。问题是 inline 元素,而不是 inline-block。 inline 元素(隐藏的输入)正在生成一个线块。使用font-size:0 将优先考虑子元素,并且基本上使行块从内联元素 0 高度开始,但这是一个 hackish 解决方案,这既不是我想要的,也不是最终使用的。
  • @TravisJ 我之所以关注 inline-block 是因为当你删除隐藏的内容时,它仍然有差距。因为内联块不习惯为空。 jsfiddle.net/FE3Gy/49你当时想出了什么解决方案? ^^
  • @nkmol - 我认为你的回答是一个很好的解决方法,可以快速完成。然而,这个样本只是一个复制品。产生它的场景是我为支持 ajax 搜索框而制作的库的一部分,它包含一个隐藏的输入。目的是将隐藏的输入存储在他们自己的 div 中,但这太过分了,也导致了这种极端情况。结果,隐藏的输入被移动到与可见输入相同的空间中(因为隐藏不会影响那里的布局)。这也减少了所需的标记。
  • 这个解决方案对我不起作用,但感谢您的解释。内联块只会占用更多空间。
【解决方案2】:

好的,正如在 cmets 中已经非常简要地提到的那样:

内联块

这个值会导致一个元素生成一个内联块 容器。内联块的内部被格式化为块框, 并且元素本身被格式化为原子内联框。

内联

该值使元素生成一个或多个内联框。

这个主题最重要的部分是元素本身的格式不仅仅是内容。每个 inline-block 元素都将被视为 原子内联框,因此会占用空间。

来源:http://www.w3.org/TR/CSS2/visuren.html#inline-boxes

【讨论】:

  • 那么有什么好的解决方法吗?这会严重影响过渡,尤其是当我们有高度未知的 div 时。
【解决方案3】:

显然display:inline-block 的默认设置是根据其父级line-height 设置视觉height。该解决方案使用以下属性制作父包装器:

#container {
  line-height:0;
}

演示 http://jsfiddle.net/FE3Gy/33/ 。您可以在此处查看具有不同 font-size 值的示例。

根据W3是:

inline-block 的内部被格式化为块框,元素本身被格式化为原子内联框。

这里关于内联框

行框的宽度由包含块和浮动确定。行框的高度由行高计算部分中给出的规则确定。

所以你可以在这里查看更多关于line-height的信息:

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

【讨论】:

    【解决方案4】:

    无论您有隐藏的输入或空格或其他什么,您都会得到一条实际的线 - 您的浏览器认为它是一些内联内容,因此它会得到一条线。

    http://jsfiddle.net/FE3Gy/7/

    <div style="display:inline-block;"> </div><div>Gap above created by inline-block</div>
    <div style="display:block;"><input type="hidden" /></div>
    <div>No gap above if using block</div>
    

    即使你一无所有,你也会得到一条线。 display: inline-block 将其转换为内联内容。

    http://jsfiddle.net/FE3Gy/15/

    【讨论】:

    【解决方案5】:

    Layne 和 Nate 的答案是正确的,但我想提醒您注意 CSS 2.1 规范第 9.4.2 节中的这一条款。

    根据需要创建行框以在其中保存内联级内容 内联格式上下文。不包含文本的行框,没有 保留空白,没有非零边距的内联元素, 填充或边框,并且没有其他流入内容(例如图像, 内联块或内联表),并且不以保留的结尾 换行必须被视为零高度行框 确定其中任何元素的位置,并且必须是 被视为不存在用于任何其他目的。

    没有流入内容的跨度(inline 元素)(&lt;input type="hidden" /&gt;display:none,因此不能被视为流入内容)符合这些标准,因此它们包含的行框被视为 0 高度或不存在。 inline-block 元素被明确排除在满足这些条件之外,因此 inline-block 元素创建了一个必须是行高的行框。

    请注意,您可以通过向 span 元素添加边框以使其不符合上述条件以另一种方式看到这一点。见http://jsfiddle.net/FE3Gy/36/

    【讨论】:

      【解决方案6】:

      display:inline-block 的行为与 display:block 不同。 当块创建一个盒子元素时,内联块创建一个盒子,但它会添加一些周围的内容,就好像它是一个单一的内联元素一样。周围的内容可能是您问题的根源。我认为除非您有非常具体的理由使用 inline-block,否则您应该使用 display:block。

      【讨论】:

      • 我只是使用 inline-block 来对齐元素
      【解决方案7】:

      正如@nkmol 上面提到的,它确实带有默认字体大小和行高,从而导致父级不必要的高度。 在某些情况下, line-height: 0 确实可以解决问题。但有时,在特殊情况下,例如父级中的空标签

      <div>
      <a href=''></a>
      </div>
      

      上述情况,只设置 font-size: 0 或 line-height: 0 并不能作为 a 标签解决问题。

      vertical-align: middle;
      

      在这种情况下解决问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-24
        • 2016-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-05
        • 2018-02-21
        • 2015-11-16
        相关资源
        最近更新 更多