Модель отображения

Часть 1

Екатерина Симонова

Все есть прямоугольники

Боксовая модель CSS

 

 

 

 

 

 

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

Это алгоритм, который обрабатывает документ и отображает его на экране устройства.

Модель визуального форматирования задаёт трансформацию каждого элемента в документе и создаёт ноль, один или несколько боксов, согласно боксовой модели CSS

MDN Web Docs

На положение блочных боксов на странице влияет:

  • размер бокса: точно задан он или вычисляется
  • тип элемента: строчный или блочный
  • схема позиционирования: нормальный поток, позиционированные или плавающие элементы
  • отношения между элементами DOM: дочерними и соседними
  • размеры и расположение окна просмотра (viewport)
  • внутренние размеры содержащихся изображений

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

Генератор боксов - это часть модели визуального форматирования, которая создает боксы из элементов документа

Элемент
                    
It's who we are
Doesn't matter if we've gone too far
Doesn't matter if it's all okay
Бокс
It's who we are
Doesn't matter if we've gone too far
Doesn't matter if it's all okay

Боксовая модель

Типы боксов

  • блочного уровня
  • строчного уровня (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

CSS-свойство:

display: block, list-item, table, flex...

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

  • Отображаются как блоки (близкая аналогия - параграф)

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

  • Выстраиваются сверху вниз

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

  • Участвуют в блочном контексте форматирования
MDN Web Docs

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

  • могут создавать вокруг себя анонимные блочные боксы

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

            
Какой-то текст

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

и текстом в конце.
Какой-то текст

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

и текстом в конце.

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

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

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: 20%;
    height: 10%;
}
                    
                
                    
div {
    width: 5em;
    height: 5em;
}
                    
                

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

                    
I'm waking up
I feel it in my bones
div { width: 400px; height: 100px; }
I'm waking up
I feel it in my bones

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

                    
Enough to make my system blow
Welcome to the new age, to the new age
div { width: 400px; height: 100px; } div div { margin: 0 20px; }
Enough to make my system blow
Welcome to the new age, to the new age

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

                    
Enough to make my system blow
Welcome to the new age, to the new age
Welcome to the new age, to the new age
div { width: 400px; height: 100px; } div div { margin: 0 20px; }
Enough to make my system blow
Welcome to the new age, to the new age
Welcome to the new age, to the new age

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

                    
Пишу тебе из пасмурных краёв
Где дождь наполнил город до краёв
Водой, в которой всё отражено
div { width: 400px; height: 100px; } div div { height: 100px; margin: 0 20px; }
Пишу тебе из пасмурных краёв
Где дождь наполнил город до краёв
Водой, в которой всё отражено

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

                    
I’m bulletproof, nothing to lose
Fire away, fire away
Ricochet you take your aim
div { width: 400px; height: 100px; } div div { width: 600px; height: 100px; margin: 0 20px; }
I’m bulletproof, nothing to lose
Fire away, fire away
Ricochet you take your aim

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

                    
Время остановилось между сказкой и былью,
Я стою на холодных плитах, покрытых звёздной пылью.
div { height: 100px; } div div { max-width: 800px; height: 100px; margin: 0 20px; }
Время остановилось между сказкой и былью,
Я стою на холодных плитах, покрытых звёздной пылью.

min/max-width и min/max-height

margin/padding

                    
What if I wanted to break
Laugh it all off in your face
What would you do?
div { width: 400px; } div div { margin: 20px; padding: 50px; }
What if I wanted to break
Laugh it all off in your face
What would you do?

margin/padding

margin: 20px 10px 5px 34px
margin-top: 20px;
margin-right: 10px;
margin-bottom: 5px;
margin-left: 34px;

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  */;
                

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

  • ширина, заданная в процентах, считается относительно ширины содержащего блока

div div {
    width: 50%;
}
                
Построив свой дом на пороге луны,
Живу без часов, без газет и без книг.
  • высота, заданная в процентах, считается относительно высоты содержащего блока, но только если она задана явно

div {
    height: 400px;
}
div div {
    height: 50%;
    width: 50%;
}
                
Никого не будет в доме. Кроме сумерек.
Один зимний день в сквозном проеме
  • высота, заданная в процентах, считается относительно высоты содержащего блока, но только если она задана явно

div {
}
div div {
    height: 50%;
    width: 50%;
}
                
Никого не будет в доме. Кроме сумерек.
Один зимний день в сквозном проеме
Незадернутых гардин
  • margin-left/right и padding-left/right, заданные в процентах, считаются относительно ширины содержащего блока
  • margin-top/bottom и padding-top/bottom, заданные в процентах, считаются относительно ширины содержащего блока

div div {
    margin: 10%;
    padding: 10%;
}
                
И где-то хлопнет дверь,
И дрогнут провода
Привет! Мы будем счастливы теперь
И навсегда.

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;
}
                
Some text

border


div {
    border: 20px dashed blue;
}
                
Some text

border


div {
    border: 20px solid blue;
}
                
Some text

border


div {
    border-width: 20px;
    border-style: solid;
    border-color: blue red;
}
                
Some text

border


div {
    border-width: 40px 20px;
    border-style: solid dotted;
    border-color: blue red;
}
                
Some text

Перерыв

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

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

.wrapper {
    width: 666px;
    padding: 10px 0;
}
.inner { } 
                

.wrapper {
    width: 666px;
    padding: 10px 0;
}
.inner { } 
                
Путник милый, ты далече, но с тобой я говорю. В небесах зажглися свечи
Провожающих зарю.

.wrapper { width: 666px; }
.inner { margin-left: 500px; }
                
Мне жаль
margin + width = width содержащего блока - border - padding
500px + [166px] = 666px

.wrapper { width: 666px; }
.inner {
    margin-left: 500px;
    margin-right: 66px;
}
                
что тебя не застал
margin + width = width содержащего блока - border - padding
500px + 66px + [100px] = 666px

.wrapper { width: 666px; }
.inner { width: 300px; }
                
летний ливень
если margin не задан, значит он равен 0, если margin задан в auto, то он вычисляется

.wrapper { width: 666px; }
.inner {
    width: 300px;
    margin-right: 0;
}
                
в июльскую ночь

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


.wrapper { width: 666px; }
.inner {
    width: 300px;
    margin-left: auto
} 
                
на Балтийском заливе.

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

margin + width = width содержащего блока - border - padding
[366px] + 300px = 666px

.wrapper { width: 666px; }
.inner {
    width: 300px;
    margin: 0 auto
} 
                
Не видела ты

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

margin + width = width содержащего блока - border - padding
[183px] + [183px] + 300px = 666px

.wrapper { width: 666px; }
.inner { margin-right: -100px; }
                
волшебства
margin + width = width содержащего блока - border - padding
-100px + [766px] = 666px

.wrapper { width: 666px; }
.inner {
    margin-right: -100px;
    margin-left: -100px;
}
                
этих
margin + width = width содержащего блока - border - padding
[866px] - 100px - 100px = 666px

.wrapper { width: 666px; }
.inner {
    width: 50%;
    margin-left: auto;
    margin-right: -100px;
}
                
линий.

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

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

Блоки

That's the price you pay
Leave behind your heartache, cast away

Ожидание

That's the price you pay
Leave behind your heartache, cast away

Реальность

That's the price you pay
Leave behind your heartache, cast away
.inner { margin-top: 30px; }
                

Блоки

Я, конечно, еще спою на прощанье, но покину твой дом — с лучом рассвета.

Ожидание

Я, конечно, еще спою на прощанье, но покину твой дом — с лучом рассвета.

Реальность

Я, конечно, еще спою на прощанье, но покину твой дом — с лучом рассвета.

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

Если у двух блочных элементов, пересекаются margin'ы, то
  1. Берутся максимальный и минимальный среди всех margin'ов
  2. Если максимальный < 0, то максимум — 0
  3. Если минимальный > 0, то минимум — 0.
  4. Результирующий 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; }
                
Как победа - не со мной,
Как надежда - нелегка.
Как победа - не со мной,
Как надежда - нелегка.

Типы боксов

  • блочного уровня
  • строчного уровня (inline)

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

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

Строчные элементы генерирует бокс(ы) строчного уровня.

Строчные элементы по-умолчанию:

  • 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

CSS-свойство:

display: inline, inline-block, inline-table

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

  • Выглядят как строки
  • Выстраиваются слева направо, сверху вниз
  • Участвуют в строчном контексте форматирования
  • Могут создать вокруг себя анонимные строчные боксы
Some inline text followed by a span followed by more inline text.
Some inline text followed by a span followed by more inline text.

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

  • не реагирует на ширину и высоту
  • не реагирует на вертикальные margin'ы
  • padding'и не затрагивают высоту строки
span {
    height: 200px;
    padding: 20px;
}
                
span {
    background: #ffb9ee;
    height: 200px;
    padding: 20px;
}
                
Just tonight I will see it’s all because of me. Just tonight I will stay and we’ll throw it all away
Just tonight I will see it’s all because of me. Just tonight I will stay and we’ll throw it all away

Математика строчных элементов

  • реагирует на ширину и высоту
  • реагирует на вертикальные margin'ы
  • padding'и затрагивают высоту строки
  • создаёт внутри себя новый блочный контекст

.wrapper { width: 500px; }
.inner {
    width: 50%;
    height: 120px;
    margin: 20px 0;
}

                
.wrapper { width: 500px; }
.inner {
    display: inline-block;
    width: 50%;
    height: 120px;
    margin: 20px 0;
}
                
                
Будем заново учиться ходить по небу, никаких светофоров, разделительных полос.
И где бы я ни был, где бы я ни был иди на мой голос, иди на мой голос

Итог

  • Элементы на странице отображаются в виде боксов
  • Каждый бокс имеет контентную часть (content), отступы (padding и margin) и границу (border)
  • Боксы бывают двух видов - блочного уровня и строчного уровня
  • Для блочных боксов размеры и отступы можно задать либо явно, либо оставить вычисляемыми
  • Строчные боксы не будут реагировать на заданные ширину, высоту и вертикальные отступы
  • Элемент можно сделать строчным или блочным, используя CSS-свойство display
  • inline-block элементы - строчные элементы, обладающие свойствами блочного