Новая, микро версия хака clearfix (Micro Clearfix Hack).

Перевод статьи:  A new micro clearfix hack.
Автор:  Nicolas Gallagher.

Как известно, хак clearfix является популярнейшим способом размещения «плавающих» блоков внутри контейнера без внесения изменений в исходный код разметки страницы. В этой статье представлен доработанный вид этого хака, который предусматривает минимальное использование CSS кода.

Здесь можно увидеть результат работы кода Micro clearfix hack.

Поддержка браузерами: Firefox 3.5+, Chrome, Safari 4+, IE 6+, Opera 9+

Метод micro clearfix полностью поддерживается последними версиями всех популярных браузеров и основан на версии хака от Терри Кобленца — clearfix reloaded, в которой было введено использование двух псевдоэлементов — :before и :after.

Ниже представлен обновленный код. Имя класса тоже укорочено:

/**
* Для современных браузеров:
* 1. Включаемый с помощью свойства content пробел это один
* из способов обхода бага в Opera, связанного с атрибутом
* conteteditable, включенным где-либо в другом месте в
* документе. В противном случае это приведет к появлению пробела сверху и
* снизу элемента с классом clearfix.
* 2. Использование значения table вместо block необходимо
* лишь в том случае, когда применяется псевдоэлемент :before
* с целью сохранения верхних полей дочерних элементов.
*/
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}

.cf:after {
clear: both;
}

/**
* Только для IE 6/7
* Данное правило активирует свойство hasLayout для
* содержания плавающих элементов в этих браузерах.
*/
.cf {
*zoom: 1;
}

Этот код генерирует два псевдоэлемента и устанавливает для каждого из них свойство display со значением table, что позволяет создать анонимный объект таблицы, в данном случае ячейку. Данный подход позволяет создать новый контекст форматирования элемента-контейнера, состоящий из двух компонентов. Первый – псевдоэлемент :before, который предотвращает схлопывание верхних полей (контейнера и дочерних, «плавающих» элементов). И второй – псевдоэлемент :after, собственно и отвечающий за отмену обтекания дочерних элементов. В результате получаем компактный, код хака, не требующий скрытия генерируемого содержимого при помощи свойства visibility: hidden.

Наличие первого :before селектора не обязательно для отмены эффекта обтекания дочерних элементов, он необходим лишь для предотвращения объединения верхних полей, которое имеет место при отображении документа в новых версиях браузеров. У этого метода есть следующие два достоинства:

  • Обеспечивается корректное отображение при совместном использовании с другими конструкциями, определяющими собственный контекст форматирования обтекаемых элементов. К примеру, содержащих свойство overflow: hidden;
  • Обеспечивается полная функциональность в «проблемных» браузерах
    IE 6/7 при наличии строки zoom:1
При некоторых, обстоятельствах ранние версии IE 6/7 не отображают нижние поля дочерних «плавающих» объектов в рамках нового блочного контекста форматирования. Более детально этот вопрос рассматривается в этой статье.

Применение пробела в качестве значения для свойства content: " " предотвращает проблемы в Opera (так называемый Opera bug). Проблема в этом случае заключается в том, что если где-либо в другом месте документа определен атрибут contenteditable, то этот браузер создает пробелы в указанных местах – перед (:before) и после (:after) форматируемого с помощью clearfix элемента. Особая благодарность Сержио Церутти (Sergio Cerrutti) за помощь в решении данной проблемы. Альтернативным способом в данном случае является определение шрифта нулевого размера.

Ранние версии Firefox.

Для браузера Firefox версии 3.5 и ниже, более предпочтительным будет использование метода «clearfix reloaded», предложенного Терри Кобленцом, в котором предусмотрено свойство visibility: hidden, скрывающее содержащиеся в псевдоэлементах символы. Причина в том, что именно эти, ранние версии Firefox для корректной работы хака требуют, чтобы генерируемые псевдоэлементы содержали символ точки — content: ".". В противном случае при определенных обстоятельствах между основным элементом документа body и его первым дочерним элементом возможно появление нежелательного свободного пространства (вот пример — jsfiddle.net/necolas/K538S/).

Альтернативные методы форматирования элемента-контейнера с целью автоматической отмены обтекания его дочерних элементов, предусматривающие использование свойств overflow: hidden или display: inline-block, также позволяют избежать появления подобного дефекта отображения в ранних версиях Firefox.

* Примечание переводчика.

Комментариев: 2 на Новая, микро версия хака clearfix (Micro Clearfix Hack).

  1. Про display table не понятно, почему именно его, почему не block например? Было бы не плохо видеть визуально пример отличия.

    1. Уважаемый massef.
      Автор статьи Nicolas Gallagher дает объяснение, почему было выбрано значение table вместо block. Специалисту такого уровня как Николас конечно виднее, но попробую обосновать этот выбор самостоятельно.
      Дело в том, что образуемый таким образом первый (:before) псевдоэлемент-таблица создает основной, так называемый, «упаковочный» бокс таблицы (table wrapper box), который содержит бокс самой таблицы и боксы ее заголовков. Все вышеупомянутые боксы могут иметь свои собственные поля (margins). Поэтому мы получаем полноценный упаковочный бокс таблицы, благодаря которому предотвращается схлопывание верхних полей элемента контейнера и его дочерних элементов. Если же взять обычный блочный элемент, то поскольку содержимым в данном случае является простой пробел, который будет воспринят браузером как «пробельный контент» и, соответственно, удален из визуальной компоновки, то это приведет к схлопыванию верхнего и нижнего полей самого бокса псевдоэлемента (это описано вот здесь) и как следствие к объединению верхних полей контейнера и его дочерних элементов. То есть суть в том, что табличный бокс при компоновке ведет себя несколько иначе, а именно, не дает объединяться верхним полям, а у обычного блочного бокса при отсутствии содержимого могут объединиться верхнее и нижнее поля, и результирующее поле тоже может быть задействовано в объединении верхних полей элемента-контейнера и его дочерних элементов.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *