0:00
Следующая тема,
о которой хотелось бы поговорить, это то,
как браузер определяет конечное положение и размеры элемента.
Здесь не случайно приведена аналогия с футболом.
В футболе у каждого игрока есть определенное место на поле.
Так же и браузер знает как определить, где должен находиться каждый элемент.
Этот процесс называется компоновка.
Компоновка – это расчет геометрии страницы,
а также расчет размеров замещаемых элементов.
Также очень часто вы можете встретить термин Reflow,
это синоним слова «компоновка».
Как же происходит компоновка?
Она происходит последовательно.
То есть элементы расставляются слева направо, сверху вниз.
xml-подобная структура HTML позволяет нам выполнять компоновку,
не дожидаясь считывания всего HTML документа.
Почему?
Потому что элементы, которые встречаются в HTML позже,
не влияют на геометрию предыдущих.
Но это корректно для всех элементов, кроме таблиц и grid'ов с auto значениями.
В таблице в последней ячейке может находиться такой элемент,
размеры которого будут больше, чем высчитанные размеры ячейки до этого.
В таком случае браузеру придется пересчитать размеры всей таблицы.
Это же справедливо и для grid'ов.
Система координат рассчитывается относительно корневого фрейма.
Ну, в нашем случае корневым фреймом будет элемент HTML.
То есть система координат начинается от левого верхнего окна браузера.
Что делает браузер?
Он определяет собственную ширину элемента.
Для браузера это будет установленная ширина операционной системы.
Далее браузер обрабатывает все дочерние элементы.
То есть он определяет для них ширину, а если этот элемент является конечным,
то есть не содержит никаких вложенных элементов,
то браузер определяет высоту элемента.
И, наконец, на основании суммарной высоты дочерних элементов,
их полей и отступов, вычисляется высота нашего элемента.
Таким образом, рекурсивно обходя дерево,
браузер компонует элементы и определяет их положение.
Различают два типа Reflow в браузере.
Первый Reflow – это глобальный Reflow.
Он, конечно же, возникает тогда, когда нам нужно отобразить страницу при ее загрузке.
Но есть еще несколько событий,
которые влияют на браузер и ведут к глобальному Reflow.
Например изменение окна браузера.
В таком случае браузеру нужно пересчитать геометрию всех элементов на странице.
Или, например, изменение размеров шрифта – тоже,
изменение, которое ведет ко всем пересчетам.
Есть еще похожие глобальные события,
которые могут привести к глобальному Reflow.
Другой тип Reflow, который не влияет на геометрию всей страницы,
называется инкрементный Reflow.
Он возникает, например, когда вы вставляете новый элемент в DOM дерева.
Или вы меняете какой-то атрибут, например меняете значение HTML класса.
Или, например, у вас есть какие-то реакции на изменение состояния элемента,
например по наведению мыши или по фокусу.
В таком случае браузер не переадресовывает всю страницу, а в первую очередь
выполняет определение элементов, которые должны быть перерисованы.
Браузер помечает эти элементы «грязными», то есть нужно пересчитать их размеры,
и определив весь список таких элементов, для них выполняют Reflow.
Давайте рассмотрим на примере.
Вот у нас есть такое DOM дерево и мы, например, меняем CSS свойство background.
Какой Reflow возникнет в данном случае?
Правильный ответ: никакой.
Background не влияет на размеры и положение элемента,
поэтому Reflow здесь не произойдет.
Другой пример: мы меняем CSS свойство transform.
В таком случае у нас поменяется положение элемента нашего, но дальше
Reflow не произойдет, так как transform не влияет на соседей и на родителей.
Ну вот теперь пример более интересный: мы меняем высоту элемента.
Что будет происходить в данном случае?
В первую очередь, у нас изменится положение соседа, брата нашего элемента.
Дальше у нас изменится высота родителя,
так как у нас изменилась высота дочерних элементов.
Изменилась высота родителя – значит изменится положение
брата родителя и так далее вверх до корневого элемента.
Здесь в этой схеме есть один недостаток, которые внимательные слушатели,
наверное, уже заметили: это не всегда так.
То есть я вас немножко обманул.
Почему это может быть не так?
Ну, например, если наш родитель имеет фиксированную высоту.
В таком случае инкрементный Reflow дойдет до родителя и дальше никуда не пойдет.
Другой такой пример, когда инкрементный Reflow может пойти,
а может и не пойти, это изменение ширины инлайнового элемента.
Здесь в данном случае я имею в виду не изменение CSS свойства width,
а изменение контента элемента span,
например мы вставили какой-то дополнительный набор символов внутрь него.
В таком случае у нас элемент span как может увеличить высоту параграфа,
так может и не увеличить.
И, соответственно, мы не можем гарантировать, что инкрементный Reflow в
данном случае пойдет по всем этим элементам и они изменят свое положение.
В данном видео мы рассмотрели механизм компоновки в браузере,
как он выполняется, что такое глобальный Reflow,
что такое инкрементный Reflow и в каких случаях как он может идти.