【问题标题】:Mysterious CSS vertical space神秘的 CSS 垂直空间
【发布时间】:2010-02-22 15:42:39
【问题描述】:

来自这个简单的 html。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Hello</title>
  <style type="text/css" media="screen">
    .t1 {
      padding: 0px;
      margin: 0px;
    }
    .popup {
      display: inline-block;
      position: relative;
      width: 0px;
      padding: 0px;
      margin-left: -0.5em;
    }
    .hint {
      position: absolute;
      z-index: 1;
      width: 20em;
      background-color: white;
      border: 1px solid green;
      padding: 0.5em;
      margin-top: 1em;
    }
    .list {
      padding: 0px;
      padding-left: 1em;
      margin: 0px;
    }
  </style>
</head>

<body>

<!-- properly layout -->
<div style="height: 10em;">
  <span class="t1">MyObject o = www.mycompany.project.ObjectFactory.</span>
  <div class="popup">
    <div class="hint">
      <ul class="list">
        <li>NewSimpleObject(int x);</li>
        <li>NewComplexObject(int x, int y);</li>
        <li>NewComplicateObject(int x, int y, intz);</li>
      </ul>
    </div>
    <div>&nbsp;</div>  <!-- no idea why, but ending space is required for proper layout -->
  </div>
</div>

<!-- incorrect layout -->
<div style="height: 10em;">
  <span class="t1">MyObject o = www.mycompany.project.ObjectFactory.</span>  
  <!-- mysterious vertical space appear here -->
  <div class="popup">
    <div class="hint">
      <ul class="list">
        <li>NewSimpleObject(int x);</li>
        <li>NewComplexObject(int x, int y);</li>
        <li>NewComplicateObject(int x, int y, intz);</li>
      </ul>
    </div>
    <!-- <div>&nbsp;</div>  -->
  </div>
</div>

</body>

</html>

结果如下:

alt text http://img23.imageshack.us/img23/6224/resultrendering.png

跨浏览器的结果相似。所以我相信这不是浏览器错误。

第二次渲染中文本行和弹出提示之间的垂直空间来自哪里?而

 
又是如何解决这个问题的呢?

更新:

Richard M 的答案中得出结论。没有内容的框没有维度(Inline 除外)。

 
使“弹出”维度存在。

根据 Richard 的说法,更好的解决方案是使用 inline 而不是 inline-block。自the vertical dimension of inline is the same regardless of its content existence

由于某种我还不知道的原因,ma​​rgin-top: 1em 在切换到“内联”时不再需要

更新 2:

哦不。。这个问题还不能结束。 Richard M 建议的更改(使用 inline 并删除 margin-top)仅适用于 Webkit 浏览器(Chrome、Safari) 在 IE 和 Firefox 上,popup 框向左对齐而不是比文本行。

问题中的第一个示例(内联块和非空内容)可能是目前最可靠的选择。

更新 3:

结论!这个问题的真正原因源于没有内容的non-inline 块没有维度。 Richard M 建议使用inline 来避免这个问题。不幸的是,我发现这个解决方案在浏览器中不一致。我想出了另一个相反方向的选项,通过height: 1px; 使用带有强制尺寸的inline-block 这在任何浏览器中都可以正常工作。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Hello</title>
  <style type="text/css" media="screen">
    .t1 {
      padding: 0;
      margin: 0;
      width: 0em;
    }
    .popup {
      display: inline-block;
      padding: 0;
      margin: 0; 
      position: relative;
      width: 0;
      height: 1px;  <!-- force vertical dimension -->
    }
    .hint {
      position: absolute;
      z-index: 1;
      padding: 0;
      margin: 0;
      margin-top: 1px;  <!-- compensate for the setup dimension -->
      width: auto;
      white-space: nowrap;
      background-color: white;
      border: 1px solid green;
    }
    .list {
      padding: 0;
      padding-left: 1em;
      margin: 0.5em;
    }
  </style>
</head>

<body>

  <!-- properly layout -->
  <div style="height: 10em;">
    <span class="t1">MyObject o = www.mycompany.project.ObjectFactory.</span><!-- 
      whitespace is not welcome
    --><div class="popup">
      <div class="hint">
        <ul class="list">
          <li>NewSimpleObject(int x);</li>
          <li>NewComplexObject(int x, int y);</li>
          <li>NewComplicateObject(int x, int y, int z);</li>
        </ul>
      </div>
    </div><!--
      whitespace is not welcome
    --><span>(1, 2, ...</span>
  </div>

</body>

</html>

【问题讨论】:

    标签: html css xhtml


    【解决方案1】:

    这与以下事实有关:divpopup 类不是 position: absolute 的类,而是它的子类 hint

    从浏览器的角度来看,popup div 在仅包含 hint 时,没有内容,因此没有尺寸。 &lt;div&gt;&amp;nbsp;&lt;/div&gt; 为其提供内容并导致hint 弹出窗口在div 的顶部边缘正确启动- 但为什么会这样,我仍然无法理解,即使我确信有一个完全合乎逻辑的解释:)

    【讨论】:

    • 我认为没有内容或尺寸的弹出窗口会导致问题。您可以通过将
      留在那里或明确设置 .popup 的高度来纠正它(它可以是任何小的值。我尝试了 10px 并且效果很好。)
    • @takteek 是真的。我发现令人着迷的是为什么带有 no 内容的弹出窗口会导致 hint 的起点向下移动 1 行,但带有 内容的弹出窗口不会。这是一个非常棘手的边缘案例。无论如何,可以使用您提到的方法修复它。
    【解决方案2】:

    您的 .hint div 有 1em 的上边距以将其“推”到文本行下方,但是在您的第二个实例中,您的 .popup div 不包含任何内容(因为绝对定位的元素不占用空间) .没有内容的 inline-block div 没有高度或宽度,位于一行文本的基线上。因此,您“推”出底部而不是顶部,因此额外的 1em 垂直空间。我真的不明白你为什么使用 inline-block,考虑到 div 的内容是绝对定位的,inline 也可以正常工作。


    针对您的问题编辑:按照我的建议使用显示内联应该可以,但是您需要将绝对定位的.hint div 的左侧和顶部值设置为零。此外,您需要删除您的 &lt;div&gt;&amp;nbsp;&lt;/div&gt; 元素,否则您最终会在它发生的地方出现换行符(因为它不是内联的)。

    【讨论】:

    • 你的意思是我应该使用
    • 是的,改为显示内联并删除 1em 上边距,您的两个案例的布局将相同。
    • 空的“inline-block”没有高度。但是空的“内联”与前面的高度相同。这是本课的正确要点吗?
    • 是的,据我了解是这样。内联元素的高度等于包含元素的行高,而内联块元素没有固有尺寸。
    • 请注意您的投票减少了。我不知道为什么,但是 Richard M 的回答绝对正确地解释了这个问题的原因。 (虽然,他的最新建议实际上并不奏效:)
    【解决方案3】:

    难道真正的意图是:

    <div style="clear:both;"></div>
    

    而不仅仅是:

    <div>&nbsp;</div>
    

    【讨论】:

    • 哇.. 清楚:两者都使样本工作!不知道为什么。你能解释一下吗?
    • 这很像在其上方的浮动对象之后添加回车,这意味着您正在清除它们下方的工作区。
    • 嗯..来自Pekka的回答,看起来“弹出”中的任何内容都可以。 "clear:both" 在这种情况下不应该有任何效果。
    • @rockjock 我相信我的情况没有“浮动”。
    • 但是 和 .popup 是内联块,所以你真的不必指定浮点数。它们已经在漂浮了。
    【解决方案4】:

    您可以在提示上调整您的margin-top。如果需要更正对齐,您可以将其设置为负值。

    【讨论】:

    • 是的,但这并不能真正解决渲染不同的谜团,是吗?
    【解决方案5】:

    如果删除 margin-top: 1em;第二种布局将起作用。

    编辑:将 ma​​rgin-top: 1em; 替换为 overflow: auto; 并且您不再需要 div。

    【讨论】:

    • 但是第一个会失败。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签