神秘的CSS垂直空间

时间:2010-02-22 15:42:39

标签: html css xhtml

从这个简单的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

浏览器的结果相似。所以我认为这不是一个浏览器错误。

第二次渲染中文本行和弹出提示之间的垂直空间来自哪里? &lt; div&gt;&amp; nbsp;&lt; / div&gt; 如何解决此问题?

更新:

来自 Richard M 的答案。没有内容的框没有维度(Inline除外)。 &lt; div&gt;&amp; nbsp;&lt; / div&gt; 制作“popup”尺寸。

根据理查德的说法,更好的解决方案是使用内联而不是内联块。自the vertical dimension of inline is the same regardless of its content existence

以来

由于某些原因我还不知道,切换到“内联”时不再需要 margin-top:1em

更新2:

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

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

更新3:

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

<!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>

5 个答案:

答案 0 :(得分:4)

这与divpopup类的position: absolute不是hint的{​​{1}},而是其子popup的事实有关。

从浏览器的角度来看,hint div(仅包含<div>&nbsp;</div>时)无内容,因此没有维度。 hint为其提供内容,并使div弹出窗口在{{1}}的上边缘正确启动 - 但为什么会这样,仍然逃避我,即使我确定有一个完美的逻辑解释:)

答案 1 :(得分:3)

真正的意图是:

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

而不只是:

<div>&nbsp;</div>

答案 2 :(得分:3)

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


回答您的问题编辑:使用我建议的内联显示应该有效,但您需要将绝对定位的.hint div的左侧和顶部值设置为零。此外,您需要删除<div>&nbsp;</div>元素,否则最终会出现换行符(因为它不是内联的)。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

编辑:将 margin-top:1em; 替换为 overflow:auto; ,您不再需要div了。