Статьи

Управление блочной моделью CSS

Ниже приводится выдержка из нашей книги CSS Master , написанной Тиффани Браун. Копии продаются в магазинах по всему миру, или вы можете купить их в электронном виде здесь .

Пожалуй, самый важный момент, который нужно понять о CSS, заключается в следующем: все является коробкой . Более конкретно, каждый элемент в документе генерирует поле. Этот блок может быть блоком уровня блока или блоком встроенного уровня. Тип блока определяет, как элемент влияет на макет страницы.

Будет ли элемент создавать блок и какой тип блока он будет создавать, будет зависеть от языка разметки. CSS разрабатывался как способ стилизации HTML-документов, поэтому большая часть модели визуального рендеринга CSS основана на различии HTML между блочными и встроенными элементами. По умолчанию такие элементы, как p и section создают блоки уровня блока, а a , span и em создают встроенные блоки. SVG, с другой стороны, не использует блочную модель, поэтому большинство связанных с макетом свойств CSS не работают с SVG.

Блоки уровня блока создают новые блоки контента, как показано на рисунке 4.1. Блоки уровня блока отображаются вертикально в соответствии с порядком их исходного кода и (за исключением таблиц) расширяются, чтобы заполнить доступную ширину содержащего их элемента. Это называется отображаемым значением нормального потока block , list-item , table или любого из значений table-cell table-* (например, table-cell ).

Рисунок 4.1. Блоки уровня блока с элементами h1, p, ul и table внутри содержащего элемента (серая область)

В отличие от этого, встроенные блоки не образуют новые блоки контента. Вместо этого эти блоки составляют линии внутри блока блока. Они отображаются горизонтально и заполняют ширину вмещающего блока, при необходимости перенося строки, как показано на рисунке 4.2. Боксы на уровне строки имеют display значение inline , inline-block , inline-table или ruby .

Рисунок 4.2. Пример встроенного поля с полем: 1em и отступом: 5px

Но как рассчитываются размеры коробки? Вот где это становится все сложнее. Как видно на рисунке 4.3, размеры блока представляют собой сумму области содержимого блока, плюс его ширины заполнения и ширины границы, как определено в CSS2. Ширина поля создает поле поля для элемента и влияет на другие элементы в документе; однако ширина поля не влияет на размеры самого блока.

Рисунок 4.3. Блочная модель CSS 2.1

Например, элемент p с width: 300px , padding: 20px и border: 10px имеет расчетную ширину 360 пикселей. Это сумма его ширины, левого и правого отступа, а также левого и правого свойств border-width . Чтобы создать элемент шириной 300 пикселей с 240px 20 пикселей и границей 10 пикселей, width должна составлять 240px . Большинство ведущих браузеров рассчитывают ширину именно таким образом. Internet Explorer 5.5, однако, этого не сделал.

Вместо этого IE5.5 использовал свойство width в качестве окончательного арбитра размеров блока с отступом и границей, нарисованной внутри блока, как показано на рисунке 4.4. Оба значения фактически вычитались из width , уменьшая размер области содержимого. Хотя это полная противоположность поведению, определенному в спецификации, многие веб-разработчики решили, что это более разумный подход. [10]

Рисунок 4.4. Блочная модель CSS 2.1 против старой блочной модели «5.5»

Частично в качестве способа разрешения этих конкурирующих моделей рабочая группа CSS ввела box–sizing . Это позволяет нам выбирать реализацию блочной модели, которую мы предпочитаем, и значительно упрощает вычисления при работе с адаптивными проектами.

Выбор модели box-sizing

Свойство box-sizing определено в спецификации уровня 3 модуля базового интерфейса пользователя CSS. У него есть два возможных значения: content-box и content-box border-box .

Изначально значение box-sizing это content-box . С этим значением установка свойств width и height элемента влияет на размер его области содержимого. Это соответствует поведению, определенному спецификацией CSS 2.1, и это поведение по умолчанию в современных браузерах (как показано на рисунке 4.4).

Установка значения box-sizing в border-box создает немного магии. Теперь значения width и height будут применены к краю внешней границы вместо области содержимого. Границы и отступы отрисовываются внутри поля элемента в соответствии со старым поведением Internet Explorer 5.5. Давайте рассмотрим пример, который смешивает ширину в процентах и px единицы для отступов и границ:

 <div class="wrapper"> <article> <h2>This is a headline</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing ... </p> </article> <aside> <h2>This is a secondary headline</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing ... </p> </aside> </div> в <div class="wrapper"> <article> <h2>This is a headline</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing ... </p> </article> <aside> <h2>This is a secondary headline</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing ... </p> </aside> </div> в <div class="wrapper"> <article> <h2>This is a headline</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing ... </p> </article> <aside> <h2>This is a secondary headline</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing ... </p> </aside> </div> 

К нашим элементам article и aside применен следующий CSS, который дает нам макет, показанный на рисунке 4.5, где первый элемент имеет ширину 60%, а второй — 40%:

 article, aside { background: #FFEB3B; border: 10px solid #9C27B0; float: left; padding: 10px; } article { width: 60%; } aside { width: 40%; } 

Рисунок 4.5. Элементы с размерами блока: блок содержимого

По умолчанию, как в aside и в article есть значение box-sizing поля для поля content-box . Значения border-width и padding добавляют 40 пикселей к ширине каждого элемента, что значительно снижает разбивку на 60% / 40%. Теперь давайте добавим box-sizing: border-box к article и aside элементы:

 article, aside { box-sizing: border-box; } 

Вы можете видеть изменение на рисунке 4.6: элементы имеют одинаковую ширину, но box-sizing: border-box означает, что ширина включает в себя рамку и отступ. Поскольку свойство width применяется к краю границы, а не к области содержимого, наши элементы теперь помещаются рядом.

Рисунок 4.6. Элементы с коробкой размеров: бордюр.

Я бы посоветовал вам использовать box-sizing: border-box в ваших проектах. Это облегчает жизнь, так как нет необходимости вычислять значение width для учета значений padding и border , а поля ведут себя более предсказуемо.

Лучший способ применить box-sizing: border-box с правилами сброса. Следующий пример взят из статьи Криса Койера «Уловки CSS»: « Наследование box-sizing ячеек, возможно, немного лучшая практика» :

 html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; } 

Это применяет размер border-box к каждому элементу по умолчанию, не влияя на поведение размеров существующих частей вашего проекта. Если вы знаете, что не будет сторонних или устаревших компонентов, которые полагаются на поведение блоков content-box , вы можете упростить эти правила:

 *, *:before, *:after { box-sizing: border-box; } 

В Таблице 4.1 показана текущая поддержка Bowser для box-size: border-box

Internet Explorer Fire Fox Сафари Хром опера Android
8+ 2+ (версии <29 требуют префикса -moz- ) 3.1+ (версии <5.1 требуют префикса -webkit- ) 4+ (версии <9 требуют префикса -webkit- ) 10.1+ 2.1+ (версии <4 требуют префикса -webkit- )

Управление блочной моделью — это только один из элементов понимания того, как создавать сложные макеты. Давайте углубимся в наслоение элементов в следующем разделе.