Flexbox

CSS flexbox (Flexible Box Layout Module) - модуль макета гибкого контейнера - представляет собой способ компоновки элементов, в основе лежит идея оси.

Flexbox состоит из гибкого контейнера (flex container) и гибких элементов (flex items).
Гибкие элементы могут выстраиваться в строку или столбик, а оставшееся свободное пространство распределяется между ними различными способами.

Основная цель flexbox -гибкая настройка ширины и высоты элементов, для более удобного распределения элементов в родительском контейнере, в частности — это удобно в тех случаях, когда нужно соответствовать всем типам дисплеев устройств и размерам экранов. Flex контейнер расширяет вложенные элементы для того, чтобы заполнить доступное пространство или же урезает их, чтобы избежать переполнения.

Какую проблему может решать:
  • Вертикальное выравнивание блока внутри родителя
  • Распределение ширины/высоты одинаково между всеми дочерними элементами
  • Решать проблему с горизонтальным и вертикальным центрированием
  • Переносить элементы внутри контейнера, не допуская его переполнения
  • Создавать прижатый к низу страницы подвал сайт
  • Создавать резиновое меню

Важно!
Flexbox лучше всего подходит для компонентов в приложении и для не масштабных шаблонов. Не стоит использовать только одни Flexbox для создания сайта, необходимо грамотно совмещать их с другими способами компоновки элементов.
Flexbox: основные понятия
Картинка с сайта w3.org
Оси — одно из основных понятий во флексбоксах.
В обычном потоке документа блоки и текст располагаются слева направо и сверху вниз.

Элементы в flexbox могут располагаться вдоль основной оси (от main-start до main-end) и/или же вдоль поперечной оси (от cross-start до cross-end).

- main axis - основная ось flex контейнера, вдоль которой располагаются flex элементы. Обратите внимание, что ей необязательно быть горизонтальной, все зависит от свойства flex-direction, о котором вы прочитаете позже.
Начало и конец главной оси называются main start и main end. Выкладываются соответственно, начиная с main-start и заканчивая main-end.

- cross axis - ось перпендикулярная главной оси, называется поперечной. Её направление зависит от направления главной оси.
Начало и конец этой оси называются cross start и cross end. Выкладываются соответственно, начиная с cross-start и заканчивая cross-end.

- Основной размер (main size) - высота или ширина flex-элемента, что зависит от того, в каком направлении идёт основная ось.

- Поперечный размер (cross size) - ширина или высота flex-элемента, в зависимости от направления поперечной оси.

Дополнительно:
- Родительский элемент, на который назначено свойство display: flex называется flex container
- Элементы, размещённые в нём как flex-блоки называются flex items
Display: flex и inline-flex
Создание CSS разметки с помощью Flexbox начинается с установки необходимому HTML элементу CSS-свойства display со значением flex или flex-inline.

После этого данный элемент становится flex-контейнером (flex container), а все его дочерние элементы – flex-элементами (flex items).

По умолчанию flex-элементы во flex-контейнере занимают всю его высоту.

Значение flex или flex-inline определяет то, как flex-контейнер будет представлен на странице.
Flex - элемент ведёт себя как блочный.
Flex-inline - элемент ведёт себя как строчный.

Ранее вы уже видели пример работы display:flex, рассмотрим тут его еще раз и добавим еще пример с display:flex-inline
html
<!-- flex-контейнер -->
<div class="main_box">
  <div class="box1">Блок 1</div>
  <div class="box2">Блок 2</div>
  <div class="box3">Блок 3</div>
</div>
css - display:flex
.main_box
{
    display: flex;
}

.box1, .box2, .box3
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
}
css - display:flex-inline
.main_box
{
    display: flex-inline;
}

.box1, .box2, .box3
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
}
Устройство flex-контейнера
Направление осей
В CSS Flexbox имеются две оси.
Первая ось - главная (по умолчанию она направлена слева направо).
Вторая ось - поперечная (по умолчанию направлена сверху вниз), она всегда перпендикулярна главной.

Главная ось задаёт основное направление flex-элементов во flex-контейнере, а поперечная ось определяет их направление переноса на новую линию.
Направление главной оси: flex-direction
По умолчанию элементы во flex-контейнере располагаются вдоль направления главной оси (т.е. слева направо) на одной линии.

Направление главной оси можно поменять с помощью CSS-свойства flex-direction.
По умолчанию этому свойству присваивается значение row, т.е. располагать дочерние элементы в ряд слева направо (для большинства языков) или справа налево (для арабских языков).

Но есть и другие значения, смотрите ниже:

flex-direction: row;  /* слева направо (по умолчанию) */
flex-direction: row-reverse; /* справа налево */
flex-direction: column; /* сверху вниз */
flex-direction: column-reverse; /* снизу вверх */
flex-direction: inherit; /* переводит значение свойства в значение по умолчанию */
flex-direction: initial; /* наследует значение свойства от родительского элемента */
Рассмотрим на примере:
html
<p>flex-direction: row;</p>
<!-- flex-контейнер -->
<div class="main_box">
  <div class="box1">Блок 1</div>
  <div class="box2">Блок 2</div>
  <div class="box3">Блок 3</div>
</div>

<hr>

<p>flex-direction: row-reverse;</p>
<!-- flex-контейнер 2-->
<div class="main_box2">
  <div class="box1">Блок 1</div>
  <div class="box2">Блок 2</div>
  <div class="box3">Блок 3</div>
</div>

<hr>

<p>flex-direction: column;</p>
<!-- flex-контейнер 3-->
<div class="main_box3">
  <div class="box1">Блок 1</div>
  <div class="box2">Блок 2</div>
  <div class="box3">Блок 3</div>
</div>

<hr>

<p>flex-direction: column-reverse;</p>
<!-- flex-контейнер 4-->
<div class="main_box4">
  <div class="box1">Блок 1</div>
  <div class="box2">Блок 2</div>
  <div class="box3">Блок 3</div>
</div>
style.css
.main_box
{
    display: flex;
    flex-direction: row;
}

.main_box2
{
    display: flex;
    flex-direction: row-reverse;
}

.main_box3
{
    display: flex;
    flex-direction: column;
}

.main_box4
{
    display: flex;
    flex-direction: column-reverse;
}

.box1, .box2, .box3
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
}
Направление поперечной оси
Вдоль этой оси работают «вертикальные» выравнивания.

Поперечная ось всегда перпендикулярна главной оси и поворачивается вместе с ней:
  • Если главная ось направлена горизонтально, то поперечная ось смотрит вниз.
  • Если главная ось направлена вертикально, то поперечная ось смотрит направо.
Это не совсем логичное поведение, к которому надо привыкнуть. Получается, что поперечная ось никогда не смотрит вверх или влево. А свойства для поворота поперечной оси нет.
Управление многострочностью: flex-wrap
По умолчанию все flex-items располагаются на одной строке, для того что бы они могли переноситься на новые строки внутри flex-container используется свойство flex-wrap. Свойство также позволяет контролировать направление, в котором выкладываются строки.

Расмотрим пример.
Ширина flex-контейнера равна 300px, добавим еще flex-элементов и наглядно увидим, что сначала блоки попытались ужаться (цифры перенеслись на новую строку), но в итоге дочерние элементы выбились из своего родителя-контейнера.

html
<div class="main_box">
  <div class="box1">Блок 1</div>
  <div class="box2">Блок 2</div>
  <div class="box3">Блок 3</div>
  <div class="box4">Блок 4</div>
  <div class="box5">Блок 5</div>
</div>
css
.main_box
{
    display: flex;
    flex-direction: row;
    border-radius: 5px;
    background-color: #138900;
    padding: 15px;
    margin: 30px;
    width: 200px;
}

.box1, .box2, .box3, .box4, .box5
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
}
Исправим, добавив свойство - flex-wrap: wrap;
У него также есть три значения:
css
flex-wrap:nowrap; /* (только на одной линии - по умолчанию) */
flex-wrap:wrap;  /* (разрешить перенос flex-элементов на новые линии) */
flex-wrap: wrap-reverse;  /*(осуществлять перенос flex-элементов в обратном порядке) */
Получаем:
Заметьте, что значения wrap и wrap-reverse CSS-свойства flex-wrap определяют направление поперечной оси.
То есть, если в flex-direction мы задавали направление по главной оси, то flex-wrap мы задаем направление поперечной оси.
Сокращение: flex-flow
Существует сокращение для свойств flex-direction и flex-wrap - flex-flow.
Например, вы можете заменить:
css
flex-direction: row;
flex-wrap: wrap;

/* Можно заменить:*/
flex-flow: row wrap; /* 1 значение - flex-direction, 2 значение - flex-wrap */
Порядок отображения flex-элементов: order
В Flexbox также есть возможность менять порядок расположения flex-элементов, не влияя на исходный порядок.
Это ещё одна вещь, которую невозможно сделать традиционными методами CSS.

По умолчанию, элементы располагаются в контейнере в том порядке, в котором указаны в разметке.
Для изменения порядка следования одних flex-элементов относительно используйте свойство order.
Это свойство выстраивает элементы в порядке возрастания их номеров.

По умолчанию все flex-элементы имеют order: 0;.
При указании значения от -1 для элемента он перемещается в начало сроки, значение 1 — в конец.
Если несколько flex-элементов имеют одинаковое значение order, они будут отображаться в соответствии с исходным порядком.

Посмотрите на пример ниже. Расставим знакомые уже нам блоки в другом порядке. Заданим порядок блоков такой: 5 блок, 3 блок, 4 блок, 2 блок и 1 блок.
Для этого блоку 5 мы зададим значение -1, тем самым двигая его в самый верх.
3 и 4 блок оставим на своих местах, оставляем значение по умолчанию - 0.
Чтобы 2 блок шел за 4, ставим ему значение 1, то есть он встанет сразу после значения 0 у 4 блока.
Чтобы 1 блок встал сразу за 1, присвоим ему значение 2.
html
<div class="main_box">
  <div class="box1">Блок 1</div>
  <div class="box2">Блок 2</div>
  <div class="box3">Блок 3</div>
  <div class="box4">Блок 4</div>
  <div class="box5">Блок 5</div>
</div>
css
.main_box
{
    display: flex;
    flex-direction: raw;
    flex-wrap: wrap;
    border-radius: 5px;
    background-color: #138900;
    padding: 15px;
    margin: 15px;
    width: 390px; 
}

/* передвинем 1 flex-элемент до 5 позиции */
.box1
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
    order: 2;
}

/* передвинем 2 flex-элемент до 4 позиции */
.box2
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
    order: 1;
}

/* оставим 3 flex-элемент на своем месте */
.box3
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
    order: 0;
}

/* оставим 4 flex-элемент на своем месте */
.box4
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
    order: 0;
}

/* переместим 5 flex-элемент в начало */
.box5
{
    border-radius: 5px;
    background-color: rgb(207,232,220);
    padding: 1em;
    order: -1;
}
Гибкость flex-элементов
Определяющим аспектом гибкого макета является возможность «сгибать» flex-элементы, изменяя их ширину и высоту, чтобы заполнить доступное пространство в основном контейнере.

Коэффициент роста: свойство flex-grow
Задает возможность элементу увеличиваться в размере.
Принимает число, которое выступает в качестве пропорции. Пропорция определяет, какое количество доступного пространства в контейнере может занимать элемент.

Значение 0, запрещает увеличение. Отрицательные значения не принимаются.
Если все элементы имеют свойство «flex-grow» со значением 1, доступное пространство будет между ними распределяться равномерно.
Если значением flex-grow одного из элементов является 2, данный элемент будет занимать двойную порцию пространства по сравнению с остальными элементами (или, по крайней мере, попытается это сделать).
Коэффициент уменьшения: свойство flex-shrink
Полная противоположность свойству flex-grow. Определяет, насколько блоку можно уменьшиться в размере.
Используется, когда элементы не вмещаются в контейнер. Вы определяете, какие элементы должны уменьшиться в размерах, а какие — нет.

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

Подробнее о том, как работает сжатие можно почитать тут.
Свойство flex-basis
Отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами CSS Flexbox.
Этим размером может быть длина (например, 20%, 5rem и т.д.) или ключевое слово.
Ключевое слово «auto» означает использование значения свойства «width» или «height» элемента.
Ключевое слово «content» означает учет содержимого элемента. Указанное ключевое слово пока плохо поддерживается, поэтому сложно определить разницу между min-content, max-content и fit-content.

Flex-basis влияет на размер элементов вдоль главной оси.
Если значением свойства является 0, окружающее элемента пространство не принимается в расчет.
Если значением является «auto», доступное пространство распределяется согласно значению свойства «flex-grow».
Сокращение: flex
Данное свойство является сокращением для flex-grow, flex-shrink и flex-basis.
Второй и третий параметры (flex-shrink и flex-basis) являются опциональными.
Значения по умолчанию: 0 (grow) 1 (shrink) auto (basis). Можно опустить.

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

Выравнивание вдоль главной оси: justify-content
Выравнивает элементы вдоль главной оси (обычно по горизонтали).
Добавляет промежутки к элементам, так как по умолчанию, они сгруппированы вместе.
Промежутки добавляются после расчета значений margin и flex-grow. Если какие-либо элементы имеют ненулевое значение flex-grow или margin: auto, свойство не будет оказывать влияния.
Оно также позволяет управлять выравниванием при переполнении строки элементами. Например переносить переполняющие колонку элементы в новую колонку и выравнивать их так же как и в основной колонке.

Свойство не наследуется и задаётся для флекс-контейнера.
justify-content:flex-start;  /* элементы выравниваются относительно начала оси – по умолчанию. */

justify-content:flex-end;  /* элементы выравниваются относительно конца оси. */

justify-content:center;  /* элементы выравниваются по центру. */

justify-content:space-between;  /* расстояния между соседними элементами одинаковые, между элементами и краями флекс-контейнера отступов нет. */

justify-content:space-around;  /* расстояния между соседними элементами одинаковые, между элементами и краями флекс-контейнера есть отступ, равный половине расстояния между соседними элементами. */

justify-content:space-evenly;  /* расстояния между соседними элементами и краями флекс-контейнера одинаковые. */
Выравнивание вдоль поперечной оси: align-items
Выравнивает элементы вдоль поперечной оси (обычно по вертикали).
Это свойство задаётся для флекс-контейнера.

Его значением по умолчанию является stretch. Именно благодаря этому значению флекс-элементы и растягиваются на всю «высоту» флекс-контейнера. Если флекс-элементам задана высота, то растягиваться они не будут.
align-items:stretch;  /* по умолчанию - элементы растягиваются, чтобы заполнить весь контейнер с учетом их min-width и max-width. */

align-items:flex-start;  /*  элементы размещаются с начала поперечной оси. */

align-items:flex-end;  /* элементы размещаются с конца поперечной оси. */

align-items:center;  /* элементы выравниваются по центру. */

align-items:baseline;  
/* Если задать его контейнеру, то флекс-элементы будут выравниваться по базовой линии текста в них. Эта воображаемая линия проходит по нижней части букв.
Если выровнять флекс-элементы по базовой линии, то они выстроятся так, чтобы текст в них был как бы на «одной строке».*/
Выравнивание содержимого в нескольких строках: align-content
Управляет выравниванием рядов флекс-элементов вдоль поперечной оси.

Свойство align-content «перекрывает» заданное значение align-items, которое управляет выравниванием флекс-элементов вдоль поперечной оси. Это происходит и в случае, когда есть только один ряд флекс-элементов, и когда рядов несколько.

Свойство не наследуется.

Значения свойства:
align-content:stretch;  /* по умолчанию -  стандартное состояние, при котором строки растягиваются на вся оставшееся место.*/

 align-content:flex-start;  /*  располагает ряды в начале поперечной оси. */

 align-content:flex-end;  /* располагает ряды в конце поперечной оси. */

 align-content:center;  /* располагает ряды от центра поперечной оси. */

 align-content:space-between; 
/* равномерно распределяет ряды вдоль поперечной оси, расстояния между соседними рядами одинаковые, отступов у краёв нет. */

align-content:space-around;  
/* равномерно распределяет ряды вдоль поперечной оси, расстояния между соседними рядами одинаковые, отступы у краёв равны половине расстояния между соседними рядами. */

align-content:space-evenly; 
/* равномерно распределяет ряды вдоль поперечной оси, расстояния между соседними рядами и у краёв одинаковые. */
Интересный факт

Ранее в спецификации w3 было описано другое поведение:
  • если есть только один ряд флекс-элементов, то работает align-items;
  • если есть несколько рядов, то работает align-content.
Довольно долго такое поведение было во всех браузерах. Но в начале 2019 года поведение было актуализировано согласно спецификации во всех современных браузерах.

Вы можете столкнуться со старым поведением, если все еще не обновили браузер.
Свойство align-content: stretch и align-items
В случае одновременного задания align-items и align-content свойство align-items не отключается полностью, а может влиять на отображение флекс-элементов в рядах.

Это происходит, когда мы используем для align-content значение по умолчанию — stretch. Оно растягивает ряды флекс-элементов, при этом оставшееся свободное место между ними делится поровну.

Отображение строк при align-content: stretch зависит от значения align-items:
  • Если у align-items задано значение stretch, то элементы в строках растягиваются на всю высоту своей строки.
  • Если значение отлично от stretch, то элементы в строках ужимаются под своё содержимое и выравниваются в строках в зависимости от значения align-items.
Выравнивание отдельного элемента: align-self
Свойство align-self в отличие от предыдущих ( justify-content, align-items и align-content) предназначено для flex-элементов. Оно позволяет изменить выравнивание flex-элемента вдоль направления поперечной оси. Свойство align-self может принимать такие же значения как align-items.
align-self:stretch;  /* по умолчанию - элементы растягиваются, чтобы заполнить весь контейнер с учетом их min-width и max-width */

align-self:flex-start;  /*  элементы размещаются с начала поперечной оси */

align-self:flex-end;  /* элементы размещаются с конца поперечной оси */

align-self:center;  /* элементы выравниваются по центру */

align-self:baseline;  /* элементы выравниваются вдоль их основной линии */
Применение flexbox
Идеальное выравнивание
Можно отцентровать элемент по вертикали и горизонтали так, чтобы центровка сохранялась при изменении размеров элемента или контейнера.
Для этого нужно задать контейнеру раскладку флексбокса, а дочернему флекс-элементу margin: auto. В этом случае флекс-элемент уменьшит свой размер под содержимое и отцентруется по вертикали и горизонтали.

«Гибкое» меню
Флексбокс будет полезен, если нужно создать раскладку, в которой пункты равномерно распределены по блоку меню, при чём первый пункт примыкает к левой части блока меню, а последний — к правой, с небольшими внутренними отступами.

Чтобы это сделать, нужно задать меню раскладку флексбокса, тогда пункты станут флекс-элементами. Затем с помощью свойства распределения элементов justify-content: space-around; можно добиться нужного результата.
Если вы добавите в меню ещё один пункт, отступы между пунктами меню будут «гибко» меняться, подстраиваясь под новые условия.

Сортировка элементов на CSS
Используя одновременно флексбокс и селектор по выделению чекбокса :checked ~, можно с помощью этого селектора управлять порядком флекс-элементов, изменяя направление главной оси с помощью flex-direction. Лучше всего эффект работает, когда направление главной оси меняется с «сверху вниз» на «снизу вверх». При этом флекс-контейнер должен находиться в разметке на одном уровне с чекбоксом.

Блоки одинаковой высоты
В обычной блочной модели есть фундаментальный недостаток — соседние блоки ничего не знают друг о друге, поэтому их высоты нельзя «связать». При этом надо учитывать, что содержимое блоков может быть разным и их высота может меняться.
На флексбоксах можно реализовать раскладку с блоками одинаковой высоты — флекс-элементы по умолчанию растягиваются на всю высоту контейнера. Для этого достаточно задать родительскому блоку display: flex;.
Создавать прижатый к низу страницы подвал сайт
Полезные ссылки
Чтобы не запутаться во всем разнообразии flexbox, сохраните себе краткую шпаркалку на телефон или компьютер - шпаргалка
Практика
1. Палитра цветов
Тебе будет дан код, его нужно дописать и с помощью флексбокса разложить цвета на палитре в точности как на образце.

Подсказка.
Используй свойства: display: flex, flex-direction, justify-content, align-items и align-self.
Также вспомни про поля из урока по блочной верстке.

    Материалы:
    Цвет 1 - #43976F
    Цвет 2 - #427494
    Цвет 3 - #73A148
    Цвет 4 - #A6614A
      <!DOCTYPE html>
      <html lang="ru">
        <head>
          <meta charset="utf-8">
          <title>простая палитра</title>
          <link href="" rel="stylesheet"> <!-- Не забудь подключить стили -->
        </head>
        <body class="exam">
          <div class="palette">
            <div class="color-1">1</div>
            <div class="color-2">2</div>
            <div class="color-3">3</div>
            <div class="color-4">4</div>
          </div>
        </body>
      </html>
      .exam {
          padding: 15px;
          margin: 0px;
          width: 200px;
          text-align: center;
          background-color: #cfe8dc54;
          color: rgb(255, 255, 255);
          font-weight: 600;
      }
      
      .palette {
          position: relative;
          box-sizing: border-box;
          padding: 5px;
          border: 5px solid #CFE8DC;
          border-radius: 10px;
          background-color: #fff;
          top: 10px;
          margin: 150px 0px 0px 600px;
          width: 600px;
          height: 500px;   
      }
      Образец:
        2. Сложная палитра цветов
        Тебе будет дан код, его нужно дописать и с помощью флексбокса разложить цвета на палитре в точности как на образце.

        Подсказка.
        Используй свойства: display: flex, flex-wrap, justify-content, align-content, flex-basis и order.

        Цвет 1: фон - #52AABC, текст - #1B6B7A
        Цвет 2: фон - #97D8ED, текст - #31809A
        Цвет 3: фон - #F0E593, текст - #9C8F30
        Цвет 4: фон - #F8BC43, текст - #A17316
        Цвет 5: фон - #A6620A, текст - #D3A366
        Цвет 6: фон - #A67E0A, текст - #D3B766
        Цвет 7: фон - #A6340A, текст - #D38366

          Материалы:
          Цвет 1: фон - #52AABC, текст - #1B6B7A
          Цвет 2: фон - #97D8ED, текст - #31809A
          Цвет 3: фон - #F0E593, текст - #9C8F30
          Цвет 4: фон - #F8BC43, текст - #A17316
          Цвет 5: фон - #A6620A, текст - #D3A366
          Цвет 6: фон - #A67E0A, текст - #D3B766
          Цвет 7: фон - #A6340A, текст - #D38366
            <!DOCTYPE html>
            <html lang="ru">
              <head>
                <meta charset="utf-8">
                <title>сложная палитра</title>
                <link href="" rel="stylesheet"> <!-- Не забудь подключить стили -->
              </head>
              <body class="exam">
                <div class="palette">
                  <div class="color-1">1</div>
                  <div class="color-2">2</div>
                  <div class="color-3">3</div>
                  <div class="color-4">4</div>
                  <div class="color-5">5</div>
                  <div class="color-6">6</div>
                  <div class="color-7">7</div>
                </div>
              </body>
            </html>
            .exam {
                padding: 15px;
                margin: 0px;
                width: 200px;
                text-align: center;
                background-color: #cfe8dc54;
                color: rgb(255, 255, 255);
                font-weight: 600;
            }
            
            .palette { 
                position: relative;
                box-sizing: border-box;
                padding: 5px;
                border: 5px solid #f5f5f5;
                border-radius: 10px;
                background-color: #fff;
                margin: 150px 0px 0px 600px;;
                width: 600px;
                height: 500px;
                font-weight: bold; 
            }
            Образец:
              3. Испытание - очень сложная палитра цветов
              Тебе будет дан код, его нужно дописать и с помощью флексбокса разложить цвета на палитре в точности как на образце.

              На этот раз придётся воспользоваться всем изученным арсеналом свойств флексбокса. Также для прохождения может понадобиться повторение CSS-селекторов.

                Материалы:
                  <!DOCTYPE html>
                  <html>
                    <head>
                      <meta charset="utf-8">
                      <title>Название документа</title>
                      <link rel="stylesheet" href=""> <!-- не забудь подключить стили-->
                     </head>
                     <body class="exam">
                      <div class="palette-box">
                        <p>Палитра 1</p>
                        <div class="palette-small">
                          <div class="color-1"></div>
                          <div class="color-2"></div>
                          <div class="color-3"></div>
                          <div class="color-4"></div>
                        </div>
                      </div>
                      <div class="palette-box">
                        <p>Палитра 2</p>
                        <div class="palette-small">
                          <div class="color-1"></div>
                          <div class="color-2"></div>
                          <div class="color-3"></div>
                          <div class="color-4"></div>
                        </div>
                      </div>
                      <div class="palette-box">
                        <p>Палитра 3</p>
                        <div class="palette-small">
                          <div class="part">
                            <div class="color-1"></div>
                            <div class="color-2"></div>
                          </div>
                          <div class="part">
                            <div class="color-3"></div>
                            <div class="color-4"></div>
                          </div>
                        </div>
                      </div>
                      <div class="palette-box">
                        <p>Палитра 4</p>
                        <div class="palette-small">
                          <div class="part">
                            <div class="color-1"></div>
                            <div class="color-3"></div>
                          </div>
                          <div class="part">
                            <div class="color-2"></div>
                            <div class="color-4"></div>
                          </div>
                        </div>
                      </div>
                    </body>
                  </html>
                  body {
                      font-family:"Arial","Helvetica Neue","Helvetica",sans-serif;
                    }
                    
                    .exam {
                       padding: 15px;
                       margin: 200px 500px;
                       width: 800px;
                       text-align: center;
                       background-color: #cfe8dc54;
                    }
                    
                    .palette-box {
                      box-sizing: border-box;
                      display: inline-block;
                      vertical-align: top;
                    }
                    
                    .palette-small {
                      top: 5px;
                      margin: 0 70px 25px 0;
                      width: 200px;
                      height: 200px;
                      position: relative;
                      box-sizing: border-box;
                      padding: 5px;
                      border: 5px solid #CFE8DC;
                      border-radius: 10px;
                      background-color: #fff;
                    }
                    
                    p {
                        text-align: left;
                    }
                    
                    .color-1 {
                      border-radius: 5px;
                      background-color: #52AABC;
                      padding: 1em;
                      margin: 1px;
                    }
                    
                    .color-2 {
                      border-radius: 5px;
                      background-color: #97D8ED;
                      padding: 1em;
                      margin: 1px;
                    }
                    
                    .color-3 {
                      border-radius: 5px;
                      background-color: #F0E593;
                      padding: 1em;
                      margin: 1px;
                    }
                    
                    .color-4 {
                      border-radius: 5px;
                      background-color: #F8BC43;
                      padding: 1em;
                      margin: 1px;
                    }
                    
                  Образец:
                    4. Меню на flexbox
                    Часто встречаются дизайны, в которых пункты равномерно распределены по блоку меню. Первый пункт примыкает к левой части блока меню, а последний — к правой, причём с небольшими внутренними отступами.

                    Давай попробуем сделать вместе.
                    1. Сначала задай меню раскладку флексбокса.
                    2. С помощью свойства justify-content задай распределение элементов по главной оси с половинными отступами по краям.
                    3. Задай меню ширину 80%. Сохрани и посмотри. Теперь поставь ширину 100%. Попробуй поиграть с шириной и понаблюдай.
                    4. Для меню задай центральное выравнивание элементов по поперечной оси.
                    5. Блоку с логотипом задай порядковый номер флекс-элемента -1, затем 1.

                      Материалы:
                      Картинка: Скачать
                      Размеры картинки: ширина 120, высота 120
                      Шрифт: 'Montserrat', sans-serif

                      Для css к своему коду добавь:
                        .menu a, a {
                            display: block;
                            padding: 15px 10px;
                            color: #1D8A35;
                            text-decoration: none; /*убираем подчеркивание текста ссылок*/
                            font-size: 24px;
                        }
                        
                        .menu {
                          /* К своим flexbox-значениям добавь код ниже*/
                        
                          margin: 0px; /*убираем верхнее и нижнее поле, равное 1em*/
                          padding-left: 0px; /*убираем левый отступ, равный 40px*/
                          background-color: #9FEAB0;
                          box-shadow: 0 5px 0 0 #1D8A35; /*задаем тень меню*/
                          list-style: none; /*убираем маркеры списка*/
                        }
                        Образец:
                          5. Продолжаем сайт с диванами
                          Не забыли про наш сайт с диванами? Давайте его немного дополним.
                          Добавим с помощью flexbox ещё одну секцию с товарами.
                          Наверное было сложно писать футер с помощью позиционирования, давай его тоже поправим и напишем его с помощью flexbox.

                          Подсказка.
                          Карточки товара можно оформить как маркированный список с классами, в которых потом уберешь маркировку и сам список оформи флексами.
                          Если совсем не получается ниже есть небольшой фрагмент кода по оформлению, но не подглядывай сразу, попробуй сам.

                            Материалы:
                            Коричневый диван: Скачать
                            Желтое кресло: Скачать
                            Кровать: Скачать

                            Цвета фона секции с товарами: #fff3e5

                            Размер секции с баннером и заголовком: 450px

                            Заголовок "Самые популярные товары":
                            Шрифт:"Georgia", "Times", serif
                            Размер: 30px
                            Межстрочное расстояние: 24px;
                            Толщина: 400

                            Заголовки в карточках:
                            Шрифт: "Georgia", "Times", serif
                            Размер: 22px
                            Толщина: 700
                            Выравнивание текста по центру
                            Межстрочное расстояние: 18px

                            Описание в карточке:
                            Размер: 16px
                            Курсивное начертание
                            Выравнивание текста по центру
                            Межстрочное расстояние: 16px

                            Стоимость:
                            Шрифт: "Arial", "Helvetica", sans-serif;
                            Размер: 22px
                            Толщина: 700
                            Цвет: #ff8a00
                              Образец:
                                Подсказка
                                <ul class="products-list">
                                            <li class="product-card">
                                              <h3>Корсар</h3>
                                              <p>Диван раскладной</p>
                                              <p class="price"><del>5000</del> 2500₽</p>
                                              <img src="/корсар.png" width="360" height="270" alt="диван раскладной Корсар">
                                            </li>
                                              .....
                                </ul>
                                
                                6. Инструктаж для хозяина
                                Попробуйте испытать свои силы и сверстать свой первый лендинг.
                                Используй все полученные ранее знания: блочная верстка, флексы, селекторы.

                                  Материалы:
                                  Картинка логотипа: Скачать
                                  Картинка фона: Скачать
                                  Картинка Доге: Скачать
                                  Иконка 1: Скачать
                                  Иконка 2: Скачать
                                  Иконка 3: Скачать

                                  Цвета, используемые на странице:
                                  #000000, #ffffff, #ffffffcb, #cccccc, #c4c4c4, #999999, #ffc5b3, #666666, #ff5a26
                                    Образец:
                                      Предыдущее занятие | Следующее занятие