hasLayout
При слове IE6 каждый верстальщик тяжело вздыхает. Количество багов и глюков этого браузера огромными корявыми буквами вписано в историю веба. От самых простых (например проблемы с отступом плавающих блоков) до уж совсем странных и непонятных.
Вот наглядный пример странного поведения IE6. Имеем обычный HTML:
<ul> <li><a href="#">Элемент списка 1</a></li> <li><a href="#">Элемент списка 2</a></li> <li><a href="#">Элемент списка 3</a></li> <li><a href="#">Элемент списка 4</a></li> <li><a href="#">Элемент списка 5</a></li> <li><a href="#">Элемент списка 6</a></li> <li><a href="#">Элемент списка 7</a></li> </ul>
Стили браузера по умолчанию сброшены (это можно сделать, например, с помощью reset.css). Ничего странного, все выглядит одинаково во всех браузерах, в том числе и, как ни странно, в IE6.
Странности начинаются, если по какой-то причине ссылки нужно сделать блочными (например, чтобы для них вставить красивую фоновую картинку), т.е. прописать для них следующий CSS:
li a{ display:block; }
В IE6 между элементами списка появляются непонятные отступы. В живую можно посмотреть здесь (смотреть в IE6, конечно). Для тех счастливчиков, которые с радостными возгласами удалили IE6 со своего компьютера, ниже есть скриншоты:
Список блочных ссылок во всех браузерах кроме IE6. | Список блочных ссылок в IE6. |
Что же делать? Будем боротся с этим детищем Microsoft используя их же разработки!
В Microsoft Internet Explorer для Windows (в Internet Explorer для Mac OS этого нет) есть специальное свойство-флаг, управляя которым можно избавится от многих глюков IE6-7.
Познакомьтесь: hasLayout!
Определение hasLayout
Вот что говорит по этому поводу Microsoft: свойство hasLayout определяет наличие у элемента layout (надо же!).
Термин layout на русский язык можно перевести по-разному: планировка, расположение, слой, схема и т.д. В газетном деле этим термином обозначают расположение материала на странице. При интерпретации кода браузером (а конкретно ИЕ) наличие или отсутствие layout определяет поведение элемента относительно родительских элементов и его влияние на дочерних.
HasLayout это не CSS свойство, а как бы внутренний флаг, говорящий браузеру о наличии layout и в HTML и CSS напрямую никак не отраженный.
Отличия между элементами с layout и без него
Маркус Милке (Markus Mielke) из команды разработчиков IE в своей статье "HasLayout" Overview условно различает элементы на две категории:
- Элементы содержащие контент, размеры и отображение которых зависит от их родительских элементов
- Элементы отвечающие и за свои размеры и за организацию и визуализацию своего содержимого
Т. е. элементы, не имеющие layout, и элементы, его имеющие соответственно.
Как правило, элемент имеющий layout является прямоугольной областью, т.е. его присвоение строчному элементу приводит к тому, что элемент ведет себя как строчный блок (см. рисунок):
Строчный элемент не имеющий layout. | Строчный элемент имеющий layout. |
Как узнать, есть ли у элемента layout?
Ответы на этот вопрос предлагают разные: от подробного исследования всего css файла до использования специальных скриптов. Но мой же взгляд есть гораздо более простой метод. Поскольку о наличии и отсутствии layout мы начинаем задумываться, когда IE ведет себя неадекватно, то самый простой способ, это принудительно присвоить layout элементу и посмотреть, поможет ли это побороть глюк.
Элементы, имеющие layout изначально
Всегда имеют layout следующие элементы:
Управление hasLayout
Хотя нельзя присвоить hasLayout значения true/false непосредственно в коде, можно установить layout прописав элементу некоторые CSS свойства. "Выключить" hasLayout можно, только убрав у элемента все свойства, устанавливающие layout или присвоив им такие значения, которые layout не устанавливают. Перечень свойств и их значений, устанавливающих/не устанавливающих layout приведены в таблице ниже:
CSS свойство | Значение устанавливающие layout | Значение не устанавливающие layout | Заметки |
---|---|---|---|
display | inline-block | все кроме inline-block | |
height | любое значение кроме auto | auto | таким образом нельзя "включить" hasLayout для строчных элементов |
float | left или right | none | |
position | absolute | любое значение кроме absolute | |
width | любое значение кроме auto | auto | таким образом нельзя "включить" hasLayout для строчных элементов |
writing-mode | tb-rl | lr-tb | это свойство не проходит валидацию |
zoom | любое значение кроме normal | normal | это свойство не проходит валидацию |
Нельзя забывать, что для некоторых тегов hasLayout всегда имеет значение true и сбросить его не удастся (см. перечень тегов приведенный выше).
К счастью, основная масса глюков возникает, когда элемент не имеет layout и достаточно его присвоить, чтобы элемент начал вести себя адекватно.
Хотя свойство hasLayout присутствует в IE любой версии, ошибки, связанные с ним, возникают, как правило, в IE6, реже в IE7, и для их исправления достаточно добавить элементу layout только для этих браузеров.
Каждый сам волен выбирать, каким образом присваивать элементу layout. Самый безопасный с точки зрения верстки способ, это присвоить свойство zoom со значением 1. Это свойство Microsoft присваивает элементу масштаб 100% который никак не влияет на элемент (правда строчные элементы начинают вести себя как строчные блоки, но это следствие не zoom:1, а присвоения им layout). Но это свойство не проходит валидацию и этот момент нужно учитывать.
Если искать валидное решение, то для строчных элементов можно применить display:inline-block. Oн и заставит строчные элементы вести себя как строчные блоки, но это уже не имеет значения, поскольку наличие layout уже заставляет элемент вести себя как строчный блок.
Для блочных элементов, у которых не заданы значения width/height, можно для IE6 прописать значение width:100%, или присвоить элементу какую-либо высоту height (1%, 1px, 0px). С высотой нужно быть аккуратным, если у блока задана высота 1px, то уже не стоит присваивать ему overflow:hidden.
Устраняем глюк с блочными ссылками в списках
В примере приведенном в начале статьи достаточно будет только для IE6 прописать для ссылок:
li a{ display:block; zoom:1; }
И IE6 (о чудо!) ведет себя как все остальные браузеры. Демо-пример
Что еще лечиться включением hasLayout
Добавлением layout лечатся глюки связанные с:
- отображением «плавающих» блоков
- отступами между элементами и их потомками
- нестандартным поведением самих блоков
- абсолютным и относительным позиционированием элементов и многим другим
Наиболее полный перечень таких глюков приведен в статье "On having layout" и все желающие могут с ним ознакомиться.
Выводы
Microsoft свойство hasLayout, используемое в браузере IE/Win позволяет определить наличие у элемента layout, который несет ответственность за отображение и размеры элемента и за отображение и размеры дочерних элементов, не имеющих layout. С помощью управления свойством hasLayout можно устранить многие странные глюки IE6-7. Знание этого свойства дает верстальщику мощное оружие в борьбе с IE, экономит время и сохраняет нервы!
Материал:
- MSDN :: hasLayout Property