- PVSM.RU - https://www.pvsm.ru -
В данной статье рассматривается ситуация, когда элемент, создающий новый блочный контекст форматирования, имеет потомков, имеющих значение свойства float отличное от none. В большинстве статей на данную тему поведение элементов в подобных случаях предлагается принять на веру, поэтому в данной статье акцент делается на обосновании интерпретации браузерами положений спецификации W3C.
Существует некий элемент-контейнер, в котором находится элемент со значением свойства float, установленным как left. Для наглядности у контейнера установлены границы и фон.
jsFiddle [1]
Как видно из примера, контейнер схлопывается — его рассчитанная высота устанавливается в ноль. Этот случай часто встречается в верстке, все к нему привыкли и сложно найти верстальщика, не сталкивавшегося с такой ситуацией.
Дело в том, что если значение свойства height незамещаемого блочного элемента (т.е. контейнера в нашем примере) установлено в auto (а это значение установлено по умолчанию), то его высота определяется исходя из высоты элементов-потомков; при этом в расчет берутся только элементы, участвующие в нормальном потоке. Таким образом, float-элементы и элементы, спозиционированные абсолютно, игнорируются при определении высоты контейнера (ссылка на спецификацию [2]).
Существует несколько вариантов решения этой задачи.
Самый очевидный — поместить блок с соответствующим значением свойства clear после float-элемента. В этом случае блок находится ниже float-элемента по определению свойства clear, а контейнер рассчитывает высоту исходя из положения этого элемента.
Более продвинутым (и, возможно, лучшим из всех) решением является внедрение класса clearfix, популяризованного уже не твиттеровским Bootstrap’ом и позволяющего добиться того же эффекта без нарушения семантики документа.
Но есть еще одно решение. Оно состоит в том, чтобы задать контейнеру overflow:hidden.
jsFiddle [3]
В самом деле, все становится на свои места, контейнер принимает высоту внутреннего элемента, но как это работает?
Прежде чем рассмотреть механизм данного явления, отметим, что не только overflow:hidden решает проблему. Контейнер примет высоту float-элемента, если ему задать абсолютную позицию, установить display: inline-block и в некоторых других случаях. Что же происходит на самом деле?
Дело в том, что во всех этих случаях внутри контейнера создается новый блочный контекст форматирования.
Блочный контекст форматирования — как коробка, в которой лежат вещи — если рядом лежит другая такая же коробка, то вещи из первой не могут повлиять на положение вещей во второй.
Если вернуться к верстке, то блочный контекст форматирования — среда, в которой блоки размещаются в привычном для блоков порядке — сверху вниз, расстояние между ними определяется отступами (margins), отступы соседних блоков схлопываются (ссылка на спецификацию [4]). Элементы из разных блочных контекстов форматирования никак не могут повлиять на положение друг друга на странице.
Если вы впервые сталкиваетесь с понятием блочного контекста форматирования, попробуйте решить следующую практическую задачу: jsFiddle [5].
Итак, с понятием контекста разобрались. Теперь ответим на следующий вопрос — почему при создании блочного контекста форматирования float-элементы учитываются для определения высоты контейнера?
Дело в том, что этот случай отдельно оговорен в спецификации. К блокам, создающим новый блочный контекст форматирования и имеющим height:auto (напомню еще раз, что это значение установлено по умолчанию), применяется следующее правило (ссылка на спецификацию [6]):
Если у элемента есть float-потомки, нижняя грань отступов которых находится ниже нижней линии данного элемента, высота данного элемента увеличивается, чтобы вместить эту грань. Только float-элементы, находящиеся в данном блочном контексте форматирования участвуют в этом — например, float-элементы внутри абсолютно спозиционированных потомков или других float-потомков не учитываются.
Короче говоря, при определении высоты элемента, создающего новый блочный контекст форматирования в расчет берется высота непосредственно дочерних float-элементов (ну и конечно же, как обычно, элементов, участвующих в нормальном потоке).
В этой главе перечислены случаи, в которых создается новый контекст форматирования. В контексте проблематики данной статьи этот перечень — список случаев, при которых блок будет подстраиваться по высоте под дочерние float-элементы. Итак, блочный контекст форматирования создается:
В статье рассмотрен вопрос подстраивания высоты элемента, создающего новый блочный контекст форматирования под размеры дочерних float-элементов. Этот вопрос — лишь часть механизма работы блочного контекста форматирования, но надеюсь, что данная статья помогла вам разобраться в новых аспектах CSS-спецификации.
Спасибо за внимание.
Автор: everyonesdesign
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/web-razrabotka/30545
Ссылки в тексте:
[1] jsFiddle: http://jsfiddle.net/C7Kzm/1/
[2] ссылка на спецификацию: http://www.w3.org/TR/CSS2/visudet.html#normal-block
[3] jsFiddle: http://jsfiddle.net/C7Kzm/2/
[4] ссылка на спецификацию: http://www.w3.org/TR/CSS2/visuren.html#block-formatting
[5] jsFiddle: http://jsfiddle.net/sz95k/2/
[6] ссылка на спецификацию: http://www.w3.org/TR/CSS21/visudet.html#root-height
[7] ссылка на спецификацию: http://www.w3.org/TR/CSS2/visuren.html#fixed-positioning
[8] Источник: http://habrahabr.ru/post/174443/
Нажмите здесь для печати.