UfoStation

Layout stage

После того как мы вычислили какие элементы будут на странице и как они будут выглядеть (вычислили стили), нам необходимо понять, а где же они будут представлены на странице и какие размеры будут занимать. Другими словами нам необходимо вычислить геометрию элементов.

За вычисление геометрии элементов на страницы отвечает шаг layout — вычисление макета. Здесь мы преобразуем элементы DOM дерева с учетом CCSOM модели в Layout дерево.

Отображение элементов из DOM tree (или Shadow DOM tree) в Layout tree не происходит 1 к 1, поскольку нет необходимости вычислять геометрию объектов, которые не будут отображаться.

Также причина по которой отображение элементов происходит не 1 к 1 из DOM tree в Layout tree, заключается в том, то некоторые элементы могут быть обернуты в дополнительные (так называемые анонимные) Layout объекты.

Например, выше представлен результат преобразования для следующего html-элемента:

<div style="max-width: 100px">
  <div style="float: left; padding: 1ex">F</div>
  <br />The <b>quick brown</b> fox
  <div style="margin: -60px 0 0 80px">jumps</div>
</div>

Пример выше взят из доклад: Life of a Pixel

За вычисления макета отвечает layout движок в составе Blink, за последние несколько лет он был переработан и переименован в LayoutNG и является частью нового переписанного движка рендеринга RenderingNG. NG здесь означает next generation.

Если начнёте погружаться в документацию Chromium, разбросанную по README-файлам или найдете какой-нибудь docs-файл, например, с описанием работы LayoutNG или реализацией конкретной фичи то, примеры, в которых названия объектов или классов имеют NG относятся к новому движку.

Поэтому выше на изображения приведены layout деревья полученные разными движками внутри Blink.

Надеюсь, что правильно разобрался во всем этом.

То, как будет вычисляться layout, какая layout model будет использоваться, определяется CSS-свойством display.

Существующие layout models: box, table, flexbox, grid.

Чтобы понять какие стили также влияют на будущий layout элемента можно найти в chrome devtools группу стилей, которая также и называется layout.

Как понять какое значение CSS-свойства display у элемента, если мы его явно нигде не указывали? А если без помощи devtools? 🤷‍♂️

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

В исходниках Blink можно найти предопределенные стили для html-страниц, а также некоторые другие, например, для тэгов audio, video, стили для полноэкранного режима, стили для страницы view-source, дополнительные стили под android версию и так далее.

В devtools performance при исследовании вкладки computed styles любого элемента можно обнаружить его css box model, независимо от того какое значение display установлено.

Это связано с тем, что display свойство имеет внутренние значение (inline или block) и внешнее значение (flex, grid или flow). Отличное объяснение этому нашел на канале Mozilla DeveloperInner & Outer Values of the Display Property.

Если кратко, то CSS Box Model это описание элементов на странице в виде блоков, где каждый блок имеет область с контентом, а также необязательные (согласно спецификации) окружающие padding, border и margin области (смотри картинку выше).

Еще важно, что стоит знать — margin области соседних блоков схлопываются.

Про CSS Box Model можно подробнее почитать на MDN, в спецификации или в курсе Learn CSS.

Также на этапе layout в rendering pipeline в Chromium вычисляются и размеры текста с учетом его типографских особенностей, а происходит это с помощью библиотеки HarfBuzz.

Все вычисления layout происходят в одноименной задаче, которая к слову всегда встречается в devtools performance после того как страница загрузилась, а затем выполнились задачи Parse HTML и Recalculate Style.

Нашли ошибку или опечатку? Предложите исправление

← Вернуться в блог