---
title: Блочная модель
description: |2-

  Все, что отображается в CSS, представляет собой блоки.
  Таким образом, понимание того, как работает блочная модель CSS, является основой CSS.
audio:
  title: 'Подкаст CSS   - 001: Блочная модель'
  src: "https://traffic.libsyn.com/secure/thecsspodcast/TCP_CSS_Podcast__Episode_001_v2.0.mp3?dest-id=1891556"
  thumbnail: image/foR0vJZKULb5AGJExlazy1xYDgI2/ECDb0qa4TB7yUsHwBic8.png
authors:
  - andybell
date: 2021-03-29
---

Скажем, у вас есть такой фрагмент HTML:

```html
<p>Это параграф текста, в котором есть несколько слов.</p>
```

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

```css
p {
  width: 100px;
  height: 50px;
  padding: 20px;
  border: 1px solid;
}
```

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

<figure>{% Codepen { user: 'web-dot-dev', id: 'WNRemxN', height: 300 } %}</figure>

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

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

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

Это можно контролировать, используя указание **внешних размеров** (extrinsic sizing), или же можно позволить браузеру принимать решения за вас на основе размера контента, используя **внутреннее определение размера** (intrinsic sizing).

Давайте вкратце рассмотрим разницу на следующем примере.

<figure>{% Codepen { user: 'web-dot-dev', id: 'abpoMBL' } %} <figcaption>Обратите внимание, что когда для блока используется указание внешних размеров, существует ограничение на количество добавляемого содержимого, прежде чем оно выйдет за пределы блока. Таким образом, слово «awesome» не поместится. </figcaption></figure>

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

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

<figure>{% Codepen { user: 'web-dot-dev', id: 'wvgwOJV', height: 650 } %}</figure>

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

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

{% Aside "key-term" %} Когда содержимое слишком велико для блока, в котором оно находится, мы называем это переполнением. Тем, как элемент обрабатывает переполняющее содержимое, можно управлять, используя свойство `overflow`. {% endAside %}

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

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

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

<figure>{% Img src="image/VbAJIREinuYvovrBzzvEyZOpw5w1/ECuEOJEGnudhXW5JEFih.svg", alt="Диаграмма, показывающая четыре основных области блочной модели — блок контента, блок заполнения, блок границ и блок отступа", width="800", height="547" %}<figcaption> Четыре основных области блочной модели: блок контента (content box), блок заполнения (padding box), блок границ (border box) и блок отступа (margin box).</figcaption></figure>

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

**Блок заполнения** окружает блок контента и является пространством, созданным свойством [`padding`](https://developer.mozilla.org/docs/Web/CSS/padding). Поскольку отступ находится внутри блока, фон блока будет виден в создаваемом им пространстве. Если для нашего блока заданы правила переполнения, такие как `overflow: auto` или `overflow: scroll`, это пространство также займут полосы прокрутки.

<figure>{% Codepen { user: 'web-dot-dev', id: 'BaReoEV' } %}</figure>

**Блок границ** окружает блок заполнения, а его пространство занято значением `border`. Блок границ — это рамка вашего блока, а **края границы** (border edge) — это предел того, что вы видите. Свойство <a href="https://developer.mozilla.org/docs/Web/CSS/border" data-md-type="link">`border`</a> используется для визуального обрамления элемента.

Последняя область, **блок отступа**, — это пространство вокруг вашего блока, определяемое правилом `margin`. Такие свойства, как [`outline`](https://developer.mozilla.org/docs/Web/CSS/outline) и [`box-shadow`](https://developer.mozilla.org/docs/Web/CSS/box-shadow), также занимают это пространство, поскольку они отрисовываются поверх и поэтому не влияют на размер нашего блока. У нашего блока значение `outline-width` может быть `200px`, и все внутри него, включая рамку, будет точно такого же размера.

<figure>{% Codepen { user: 'web-dot-dev', id: 'XWprGea' } %}</figure>

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

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

<figure>{% Img src="image/VbAJIREinuYvovrBzzvEyZOpw5w1/FBaaJXdnuSkvOx1nB0CB.jpg", alt="Три фоторамки", width="800", height="562" %}</figure>

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

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

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

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

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

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

1. [Откройте DevTools](https://developer.chrome.com/docs/devtools/open/)
2. [Выберите элемент](https://developer.chrome.com/docs/devtools/css/reference/#select)
3. Включите отладчик блочной модели

<figure>{% Video src="video/VbAJIREinuYvovrBzzvEyZOpw5w1/sKdHrAfqahgWfDVQEBBT.mp4", controls=true %}</figure>

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

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

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

У `inline`-элемента есть блочный отступ, но другие элементы его игнорируют. Используйте `inline-block`, и эти элементы будут учитывать отступ, при этом элемент будет поддерживать большинство тех же действий, что и `inline`-элемент. `block` по умолчанию заполняет доступное **встроенное пространство** (inline space), тогда как размер элементов `inline` и `inline-block` будет соответствовать их содержимому.

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

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

{% Assessment 'box-model' %}

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

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

```css/1
.my-box {
  box-sizing: border-box;
	width: 200px;
	border: 10px solid;
	padding: 20px;
}
```

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

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

<figure>{% Codepen { user: 'web-dot-dev', id: 'oNBvVpM', height: 650 } %}</figure>

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

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

Поскольку альтернативная блочная модель может быть более предсказуемой, разработчики часто добавляют это правило к сбросам и нормализаторам, таким [как этот](https://piccalil.li/blog/a-modern-css-reset).

## Ресурсы

- [Введение в блочную модель](https://developer.mozilla.org/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model)
- [Что такое браузерные инструменты разработчика?](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools)

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

- [Chromium](https://chromium.googlesource.com/chromium/blink/+/master/Source/core/css/html.css)
- [Firefox](https://searchfox.org/mozilla-central/source/layout/style/res/html.css)
- [Webkit](https://trac.webkit.org/browser/trunk/Source/WebCore/css/html.css)
