IE7 ошибка рендеринга: заголовок перед плавающим списком - PullRequest
4 голосов
/ 01 мая 2010

Может кто-нибудь объяснить мне эту ошибку 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>.
  • Теперь выполните одно из следующих действий:
    1. Раскомментируйте правило CSS для <h1>. Пробел исчезает, и список отображается плотно с <div>, но также очень близко к <h1>.
    2. В качестве альтернативы, раскомментируйте правило CSS для <ul>. Теперь узкая синяя рамка отображается над <ul>, но пропасть исчезает.

Мои вопросы:

  1. Как поле <h1> (я полагаю, подойдет любой элемент уровня блока с определенным полем) влияет на пространство под списком?
  2. Можно ли предотвратить это, не устанавливая поля заголовка равными 0 или не вмешиваясь в границы <ul> (настройка border-width: 0; не работает BTW)?

Я полагаю, что он связан с <ul>, не имеющим высоты, потому что он только плавал детей. Возможно, кто-то, кто лучше разбирается в особенностях IE7, чем я, может объяснить, что движок рендеринга делает здесь. Спасибо!

Ответы [ 3 ]

1 голос
/ 01 мая 2010

Это Неправильная ошибка с плавающей запятой . Связанная статья объясняет проблему. Это также влияет на IE6, кстати.

Как говорит Сяак Пристер, человек, которому Жерар Тальбот приписывает ошибку, причина в том, что IE сначала отображает перемещенный элемент в той же строке, что и предыдущий, затем видит его и очищает, но не может перерисовать текст.

Одним из распространенных решений является взлом clearfix, на который ответил кто-то еще здесь, или размещение пустого очищающего элемента после блока с плавающей точкой, как <br style="clear:left;">. Поместите его между ul и div. Таким образом, IE заставит очистить, прежде чем достигнет div.

1 голос
/ 01 мая 2010

Я нашел решение, которое кажется хорошим компромиссом. Это основано на том факте, что установка границы для <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)

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

0 голосов
/ 01 мая 2010

Это действительно странная проблема, IE, кажется, полон этих прелестей. Я не знаю точно, почему он решает сделать так, но с надлежащей очисткой поплавков вы обычно можете избежать всех этих проблем. Следующий код, кажется, дает некоторую согласованность (другими словами, это то же самое с правилом CSS H1 или без него).

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