hasLayout

Автор: Татьяна Шкабко Дата публикации: 23.07.2010

При слове 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 со своего компьютера, ниже есть скриншоты:

cписок блочных ссылок во всех браузерах список блочных ссылок в 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 условно различает элементы на две категории:

  1. Элементы содержащие контент, размеры и отображение которых зависит от их родительских элементов
  2. Элементы отвечающие и за свои размеры и за организацию и визуализацию своего содержимого

Т. е. элементы, не имеющие layout, и элементы, его имеющие соответственно.

Как правило, элемент имеющий layout является прямоугольной областью, т.е. его присвоение строчному элементу приводит к тому, что элемент ведет себя как строчный блок (см. рисунок):

строчный элемент без layout строчный элемент c layout
Строчный элемент не имеющий layout. Строчный элемент имеющий layout.

Как узнать, есть ли у элемента layout?

Ответы на этот вопрос предлагают разные: от подробного исследования всего css файла до использования специальных скриптов. Но мой же взгляд есть гораздо более простой метод. Поскольку о наличии и отсутствии layout мы начинаем задумываться, когда IE ведет себя неадекватно, то самый простой способ, это принудительно присвоить layout элементу и посмотреть, поможет ли это побороть глюк.

Элементы, имеющие layout изначально

Всегда имеют layout следующие элементы:

body, img, input, table, td

Управление 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, экономит время и сохраняет нервы!

Материал: