Перейти к содержанию

Блочная модель

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

CSS подкаст

001: Блочная модель

Допустим, у вас есть такой фрагмент HTML:

1
<p>I am a paragraph of text that has a few words in it.</p>

Затем вы пишете для него этот CSS:

1
2
3
4
5
6
p {
    width: 100px;
    height: 50px;
    padding: 20px;
    border: 1px solid;
}

Содержимое вырвется за пределы элемента, и его ширина составит 142px, а не 100px. Почему так? Блочная модель — это основа CSS, и понимание того, как она работает, как на нее влияют другие аспекты CSS и, что очень важно, как ею можно управлять, поможет вам писать более предсказуемый CSS.

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

Содержание и размер

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

Вы можете управлять этим, используя внешний размер, или позволить браузеру принимать решения за вас, основываясь на размере содержимого, используя внутренний размер.

Давайте быстро рассмотрим разницу, используя демонстрационный пример.

Обратите внимание, что когда блок использует внешние размеры, существует ограничение на количество содержимого, которое можно добавить, прежде чем оно выйдет за границы блока. В этом случае слово "awesome" переполняется.

В демонстрационном примере слова "CSS — это круто" помещены в блок с фиксированными размерами и толстой рамкой. Блок имеет ширину, поэтому его размеры определяются экстернально. Он управляет размерами своего дочернего содержимого. Однако проблема заключается в том, что слово "awesome" слишком велико для этого блока, поэтому оно выходит за пределы граничного блока родительского блока (подробнее об этом будет рассказано далее в уроке). Один из способов предотвратить такое переполнение — позволить блоку иметь собственный размер, либо сняв значение ширины, либо, как в данном случае, установив width в значение min-content. Ключевое слово min-content указывает блоку ширину, равную минимальной ширине его содержимого (слова "awesome"). Это позволяет блоку идеально вписаться в текст "CSS is awesome".

Давайте рассмотрим нечто более сложное, чтобы увидеть влияние различных размеров на реальное содержимое:

Включайте и выключайте функцию внутреннего размера, чтобы увидеть, как можно получить больший контроль над внешним размером и позволить содержимому иметь больший контроль над внутренним размером. Чтобы увидеть эффект от использования внутреннего и внешнего размера, добавьте на карту несколько предложений содержимого. Когда этот элемент использует экстернальный размер, существует ограничение на количество содержимого, которое можно добавить, прежде чем оно выйдет за границы элемента, но это не так, когда включен внутренний размер.

По умолчанию этот элемент имеет заданные значения width и height — оба 400px. Эти размеры задают строгие границы для всего, что находится внутри элемента, которые будут соблюдаться, если только содержимое не слишком велико для блока, в этом случае произойдет видимое переполнение. Вы можете увидеть это в действии, изменив содержимое надписи под изображением цветка на то, которое превышает высоту блока, то есть на несколько строк.

Когда содержимое слишком велико для блока, в котором оно находится, мы называем это переполнением. Вы можете управлять тем, как элемент обрабатывает переполненное содержимое, используя свойство overflow.

При переходе к внутреннему размеру браузер принимает решение за вас, основываясь на размере содержимого блока. При использовании внутренней настройки размера гораздо сложнее добиться переполнения, так как наш блок будет изменять размер вместе с содержимым, а не пытаться изменить размер содержимого. Важно помнить, что это стандартное, гибкое поведение браузера. Хотя внешний размер дает больше контроля, внутренний размер обеспечивает наибольшую гибкость в большинстве случаев.

Области блочной модели

Блоки состоят из отдельных областей модели блока, которые выполняют определенную работу.

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

Четыре основные области модели блока: блок содержимого, блок отступов, блок границы и блок с полями.

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

Блок отступов окружает блок содержимого и представляет собой пространство, создаваемое свойством padding. Поскольку padding находится внутри блока, в образованном им пространстве будет виден фон блока. Если для нашего блока установлены правила переполнения, например overflow: auto или overflow: scroll, то полосы прокрутки также будут занимать это пространство.

Блок границы окружает блок отступов, а его пространство занимает значение border. Граница блока — это границы вашего блока, а граница — это граница того, что вы можете визуально увидеть. Свойство border используется для визуального обрамления элемента.

Последняя область, поля, — это пространство вокруг вашего блока, определяемое правилом margin для вашего блока. Такие свойства, как outline и box-shadow, тоже занимают это пространство, поскольку они рисуются сверху, поэтому не влияют на размер нашего блока. Вы можете задать нашему блоку outline-width в 200px, и все, что находится внутри блока, включая границы, будет иметь точно такой же размер.

Полезная аналогия

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

Три фоторамки

На этой диаграмме представлены три фоторамки, установленные на стене рядом друг с другом. На диаграмме имеются метки, связывающие элементы рамки с моделью блока.

Разберем эту аналогию подробнее:

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

Отладка блочной модели

Browser DevTools предоставляет визуализацию расчетов блочной модели выбранного блока, что позволяет понять, как работает блочная модель и, что немаловажно, как она влияет на сайт, над которым вы работаете.

Попробуйте сделать это в своем браузере:

  1. Open DevTools
  2. Select an element
  3. Показать отладчик блочной модели

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

Чтобы понять, как управлять блочной моделью, необходимо сначала разобраться с тем, что происходит в браузере.

Каждый браузер применяет таблицу стилей агента пользователя к HTML-документам. В каждом браузере CSS используется по-разному, но они предоставляют разумные значения по умолчанию, чтобы сделать содержимое более удобным для чтения. Они определяют, как должны выглядеть и вести себя элементы, если CSS не задан. Именно в стилях агента пользователя задается display по умолчанию. Например, если мы находимся в обычном потоке, то для элемента <div> значение display по умолчанию равно block, для <li> значение display по умолчанию равно list-item, а для <span> значение display по умолчанию равно inline.

Элемент inline имеет блочное поле, но другие элементы не будут его соблюдать. Если использовать inline-block, то эти элементы будут соблюдать границы блока, а сам элемент сохранит все те же свойства, которые он имел как элемент inline. Элемент block по умолчанию будет заполнять все доступное inline-пространство, в то время как элементы inline и inline-block будут иметь размер, равный размеру их содержимого.

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

Наличие content-box в качестве значения box-sizing означает, что когда вы задаете размеры, такие как width и height, они будут применены к content box. Если затем задать padding и border, то эти значения будут добавлены к размерам блока содержимого.

Фактическая ширина этого блока будет равна 260px. Поскольку в CSS используется стандартное box-sizing: content-box, применяемая ширина равна ширине содержимого, к ней добавляются padding и border с обеих сторон. Таким образом, 200px для содержимого + 40px padding + 20px border дают общую видимую ширину 260px.

Однако это можно контролировать, сделав следующую модификацию для использования альтернативной блочной модели border-box:

1
2
3
4
5
6
.my-box {
    box-sizing: border-box;
    width: 200px;
    border: 10px solid;
    padding: 20px;
}

Эта альтернативная блочная модель предписывает CSS применять ширину к границе бокса, а не к содержимому. Это означает, что наши border и padding будут задвинуты внутрь, и в результате, когда вы задаете .my-box ширину 200px, он действительно отображается с шириной 200px.

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

1
2
3
4
5
*,
*::before,
*::after {
    box-sizing: border-box;
}

Это CSS-правило выбирает каждый элемент в документе и все псевдоэлементы ::before и ::after и применяет к ним box-sizing: border-box. Это означает, что теперь каждый элемент будет иметь такую альтернативную блочную модель.

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

Ресурсы

Таблицы стилей пользовательского агента

Источник: Box Model

Комментарии