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

Модель визуального форматирования

Модель визуального форматирования (visual formatting model) – это набор инструкций для пользовательских агентов (браузеров), в соответствии с которыми они должны обрабатывать HTML документы для их визуального представления на экранах устройств. Это основополагающая концепция. Знание этой концепции необходимо любому веб-разработчику, т.к. в этом случае он сможет понять как тот или иной фрагмент HTML кода и стилей, применённых к нему, будет отображён в браузере.

В центре этой модели лежат boxes (боксы). Генерация boxes выполняется из HTML элементов. Это означает, что браузеру перед тем, как отобразить страницу, необходимо из HTML элементов сгенерировать boxes. Следующий этап – это расположить boxes по определённому алгоритму на веб-странице.

Модель визуального форматирования в CSS

Этот алгоритм зависит от множества факторов:

  • размеров и от того, как они заданы;
  • типа боксов (block boxes, inline boxes);
  • позиционирования (нормальный поток, position: absolute, position: fixed, position: sticky, float: left или float: right);
  • от других элементов (вложенных и дочерних);
  • от размеров viewport;
  • от собственных размеров изображений и другой информации.

Рассмотрим некоторые из этих факторов.

Схема позиционирования элементов

Схема позиционирования элемента – это один из факторов, от которого будет зависеть расположение boxes на веб-странице.

По умолчанию все HTML элементы, располагаются в нормальном потоке (normal flow).

Нормальный поток — это основной алгоритм, определяющий то, как элементы должны располагаться на странице. В нормальном потоке следования элементов осуществляется в том порядке, в котором они расположены в HTML коде с учётом их вложенности.

Задание другой схемы позиционирования элементам осуществляется с помощью CSS свойств position и float. Узнать всё об этих схемах позиционирования элементов можно в этой статье.

Типы boxes

Тип бокса – это ещё один фактор, от которого будет зависеть как бокс будет располагаться на веб-странице.

Различают два основных типа боксов: блочный (block box) и строчный (inline box).

Тип бокса зависит от CSS свойства display. Из HTML элементов, имеющих display равное block, list-item, или table генерируются один или несколько блочных боксов. Из элементов inline уровня, т.е. у которых вычисленное свойство display имеет значение inline, inline-block или inline-table генерируются боксы inline уровня.

Как происходит генерация boxes?

Процесс генерации boxes – это часть алгоритма модели визуального форматирования. Процесс генерации boxes из HTML элементов разберём на примерах.

Сначала рассмотрим простые примеры, когда из одного HTML элемента генерируется один бокс.

1. В этом примере из одного пустого элемента, имеющего display: block генерируется один блочный ящичек (block box):

<!-- элемент, имеющий по умолчанию display, равный block -->
<p></p>

2. В этом примере из элемента, имеющего display: inline генерируется один inline бокс:

<!-- элемент span имеет по умолчанию display, равный inline -->
<span>Некоторый текст...</span>

Теперь разберём более сложные примеры.

3. Пример, в котором из одного HTML элемента генерируются несколько боксов.

<!-- элемент p, имеет по умолчанию display: block -->  
<p>Текст...</p>

В этом примере будут генерироваться:

  • блочный бокс из элемента p;
  • анонимный строчный бокс, содержащий текст «Текст...» и располагающийся внутри блочного бокса.

Структура боксов:

Пример в котором показано, как из одного элементов генерируется несколько боксов

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

А так как текст не заключён в inline HTML элемент, то алгоритм модели визуального форматирования заключает его в анонимный строчный бокс (anonymous inline box).

4. Пример, в котором элемент с блочным отображением содержит в себе текст и элемент с inline отображением.

<p>Некоторый <strong>очень важный</strong> текст.</p>

В этом примере будут генерироваться блочный бокс из элемента p (по умолчанию display: block) и три строчных бокса в нём.

Это:

  • анонимный строчный бокс, содержащий текст «Некоторый »;
  • строчный бокс из элемента strong (по умолчанию display: inline) с текстом «очень важный»;
  • анонимный строчный ящичек, содержащий текст « текст».

Структура сгенерированных боксов:

Пример в котором показано, как из несколько элементов генерируется несколько боксов

5. Пример, в котором разберём какие boxes будут генерироваться из элемента div (display: block), содержащего внутри себя текст и элемент p (display: block).

<div>Текст 1<p>Текст 2</p>Текст 3</div>

Из этого фрагмента будут генерироваться следующие боксы:

  • блочный бокс из элемента div, т.к. он имеет display: block;
  • • анонимный блочный бокс, расположенный в блочном боксе сгенерированным из div, и содержащий внутри себя анонимный строчный бокс с текстом «Текст 1»;
  • блочный бокс p, находящийся в блочном боксе div и содержащий внутри себя анонимный строчный бокс с текстом «Текст 2»;
  • анонимный блочный бокс, расположенный в блочном боксе div и содержащий анонимный строчный бокс с текстом «Текст 3».

Структура боксов:

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

Почему так? Это связано с тем, что когда строчные боксы находятся на одном уровне с блочными боксами, то каждый из строчных боксов оборачивается в анонимный блочный бокс (anonymous block box).

Блочные боксы (block boxes)

Блочный бокс представляет собой прямоугольник, имеющий ширину (width), высоту (height), внешние отступы (margin), внутренние отступы (padding), границу (border) и область для контента.

Блочный бокс

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

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

В нормальном потоке (normal flow) блочные боксы размещаются вертикально один под другим в соответствии с тем порядком, в котором они записаны в HTML коде с учётом их вложенности. В горизонтальном направлении они прикрепляются к левому краю области контента того блочного бокса, в котором каждый из них расположен.

Как в HTML располагаются блочные боксы находящиеся в нормальном потоке

Строчные боксы (inline box)

Строчные боксы предназначены для представления текстового контента. Они располагаются горизонтально, как строки текста. При этом если inline box не помещается в текущую строку, то он переносится (то, что не поместилось) на следующую строку.

Принцип расположение строчных боксов в HTML

Строчным боксам нельзя задать ширину (width) и высоту (height), т.к. их размеры браузер вычисляют самостоятельно.

Изменить высоту этих inline boxes можно с помощью CSS свойства line-height (высота линии).

Высота линии строчных боксов в CSS

Задание отступов в строчных боксах с помощью margin и padding выполняется очень редко, особенно это касается боксов, содержимое которых размещается на нескольких строках. Это связано с тем, что margin и padding в этом случае не работают. Для остальных строчных боксов, т.е. у которых содержимое располагается на одной строке, можно использовать различные отступы (margin и padding) за исключением margin-top и margin-bottom.

Обратите внимание, что боксы генерируются из HTML элементов, при этом тип бокса зависит от его вычисленного значения CSS свойства display. При этом один и тот же элемент в зависимости его от конечного значения CSS свойства display может генерироваться как inline box, так и block box.

Когда создаёте HTML 5 документ применяйте элементы в соответствии с их назначением (смыслом). При выборе элемента не придавайте важность CSS свойству display, которое он имеет по умолчанию. Данное значение свойства всегда можно переназначить с помощью CSS.

Итоговый пример

В завершении разберём из каких боксов будет состоять следующий HTML документ и как они будут располагаться на странице в браузере.

<!doctype html>
<html lang="ru">
  <head>
    <title>Название страницы</title>
    <meta charset="utf-8">
  </head>
  <!-- div, h1, h2, p по умолчанию имеют display: block, а em и strong - display: inline -->
  <body>
    <h1>Заголовок статьи</h1>
    <div>
      <h2>Заголовок раздела</h2>
      <p>
        Текст 
        <em>Курсивный текст</em>
        <strong>Полужирный текст</strong>
      </p>
      <p>Ещё некоторый текст</p>
    </div>
    <p>Информация <strong>Важная информация</strong></p>
  </body>
</html>
Пример в котором показано, как из элементов генерируются боксы