# HasLayout

### Введение <a href="#vvedenie" id="vvedenie"></a>

Множество несоответствий (стандартам) Internet Explorer’а при визуализации вебстраниц может быть устранено путем присвоения конкретным элементам свойства layout. John Gallant и Holly Bergevin называют эти несоответствия «пространственными ошибками», подразумевая, что они часто могут быть исправлены, если задать элементу ширину или высоту. Это ведет к справедливому вопросу: каким образом layout может менять визуализацию одного элемента и совместное отображение нескольких?

### hasLayout: определение <a href="#haslayout-opredelenie" id="haslayout-opredelenie"></a>

Layout является исключительно концепцией IE/Win, которая определяет, как будет ограничено и визуализировано внутреннее содержание элементов, как элементы будут взаимодействовать и влиять друг на друга, реагировать на и передавать события, вызванные пользователем или приложением. Это качество в одностороннем порядке может быть вызвано некоторыми свойствами CSS. Некоторые HTML элементы обладают им по умолчанию. Разработчики Microsoft решили, что элементы должны иметь возможность получать это «свойство» (в терминах объектно-ориентированного подхода), и они назвали его *hasLayout*. Это свойство становится true, если элемент имеет\получает лейаут.

### Терминология <a href="#terminologiya" id="terminologiya"></a>

Мы говорим, что элемент «приобретает layout» или, что элемент «имеет layout», когда для него Microsoft’овское свойство hasLayout становится true. Маркус Милке (Markus Mielke) из команды разработчиков IE в своей статье "HasLayout Overview" условно различает элементы на две категории:

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

**«Элементом с layout»** может быть любой элемент, который имеет layout по умолчанию либо получил его в результате выставления некоторых соответствующих CSS-свойств.

В **«не-layout»** элементах свойство **hasLayout** не выставлено, например, чистый div Без заданных размеров может быть «не-layout родителем».

Единственным способом выставить hasLayout = false является удаление или сброс первоначального CSS-свойства, которое вызвало hasLayout = true.

### С чем приходится иметь дело <a href="#s-chem-prikhoditsya-imet-delo" id="s-chem-prikhoditsya-imet-delo"></a>

Проблема **hasLayout** затрагивает дизайнеров и верстальщиков с любым уровнем опыта. Layout обладает редкими и тяжело предсказуемыми эффектами при визуализации блоков, а также при отображении вложенных в них элементов. Следствием того, что у элемента есть или нет layout, может быть:

* Распространенные ошибки IE при отображении «плавающих» блоков;
* Различное поведение самих блоков при одинаковых базовых свойствах;
* «Схлопывание» полей между родителем и его потомками;
* Различные проблемы с созданием списков;
* Разное позиционирование фоновых картинок;
* Различия между браузерами при использовании скриптов.

Вышеприведенный список короткий и неполный.

### Откуда появляется layout <a href="#otkuda-poyavlyaetsya-layout" id="otkuda-poyavlyaetsya-layout"></a>

В отличие от стандартных CSS-свойств, layout не может быть присвоен напрямую через CSS-правила. Другими словами, не существует никакого «layout-свойства». Определенные элементы автоматически «имеют layout», и он может быть косвенно добавлен различными CSS-правилами.

### Элементы, у которых по умолчанию есть layout <a href="#elementy-u-kotorykh-po-umolchaniyu-est-layout" id="elementy-u-kotorykh-po-umolchaniyu-est-layout"></a>

По-видимому, layout есть по умолчанию у следующих элементов.

> `<html>, <body> <table>, <tr>, <th>, <td> <img> <hr> <input>, <button>, <select>, <textarea>, <fieldset>, <legend> <iframe>, <embed>, <object>, <applet> <marquee>`

### Когда необходим layout и как его назначить <a href="#kogda-neobkhodim-layout-i-kak-ego-naznachit" id="kogda-neobkhodim-layout-i-kak-ego-naznachit"></a>

Самая распространенная ситуация когда необходим layout - для родителя элементов имеющих свойство float отличное от none;

Если у вас в коде есть блок(и) со свойствами `float:left;` или `float:right;` то для их первого общего родителя необходимо прописать свойства возвращающие **hasLayout**. Такие свойства ранее как правило записывались парами: одно для Современных браузеров и одно для IE6(к счастью канул в лету))).

Поэтому приведем современные решения:

1\) **clearfix:**

```
.parent:after{ 
    content:''; 
    display:block; 
    clear:both; 
}
```

Существует и немного измененный его вариант который используется в бутстрап например.

```
.clearfix:before,
.clearfix:after {
    content: " ";
    display: table;
}

.clearfix:after {
    clear: both;
}
```

2\)

```
overflow:hidden;
```

3\)

```
display:table;
В некоторых случаях нужно добавить ( width:px; или width:100%; )
```

4\)

```
float:left; или float:right;
```

5\)

```
position:absolute;
```

6\)

```
display:inline-block;
В некоторых случаях нужно добавить ( width:px; или width:100%; )
```

Так же в зависимости от структуры и уже присутствующих свойств возможно решение бага добавлением нижнего `border.`

**Исключение:** свойства возвращающие **hasLayout** задавать не нужно если у их первого общего родителя уже есть необходимые свойства. Например: `float:left;`
