Модель отображения. Часть 1

Мохов Олег
Разработчик интерфейсов

Всё есть квадраты прямоугольники

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

Что это такое?

Алгоритм, который используется для обработки документа и отображения его визуального представления. Каждый элемент документа трансформируется 0, 1 или более box'ов в соответствие с боксовой моделью CSS.

Визуальная модель форматирования определяет как страница будет отрендерена.

Положение бокса

  • размер бокса: определен ли, ограничен или никак не задан
  • тип бокса: inline, block, и т.п
  • положение относительно других элементов в дереве: соседей или детей
  • размер и положение viewport'а
  • внутренние пропорции (картинки, видео)
  • схема позиционирования: поток, float или абсолютная

Создание боксов

Типы боксов

  • Блочного уровня (это не только display: block)
  • Строчного (inline) уровня

Боксы блочного уровня

  • Элемент рендерится как блок (близкая аналогия – параграф)
  • Элементы блочного уровня выстраиваются сверху внизу
  • Элемент блочного уровня участвует в блочном контексте форматирования
  • Элемент блочного уровня генерирует главный бокс блочного уровня (principal block-level box) и в некоторых случаях дополнительные (например list-item генерирует бокс для буллета)
  • Участвующий в блочном контексте форматирования элемент может создать вокруг себя анонимный блочный бокс

Анонимные боксы

Некий текст

с параграфом внутри

и снова текст.
Некий текст

с параграфом внутри

и снова текст.

Боксы блочного уровня
по-умолчанию

  • p
  • div
  • h1, h2, h3, h4, h5, h6
  • ol, ul
  • pre
  • address
  • blockquote
  • dl
  • fieldset
  • form
  • hr
  • table
  • display: block, list-item, table, flex...

Математика block элементов

margin-left + /* css */
border-left + /* css */
padding-left + /* css */
content-width + /* ≠ width (css) */
padding-right + /* css */
border-right + /* css */
margin-right /* css */
= width содержащего блока

box-sizing

CSS свойство, которое применяется для изменения алгоритма расчета ширины и высоты элемента.

margin + border + padding + width = width содержащего блока при content-box
margin + border + width = width содержащего блока при padding-box
margin + width = width содержащего блока при border-box
margin + border + padding + height ≠ height содержащего блока

Ширина и высота


div {
    width: 200px;
    height: 200px;
}
                

Ширина и высота


div {
    width: 400px;
    height: 200px;
}
                

Ширина и высота


div {
    width: 400px;
    height: 100px;
}
                

Ширина и высота


div {
    width: 400px;
    height: 100px;
}
div div {
}
                
Вместо тепла - зелень стекла
Вместо огня - дым

Ширина и высота


div {
    width: 400px;
    height: 100px;
}
div div {
    margin: 0 20px;
}
                
Из сетки календаря выхвачен день

Ширина и высота


div {
    width: 400px;
    height: 100px;
}
div div {
    margin: 0 20px;
}
                
Красное солнце сгорает дотла
День догорает с ним,
На пылающий город падает тень.

Ширина и высота


div {
    width: 400px;
    height: 100px;
}
div div {
    height: 100px;
    margin: 0 20px;
}
                
Перемен! - требуют наши сердца.
Перемен! - требуют наши глаза

Ширина и высота


div {
    width: 400px;
    height: 100px;
}
div div {
    height: 100px;
    margin: 0 20px;
    width: 800px;
}
                
В нашем смехе и в наших слезах, и в пульсации вен:
«Перемен! Мы ждем перемен!»

Ширина и высота


div {
    height: 100px;
}
div div {
    height: 100px;
    margin: 0 20px;
    max-width: 800px;
}
                
Электрический свет продолжает наш день,
И коробка от спичек пуста,
Но на кухне синим цветком горит газ.

margin/padding


div {
    width: 800px;
}
div div {
    margin: 20px;
    padding: 50px;
}
                
Сигареты в руках, чай на столе - эта схема проста,
И больше нет ничего, все находится в нас.

margin/padding

margin/padding

        top    right   bottom   left
margin: 2px    30px    400px    5000px;
margin: 2px    30px    400px /* 30px */;
margin: 2px    30px /* 2px      30px */;
margin: 2px /* 2px     2px      2px  */;
                

margin/padding

margin: 2px 30px 400px 5000px;
margin-top: 2px;
margin-right: 30px;
margin-bottom: 400px;
margin-left: 5000px;

                

Процентные значения

Процентные значения

  • ширина, заданная в процентах, считается относительно ширины содержащего блока
  • высота, заданная в процентах, считается относительно высоты содержащего блока, но только если она задана явно
  • margin-left/right и padding-left/right, заданная в процентах, считаются относительно ширины содержащего блока
  • высота содержащего блока (если не задана) = сумма места, занимаемого его детьми
  • margin-top/bottom и padding-top/bottom, заданная в процентах, считаются относительно ширины содержащего блока

div div {
    height: 50%;
    width: 50%;
}
                
Перемен требуют наши сердца
Перемен требуют наши глаза

div {
    height: 400px;
}
div div {
    height: 50%;
    width: 50%;
}
                
В нашем смехе и в наших слезах
И в пульсации вен
Перемен, мы ждём перемен

div div {
    margin: 10%;
    padding: 10%;
}
                
Мы не можем похвастаться мудростью глаз
И умелыми жестами рук

border

border


border: <размер> <тип> <цвет>;
border-left: <размер> <тип> <цвет>;
border-width: <размер> <размер> <размер> <размер>;
border-type: <тип> <тип> <тип> <тип>;
border-color: <цвет> <цвет> <цвет> <цвет>;
border-left-width: <размер>;
border-left-type: <тип>;
border-left-color: <цвет>;

border


div {
    border: 20px dotted blue;
}
                
Нам не нужно всё это, чтобы друг друга понять
Сигареты в руках, чай на столе

border


div {
    border: 20px dashed blue;
}
                
Так замыкается круг
И вдруг нам становится страшно что-то менят

border


div {
    border: 20px solid blue;
}
                
Перемен требуют наши сердца
Перемен требуют наши глаза

border


div {
    border-width: 20px;
    border-style: solid;
    border-color: blue red;
}
                
В нашем смехе и в наших слезах
И в пульсации вен

border


div {
    border-width: 20px 40px;
    border-style: solid dashed dotted;
    border-color: blue red;
}
                
Перемен, мы ждём перемен

Немного о математике блочных элементов

  • margin + border + padding + width =
    width содержащего блока
  • margin + width =
    width содержащего блока - border - padding
  • border/padding: либо заданы, либо auto = 0
  • если margin-left не задан, значит он равен 0, если margin-left задан в auto, то он вычисляется
  • width либо задан, либо вычисляется
  • margin-right вычисляется всегда, если заданы width и margin-right

margin + width = width содержащего блока - border - padding

.container { width: 666px; background: red; padding: 10px 0;  }
.inner { background: rgba(0, 0, 255, 0.5) } 
                

margin + width = width содержащего блока - border - padding

.container { width: 666px; background: red; padding: 10px 0;  }
.inner { background: rgba(0, 0, 255, 0.5) } 
                
Теплое место, но улицы ждут отпечатков наших ног. Звездная пыль - на сапогах. Мягкое кресло, клетчатый плед,
Не нажатый вовремя курок.
Солнечный день - в ослепительных снах..

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { margin-left: 500px; }
                
Группа крови

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { margin-left: 500px; margin-right: 66px; }
                
на рукаве

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { width: 300px; }
                
Мой порядковый номер

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { width: 300px; margin-right: 0; }
                
на рукаве

если margin-left не задан, значит он равен 0, если margin-left задан в auto, то он вычисляется

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { width: 300px; margin-left: auto } 
                
Пожелай мне удачи в бою

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { width: 300px; margin: 0 auto } 
                
пожелай мне

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { margin-right: -100px; }
                
Не остаться в этой траве

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { margin-right: -100px; margin-left: -100px; }
                
Не остаться в этой траве

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { width: 50%; margin-left: -100px; }
                
Пожелай мне удачи,

margin + width = width содержащего блока - border - padding

.wrapper { width: 666px; }
.inner { width: 50%; margin-left: auto; margin-right: -100px; }
                
Пожелай мне удачи!

Схлопывание отступов

Схлопывание отступов

.first { margin-bottom: 30px; }
.second { margin-top: 60px; }
                

Блоки

И есть чем платить, но я не хочу
Победы любой ценой

Ожидание

И есть чем платить, но я не хочу
Победы любой ценой

Реальность

И есть чем платить, но я не хочу
Победы любой ценой
.inner { margin-top: 30px; }
                

Блоки

Я никому не хочу ставить ногу на грудь.

Ожидание

Я никому не хочу ставить ногу на грудь.

Реальность

Я никому не хочу ставить ногу на грудь.

Высчитывание результирующего margin'а

Если у двух блочных элементов, принадлежащих одному контексту форматирования, пересекаются margin'ы, то
  1. Берутся максимальный и минимальный среди всех margin'ов
  2. Если максимальный < 0, то максимум — 0. То же самое с минимумом
  3. Результирующий margin = max + min
.first { margin-bottom: 60px; }
.second { margin-top: 100px; }
                
Я хотел бы остаться с тобой,
Просто остаться с тобой,
Но высокая в небе звезда зовет меня в путь.
Я хотел бы остаться с тобой,
Просто остаться с тобой,
Но высокая в небе звезда зовет меня в путь.
.first { margin-bottom: 60px; }
.second { margin-top: -60px; }
                
Группа крови - на рукаве,
Мой порядковый номер - на рукаве,
Группа крови - на рукаве,
Мой порядковый номер - на рукаве,
.first { margin-bottom: 60px; }
.second { margin-top: -80px; }
                
Пожелай мне удачи в бою, пожелай мне
Не остаться в этой траве, не остаться в этой траве
Пожелай мне удачи в бою, пожелай мне
Не остаться в этой траве, не остаться в этой траве

Боксы инлайн уровня

Боксы инлайн уровня

  • Элемент рендерится как строка
  • Элементы строчного уровня выстраиваются слева направо сверху вниз
  • Элемент инлайн уровня участвует в инлайн контексте форматирования
  • Элемент инлайн уровня генерирует бокс(ы) инлайн уровня
  • Участвующий в инлайн контексте форматирования элемент может создать вокруг себя анонимный инлайн бокс
Some inline text followed by a paragraph followed by more inline text.
Some inline text followed by a span followed by more inline text.

Математика инлайн элементов

Математика inline элементов

  • не реагирует на ширину и высоту
  • не реагирует на вертикальные margin'ы
  • padding'и не затрагивают высоту строки
.wrapper { width: 666px; }
                
Мы хотим видеть дальше, чем окна дома напротив, мы хотим жить, мы живучи, как кошки.
Мы хотим видеть дальше, чем окна дома напротив, мы хотим жить, мы живучи, как кошки.

Боксы инлайн уровня по-умолчанию

  • b, big, i, small, tt
  • abbr, acronym, cite, code, dfn, em, kbd, strong, samp, var
  • a, bdo, br, img, map, object, q, script, span, sub, sup
  • button, input, label, select, textarea
  • display: inline, inline-block, inline-table

Математика inline-block элементов

  • реагирует на ширину и высоту
  • реагирует на вертикальные margin'ы
  • padding'и затрагивают высоту строки
  • создаёт внутри себя новый блочный контекст
.wrapper { width: 666px; }
.inner {  }
                
И вот мы пришли заявить о своих правах: "Да!"
Слышишь шелест плащей - это мы... Дальше действовать будем мы!

ДЗ

https://github.com/urfu-2016/markup-task-5

Deadline
7 ноября
29:59:59.999