IE7渲染错误:在浮动列表之前标题

时间:2010-04-30 22:47:00

标签: html css internet-explorer-7 css-float

有人可以向我解释这个IE7错误吗?它出现在标准 Quirks模式渲染中,它不会出现在Firefox,Chrome或IE8中(尽管通过IE8开发工具切换渲染引擎会激发它)。这是重现行为的HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>Test</title>
    <style type="text/css">
        /* h1      { margin: 0px; } */
        ul      { padding: 0; margin: 0; list-style-type: none; }
        ul li   { float: left; width: 140px; padding: 3px; }
        div     { clear: left; padding: 3px; } 
        div, li { background-color: OrangeRed; }
        /* ul      { border: 1px solid blue; } */
    </style>
</head>
<body>
    <h1>Heading 1</h1>
    <ul>
      <li>bla 1</li><li>bla 2</li><li>bla 3</li>
    </ul>
    <div>yada</div>
</body>
</html>
  • 这会使<ul>浮动<div>高于<div>(应该是标签式用户界面)。
  • <ul><h1>之间存在无法解释的差距。
  • 现在执行以下操作之一:
    1. 取消注释<div>的CSS规则。差距消失,列表紧挨<h1>,但也非常接近<ul>
    2. 或者,取消注释<ul>的CSS规则。现在,在<h1>上方呈现了一个狭窄的蓝色边框,但间隙消失了。

我的问题:

  1. <ul>边距(我认为任何具有已定义边距的块级元素)如何影响列表下方的空间?
  2. 我是否可以防止这种情况发生,而不必将标题边距设置为0或弄乱border-width: 0;边框(设置<ul>不起作用BTW)?
  3. 我认为它与{{1}}本身没有高度有关,因为它只有漂浮的孩子。也许比我更了解IE7特性的人可以解释渲染引擎在这里做的事情。谢谢!

3 个答案:

答案 0 :(得分:1)

这是Incorrect Float Shrink-Wrap Bug。链接的文章解释了这个问题。它也影响IE6 btw。

  

作为GérardTalbot认为该错误的人Sjaak Priester,理由是IE首先将浮动元素渲染到与前一个浮点相同的行上,然后看清楚并清除它,但无法重绘文本。 / p>

其中一个常见的解决方案是clearfix黑客在这里被其他人回答,或者在具有浮动的块之后放置一个空的清除元素,如<br style="clear:left;">。将它放在uldiv之间。这样,IE会在到达div之前强制清除。

答案 1 :(得分:1)

我想出了一个似乎是一个很好的妥协的解决方案。它基于以下事实:在<ul>上设置边界可以解决问题,而前一个兄弟块级元素的margin-bottom显然会导致它。

因此在border-top: 1px solid transparent;上设置<ul>只会将其移位一个像素,这对我来说没问题。正如BalusC在评论中正确指出的那样,设置margin-top: -1px;将抵消流离失所。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>Test</title>
    <style type="text/css">
        ul      { padding: 0; margin: 0; border-top: 1px solid transparent; list-style-type: none; }
        ul li   { float: left; width: 140px; background-color: red; }
        div     { clear: left; background-color: red; } 
    </style>
</head>
<body>
    <h1>Heading 1</h1>
    <ul>
      <li>bla 1</li><li>bla 2</li><li>bla 3</li>
    </ul>
    <div>yada</div>
</body>
</html>

我承认这也是一种讽刺;它需要记住伪造的边界是什么,这比通常的CSS技巧(但有点)要好得多。


答案的上一个版本:我现在已经修复了这个问题(似乎它可以在浏览器中运行,并且不需要CSS hackery)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>Test</title>
    <style type="text/css">
        div.t ul    { padding: 0; margin: 0; list-style-type: none; }
        div.t ul li { float: left; width: 140px; background-color: red; }
        div.c       { background-color: red;  } 
    </style>
</head>
<body>
    <h1>Heading 1</h1>
    <div class="t">
      <ul>
        <li>bla 1</li><li>bla 2</li><li>bla 3</li>
      </ul>
      <br style="clear: left;">
    </div>
    <div class="c">yada</div>
</body>
</html>

我不太喜欢这个解决方案,因为它需要额外的元素。但我更不喜欢脏CSS技巧。

答案 2 :(得分:0)

这是一个非常奇怪的问题,IE似乎充满了这些乐趣。我还没有确切地知道为什么它决定这样渲染,但通过适当清除浮动,你通常可以避免所有这些麻烦。以下代码似乎给出了一些一致性(换句话说,无论有没有H1 css规则,它都是相同的。)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>Test</title>
     <style type="text/css">
        h1      { margin: 0px; }
        ul      { padding: 0; margin: 0; list-style-type: none;}
        ul li   { float: left; width: 140px; padding: 3px; }
        div, li { background-color: OrangeRed; }
        ul      { border: 1px solid blue; }
        .clearfix:after {
        content: ".";
        display: block;
        height: 0;
        clear: both;
        visibility: hidden;
        }

        .clearfix {display: inline-block;}  /* for IE/Mac */
    </style>
</head>
<body>
    <h1>Heading 1</h1>
    <div class="clearfix">
      <ul class="t">
        <li>bla 1</li><li>bla 2</li><li>bla 3</li>
      </ul>
    </div>
    <div>yada</div>
</body>