Флексбокс, часть 2

Флексбокс, часть 2

Узнаем как управлять размерами и отступами флекс-элементов и как работают коэффициенты растяжения и сжатия, а также потренируемся создавать «гибкие» раскладки и элементы интерфейса.

×

Флекс-элементы и блочная модель [1/28]

В предыдущем курсе про флексбокс мы знакомились с базовыми понятиями этого механизма раскладки и подробно изучали, как работает выравнивание флекс-элементов. Ну а этот курс будет посвящён управлению размерами флекс-элементов.

Начнём с простого вопроса. Как работает привычная нам блочная модель внутри флекс-контейнера? Есть ли какие-нибудь отличия в поведении привычных свойств?

Ширина, высота, внутренние отступы и рамки для флекс-контейнеров и флекс-элементов работают как обычно: общий размер элементов складывается из этих компонентов. Это поведение так же можно менять с помощью свойства box-sizing.

Есть и несколько важных отличий:

Теперь поработаем с уже знакомыми свойствами и убедимся, что они работают привычным нам образом.


  1. Цель 1 Задайте всем лонгбордам .skate, на которых сидят еноты, ширину 75px и высоту 300px (минимальные размеры изменять не нужно),
  2. Цель 2 внутренние отступы со всех сторон 10px.
  3. Цель 3 Затем второму скейту задайте box-sizing: border-box.
×

Особенности свойства margin [2/28]

В предыдущем задании мы не упомянули про свойство margin, ведь оно таит много сюрпризов:

Всё дело в механизме распределения свободного места. Если внутри флекс-контейнера есть свободное место, то оно перераспределяется так:

  1. находятся элементы, у которых есть внешние отступы со значением auto;

  2. всё свободное место в соответствующих направлениях отдаётся таким отступам (то есть задаётся определённый размер отступа в пикселях);

  3. если элементов с автоматическими отступами на одном направлении несколько, то место между ними перераспределяется поровну;

  4. только после этого запускаются механизмы выравнивания.

Поэтому margin: auto; влияет на положение флекс-элементов на обеих осях, а также «ломает» механизмы выравнивания, ведь выравнивание происходит, когда есть свободное место. Но если всё свободное место «перетекло» в автоматический отступ, то и выравнивать нечего.

Эти особенности можно использовать во благо. Например, с помощью автоматических отступов вы можете управлять расположением элементов вдоль главной оси. Давайте поэкспериментируем.


  1. Цель 1 Задайте скейтбордам .skate внешние отступы со всех сторон 10px.
  2. Цель 2 Затем задайте margin-left: auto; второму скейту,
  3. Цель 3 а потом margin-right: auto; четвёртому скейту.
  4. Цель 4 Напоследок измените у .spot распределение по главной оси на flex-end

    и убедитесь, что ничего не изменилось

    .
×

Выравнивание и внешние отступы [3/28]

В прошлом задании мы проверили, как автоматический внешний отступ влияет на положение флекс-элементов на главной оси. Кроме того, мы убедились, что такие отступы «ломают» свойство justify-content.

Автоматический margin влияет и на выравнивание флекс-элементов вдоль поперечной оси.

Если у флекс-элемента отступ сверху или снизу автоматический, то на него не влияют, ни align-items, ни align-self. Такой элемент прижмётся либо к верху контейнера, либо к низу.

А если задать автоматические отступы с противоположных сторон, то элемент разместится по центру флекс-контейнера, так как свободное место «впитается» отступами поровну.


  1. Цель 1 Измените у .spot выравнивание флекс-элементов вдоль поперечной оси на stretch.
  2. Цель 2 Затем задайте margin-top: auto; второму скейту.
  3. Цель 3 Третьему скейту сначала задайте собственное выравнивание в конце поперечной оси,
  4. Цель 4 а потом задайте margin-bottom: auto;.
×

Направление главной оси и внешние отступы [4/28]

Будет ли результат таким, как на картинке снизу, если повернуть главную ось в предыдущем задании?

До После

Нет, не будет!

Дело в том, что «старые нефлексовые» свойства, такие как отступы или размеры, ничего не знают про направление осей. Они «мыслят по-старому», понятиями «верх» и «низ», «право» и «лево».

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

То же относится и к вертикальным отступам.

Давайте повернём ось, а затем внесём правки и получим результат, как на картинке выше.

На момент написания курса в Safari и других WebKit-браузерах есть баг, из-за которого блоки могут позиционироваться некорректно.


  1. Цель 1 Измените у .spot направление главной оси на column.
  2. Цель 2 Затем у второго скейта удалите свойство margin-top и добавьте свойство margin-left: auto;.
  3. Цель 3 У третьего скейта удалите свойство margin-bottom и добавьте свойство margin-right: auto;.
×

Базовый размер флекс-элемента, flex-basis [5/28]

На примере отступов видно, что «старые» свойства внутри флекс-контейнера ведут себя достаточно глупо. Ширина и высота тоже не умеют реагировать на поворот главной оси. Поэтому ввели понятия главный размер или main size и поперечный размер или cross size.

Если главная ось направлена горизонтально, то главный размер — это ширина, свойство width, а поперечный размер — это высота, свойство height. Если главная ось направлена вертикально, то всё наоборот.

А хотелось бы иметь «умное» свойство для задания размера флекс-элементов, которое знает про главную ось и «поворачивается» вместе с ней.

И такое свойство есть — это flex-basis. Оно задаёт базовый размер флекс-элемента или размер вдоль главной оси.

Если flex-basis не задан или его значение равно auto, то базовый размер берётся из width или height.

Свойство flex-basis принимает те же значения, что и width/height:

flex-basis: 100px; /* базовый размер 100 пикселей */
flex-basis: 50%;   /* базовый размер 50% контейнера */

Свойство flex-basis «сильнее» свойств width и height, и если у флекс-элемента заданы все три свойства, то flex-basis переопределит либо ширину, либо высоту в зависимости от направления главной оси.


  1. Цель 1 Скейту Оранжевого Енота .racoon-orange задайте ширину 300px и высоту 100px.
  2. Цель 2 Затем задайте ему же базовый размер 100%.
  3. Цель 3 После этого поменяйте направление главной оси .spot на column.

    Смотрите, как ширина и высота меняются при повороте оси из-за заданного базового размера.

×

Испытание: кубизм [6/28]

Итак, пришла пора проверить знания.

В этом испытании вам предстоит расположить блоки на палитре в нужном порядке. Задача — подобрать размеры элементов и их внешние отступы.

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

Подсказка: размеры и неавтоматические отступы кратны 5.


×

Коэффициент растягивания элементов, flex-grow [7/28]

В предыдущем задании мы кое о чём умолчали. На самом деле, базовый размер — это не просто размер элемента вдоль главной оси, это начальный или исходный размер вдоль главной оси.

Почему так важны эти начальный или исходный?

И снова всё дело в механизме перераспределения свободного места во флексбоксе.

Если внутри флекс-контейнера по главной оси остаётся свободное место, то мы можем попросить флекс-элемент, чтобы он увеличился и занял это место. Это делается с помощью свойства flex-grow, которое можно назвать «коэффициентом флекс-жадности» флекс-элемента.

Свойство flex-grow принимает неотрицательные числовые значения, его значение по умолчанию — 0.

Если значение flex-grow равно нулю, то флекс-элемент «не претендует» на оставшееся свободное место во флекс-контейнере и не будет увеличиваться, чтобы занять это место.

Если значение flex-grow больше нуля, то флекс-элемент будет увеличиваться, «захватывая» оставшееся свободное место.

Получается, что базовый размер — это исходный размер флекс-элементов до применения flex-grow.


Задайте коэффициент растягивания flex-grow равный 1:

  1. Цель 1 скейту Зелёного Енота .racoon-green
  2. Цель 2 и скейту Оранжевого Енота .racoon-orange.
×

Пропорциональное растягивание элементов [8/28]

Если сразу у нескольких флекс-элементов значение flex-grow больше нуля, то они будут делить свободное место между собой.

Свободное место будет добавляться флекс-элементам пропорционально значениям их «коэффициента жадности». Например, если во флекс-контейнере есть два элемента:

.element-1 { flex-grow: 1; }
.element-2 { flex-grow: 2; }

То второму элементу достанется в два раза больше свободного места, чем первому. Если изменить значения коэффициентов у этих элементов на такие:

.element-1 { flex-grow: 50; }
.element-2 { flex-grow: 100; }

То ничего не изменится, так как отношение коэффициентов не изменилось: 100 в два раза больше 50. То есть важно не само значение коэффициента, а его соотношение с коэффициентами остальных элементов.

Это задание-загадка на подбор пропорций. Вам нужно подобрать такие значения flex-grow, чтобы итоговый размер элементов оказался таким же, как и у «линеек» снизу. Базовые размеры элементов и размеры флекс-контейнера вы узнаете из кода.

Сейчас поэкспериментируйте самостоятельно, а в следующем задании мы детально разберём алгоритм расчёта итогового размера флекс-элементов с ненулевыми flex-grow.

Подсказка: в простейшем решении коэффициенты будут целыми числами не больше 5.


  1. Цель 1 Задайте енотам на верхней поляне .spot-1 значения flex-grow так, чтобы их ширина стала равной ширине «линеек».
  2. Цель 2 Сделайте то же самое с енотами на нижней поляне .spot-2.

В этом задании можно менять только значения flex-grow.

×

Расчёт итогового размера с flex-grow [9/28]

1 шаг. Рассчитываем свободное место во флекс-контейнере:

Свободное место = Ширина контейнера - Сумма базовых размеров элементов

2 шаг. Считаем размер минимальной доли свободного места:

Доля свободного места = Свободное место / Сумма flex-grow всех элементов

3 шаг. Базовый размер каждого флекс-элемента увеличиваем на размер минимальной доли свободного места умноженной на значение flex-grow этого элемента:

Итоговый размер = Базовый размер + (Доля свободного места * flex-grow)

Для верхнего блока с енотами хочется задать коэффициенты 1 и 2. Но нужные размеры блоков получаются с коэффициентами 1 и 3. Давайте посчитаем:

Свободное место = 300px - (50px * 2) = 200px
Доля свободного места = 200px / (1 + 3) = 50px
Итоговый размер зелёного енота = 50px + (50px * 1) = 100px
Итоговый размер коричневого енота = 50px + (50px * 3) = 200px

Но если задать флекс-элементам нулевой базовый размер, свободное место будет занимать всю ширину флекс-контейнера, и коэффициенты жадности будут другими.

Использовать flex-basis: 0 и flex-grow для точного управления относительными размерами не стоит. Лучше использовать базовый размер в процентах.

Тонкость. На размер оставшегося свободного места влияет не только flex-basis, но и рамки, и отступы. Если flex-basis явно задано нулевое значение, то min-width на размер свободного места влиять не будет, так как ограничения размеров к флекс-элементам применяются уже после перераспределения свободного места.


  1. Цель 1 Задайте енотам на верхней поляне .spot-1 значения flex-grow так, чтобы их ширина стала равной ширине «линеек».
  2. Цель 2 Сделайте то же самое с енотами на нижней поляне .spot-2.

В этом задании можно менять только значения flex-grow.

×

Коэффициент сжатия элементов, flex-shrink [10/28]

Если сумма базовых размеров флекс-элементов больше, чем размер флекс-контейнера, то возникает отрицательное пространство.

Механизм перераспределения работает не только для свободного места, но и для отрицательного пространства. Флекс-элементы умеют распределять отрицательное пространство между собой и сжиматься.

За уменьшение флекс-элементов отвечает свойство flex-shrink, которое можно назвать «коффициентом сжатия».

Свойство flex-shrink принимает неотрицательные числовые значения, его значение по умолчанию — 1.

Если значение flex-shrink больше нуля, то флекс-элемент будет уменьшаться, «впитывая» часть отрицательного пространства, если оно существует.

Если значение flex-shrink равно нулю, то флекс-элемент уменьшаться не будет.

Флекс-элементы стараются быть максимально «гибкими» и не выпадать из своего контейнера, поэтому у flex-shrink значение по умолчанию равно 1. Но если задавать нулевые значения для коэффициента сжатия, то выпадения элементов добиться можно.


  1. Цель 1 Скейтбордам на первой поляне .spot-1 .skate задайте базовый размер флекс-элементов 300px.
  2. Цель 2 На вторую поляну добавьте скейт с Голубым Енотом.
  3. Цель 3 Затем задайте нулевой коэффициент сжатия скейту Коричневого Енота .racoon-brown
  4. Цель 4 и всем скейтам на второй поляне.
×

Пропорциональное сжатие элементов [11/28]

Свойство flex-shrink очень похоже на свойство flex-grow. Оно задаёт пропорции, в которых флекс-элементы «впитывают» отрицательное пространство.

Чем больше значение коэффициента сжатия у элемента, тем больше отрицательного пространства он «впитает» и тем сильнее сожмётся.

Когда базовые размеры флекс-элементов одинаковы, пропорции сжатия элементов считаются так же, как пропорции увеличения. Если базовые размеры флекс-элементов отличаются, то механизм усложняется. Подробно мы разберём его в следующем задании.

А пока снова поэкспериментируйте с коэффицентами в задании-загадке.

Вам нужно подобрать такие значения flex-shrink, чтобы итоговый размер элементов оказался таким же, как у коричневой и зелёной «линеек», и чтобы над красной «линейкой» ничего не было.

На красной линейке показан размер отрицательного пространства, которое распределяется при сжатии флекс-элементов.

Базовые размеры элементов и размеры флекс-контейнера вы узнаете из кода.

Подсказка: в простейшем решении коэффициенты будут целыми числами не больше 5.


  1. Цель 1 Задайте енотам значения flex-shrink так, чтобы их ширина стала равной ширине «линеек».

В этом задании можно менять только значения flex-shrink.

×

Расчёт итогового размера с flex-shrink [12/28]

Ниже описан механизм расчёта размеров элементов, когда места в контейнере не хватает:

1 шаг. Рассчитываем отрицательное пространство (ОП) во флекс-контейнере:

ОП = Ширина контейнера - Сумма базовых размеров элементов

2 шаг. Находим сумму произведений базовых размеров (СПБР) элементов на их коэффициенты сжатия:

СПБР = (Базовый размер1 * flex-shrink1) + (Базовый размер2 * flex-shrink2) + … + (Базовый размерn * flex-shrinkn)

3 шаг. Для каждого элемента считаем «нормированный коэффициент сжатия» (НКС), для чего произведение базового размера элемента на его коэффициент сжатия делим на СПБР:

НКС = (Базовый размер * flex-shrink) / СПБР

4 шаг. Базовый размер элемента уменьшаем на часть ОП пропорциональную НКС элемента:

Итоговый размер = Базовый размер - (НКС * ОП)

Получается, что доля отрицательного пространства, которую «впитает» элемент, зависит от двух факторов:

Именно поэтому в формулах присутствуют нормировки. А теперь снова попробуйте подобрать коэффициенты сжатия.


  1. Цель 1 Задайте енотам значения flex-shrink так, чтобы их ширина стала равной ширине «линеек».

В этом задании можно менять только значения flex-shrink.

×

flex-shrink и min-width [13/28]

Решение предыдущего задания: коэффициенты должны быть 1 и 1

Давайте рассчитаем размеры элементов из предыдущего задания и убедимся в правильности описанного алгоритма.

Отрицательное пространство = 200px - 100px - 300px = -200px

Сумма произведений размеров на коэффициенты = (1 * 100px) + (1 * 300px) = 400px

Нормированный коэффициент 1 элемента = (1 * 100px) / 400px = 0.25
Нормированный коэффициент 2 элемента = (1 * 300px) / 400px = 0.75

Итоговый размер 1 элемента = 100px - (200px * 0.25) = 50px
Итоговый размер 2 элемента = 300px - (200px * 0.75) = 150px

Есть несколько тонкостей, касающихся сжатия флекс-элементов:

И эти тонкости могут приводить к неожиданным эффектам, когда элементы выпадают из флекс-контейнера. Давайте поэкспериментируем.


  1. Цель 1 Коричневому Еноту .racoon-brown задайте нулевой коэффициент сжатия.
  2. Цель 2 Затем Зелёному Еноту .racoon-green задайте минимальную ширину 50px
  3. Цель 3 и внутренние отступы 25px.
×

Испытание: мастер коэффициентов [14/28]

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

В заблокированном HTML-коде заданы базовые размеры блоков, которые вам изменять нельзя. Но отталкиваясь от этих размеров, вы можете понять, в каком блоке использовать коэффициенты растяжения, а в каком — коэффициенты сжатия. И, конечно, подобрать значения коэффициентов.

Подсказка: итоговые размеры блоков кратны 50, а коэффициенты — небольшие целые числа.


×

Сокращённое свойство flex [15/28]

С помощью сокращённого свойства flex можно одновременно задать коэффициенты растягивания, сжатия и базовый размер флекс-элемента.

Свойство flex состоит из трёх компонентов, которые пишутся через пробел в следующем порядке: flex-grow, flex-shrink и flex-basis. В примере ниже два правила аналогичны:

.flex-item {
    flex: 1 2 300px;
}

.flex-item {
    flex-grow: 1;
    flex-shrink: 2;
    flex-basis: 300px;
}

Ещё у свойства flex есть особые значения: initial, auto, none. Также второй и третий компоненты необязательны. Ниже показаны различные значения свойства и их расшифровки.

flex: initial; -> flex: 0 1 auto;
flex: auto;    -> flex: 1 1 auto;
flex: none;    -> flex: 0 0 auto;
flex: 1 0;     -> flex: 1 0 0%;
flex: 1;       -> flex: 1 1 0%;
В некоторых браузерах неполные или особенные значения свойства flex интерпретируются с ошибками. Поэтому лучше задавать все три компоненты в значении этого свойства.

Попробуем это свойство на практике.


  1. Цель 1 С помощью свойства flex задайте всем скейтбордам .skate коэффициент растягивания 0, коэффициент сжатия 1, базовый размер 200px.
  2. Цель 2 Оранжевому еноту задайте коэффициент растягивания 1, коэффициент сжатия 0, базовый размер 200px,
  3. Цель 3 а затем смените коэффициент сжатия на 2.
×

Многострочный флекс-контейнер и flex-shrink [16/28]

Во всех примерах, рассмотренных раньше, флекс-контейнер был однострочным, ведь перенос флекс-элементов на новую строку по умолчанию запрещён — работает flex-wrap: nowrap;.

А как будут растягиваться и сжиматься элементы в многострочном контейнере, с flex-wrap: wrap;?

В таком контейнере свойство flex-shrink будет работать как обычно, но необходимость в нём будет возникать намного реже. Ведь при нехватке места в строке флекс-элементы будут переноситься на новую строку.

Но если появятся флекс-элементы, базовый размер которых больше размера флекс-контейнера, то такие элементы будут сжиматься и занимать целую строку. Наверное, это единственный случай, когда flex-shrink делает что-то полезное в многострочном контейнере.


  1. Цель 1 Увеличьте базовый размер всех скейтбордов до 500px.
  2. Цель 2 Разрешите перенос флекс-элементов на новую строку в блоке .spot.
  3. Цель 3 Затем задайте всем скейтам нулевой коэффициент сжатия.
×

Многострочный флекс-контейнер и flex-grow [17/28]

В отличие от flex-shrink, свойство flex-grow в многострочном флекс-контейнере срабатывает намного чаще и пользы приносит намного больше.

В каждой строке такого контейнера может быть свободное место и механизм перераспределения этого места работает построчно.

Поэтому возможность «растянуть» флекс-элементы, чтобы строки заполнялись по ширине полностью, будет возникать достаточно часто.


  1. Цель 1 Добавьте на полянку .spot последним скейт с Зелёным Енотом — див с классами skate и racoon-green.
  2. Цель 2 Блоку .spot задайте перенос флекс-элементов на новую строку,
  3. Цель 3 а затем зелёному еноту коэффициент растягивания 1.
  4. Цель 4 И, наконец, после Зелёного Енота добавьте скейт с Коричневым Енотом — див с классами skate и racoon-brown.
×

flex-basis: 100% и flex-wrap [18/28]

Познакомимся с интересным эффектом, который возникает при использовании базовых размеров в процентах.

Если задать базовый размер флекс-элемента 100% и при этом включить перенос элементов на новую строку, то элементы расположатся столбцом, хотя главная ось контейнера будет по-прежнему направлена слева направо.

Поэкспериментируем.


  1. Цель 1 Для всех скейтов задайте базовый размер флекс-элемента 100%,
  2. Цель 2 затем полянке .spot задайте перенос флекс-элементов на новую строку.
×

Заголовок с описанием на флексбоксах [19/28]

Мы рассмотрели теоретическую часть и приступаем к практической части этого курса. Давайте разберём на реальных элементах интерфейсов, в каких случаях бывает уместно использовать флексбокс.

Довольно распространённый ход в интерфейсе — блок с заголовком и небольшим уточняющим подзаголовком на одной строке. Заголовок находится в начале строки, а подзаголовок прижат к правому краю.

Если текст заголовка или подзаголовка сильно увеличится, то вёрстка не должна ломаться — тексты просто должны расположиться друг под другом.

Сверстать элемент с таким гибким поведением с помощью float или display: table не получится. Ведь нужно, чтоб блоки подписей одновременно и занимали свободное пространство, и чтобы их размеры зависели от текстового содержания, и чтобы в случае переполнения сетка перестраивалась.

Здесь нам поможет только флексбокс с flex-grow.

Для наглядности зададим текстовым блокам фоновый цвет и рамку, а в следующем задании уберём их.


  1. Цель 1 Для спанов внутри блока .card-title задайте фоновый цвет #c8dcff и сплошную рамку толщиной 1px и цветом #999999.
  2. Цель 2 Затем для .card-title задайте раскладку флексбокса
  3. Цель 3 и выравнивание флекс-элементов в конце поперечной оси.
  4. Цель 4 Блоку .card-title-main задайте коэффициент растягивания 1.
×

Заголовок с описанием, часть 2 [20/28]

А теперь давайте проверим, как сработает наша раскладка, если текста станет немного больше.

На случай «переполнения» зададим контейнеру перенос флекс-элементов на новую строку.


  1. Цель 1 Замените текст Кекс любит флекс на Инструктор Кекс и удивительный флекс,
  2. Цель 2 а затем блоку .card-title задайте перенос флекс-элементов на новую строку.
  3. Цель 3 Уберите у дочерних спанов .card-title рамку и фоновый цвет.
×

«Гибкое» меню с переполнением [21/28]

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

Напомним, что в прошлом варианте пункты равномерно распределялись внутри контейнера меню с помощью justify-content: space-around.

Новый вариант меню будет более адаптивным: пункты меню будут переноситься на следующую строку, если места будет не хватать. А ещё для достижении красивой симметрии пункты будут растягиваться, чтобы занимать весь контейнер меню. И снова нам поможет flex-grow.

Создадим базовую раскладку и зададим перенос строк.


  1. Цель 1 Для .menu задайте раскладку флексбокса,
  2. Цель 2 затем добавьте в меню последним пунктом ещё один див со ссылкой с текстом Акула.
  3. Цель 3 После этого задайте меню перенос флекс-элементов на новую строку.
×

«Гибкое» меню с переполнением, часть 2 [22/28]

Теперь остаётся задать элементам меню коэффициент растяжения и проверить, как будет вести себя меню, если мы решим изменить его ширину, либо добавить пункты.

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


  1. Цель 1 Для всех дочерних дивов в .menu задайте коэффициент растягивания 1,
  2. Цель 2 а затем добавьте в меню последним ещё один див со ссылкой с текстом Сом.
  3. Цель 3 После этого задайте блоку .menu ширину 300px,
  4. Цель 4 а затем 200px.
×

Поля ввода с динамической шириной [23/28]

Ещё один случай, когда может пригодиться флексбокс — поля ввода с динамической шириной. Требования к ним такие:

Решить эту задачу можно только при помощи флексбокса. Превратим контейнер поля ввода во флекс-контейнер, все элементы внутри него превратятся во флекс-элементы, базовый размер которых будет зависеть от их содержания — flex-basis: auto;. И останется только задать ненулевой коэффициент растягивания полям ввода.

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

Чтобы справиться с этими проблемами, надо задать всем элементам кроме полей ввода нулевой коэффициент сжатия, а самим полям ввода явно прописать минимальную ширину.

В этом задании в селекторах используется псевдокласс :not, который разбирается в курсе «Селекторы. Часть 2».

На момент написания курса в Safari и других WebKit-браузерах есть баг, из-за которого блоки могут позиционироваться некорректно.


  1. Цель 1 Блоку .input-container задайте раскладку флексбокса,
  2. Цель 2 а для .input задайте коэффициент растягивания 1.
  3. Цель 3 Затем уменьшите ширину .input-container до 200px,
  4. Цель 4 для .add-on задайте нулевой коэффициент сжатия,
  5. Цель 5 а для .input задайте минимальную ширину 50px.
×

Карточка курса [24/28]

Теперь давайте соберём на флексбоксе интерфейс с карточками курсов.

Флексбокс нужен, чтобы сделать этот блок адаптивным. Вы увидите, как гибко он адаптируется в следующих заданиях.

Начнём работу с отдельной карточки. Сделаем карточку флекс-контейнером и направим её главную ось сверху вниз. Это необходимо, чтобы в дальшнейшем гибко управлять внутренними блоками карточки.

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

В этой серии заданий мы будем добавлять временные обводки для элементов, чтобы вы лучше видели, что и как перестраивается в процессе работы. В конце задания можете удалять эти обводки, чтобы видеть промежуточный результат.

  1. Цель 1 Для .card задайте раскладку флексбокса,
  2. Цель 2 направление главной оси сверху вниз.
  3. Цель 3 Затем раскладку флексбокса задайте .card-meta,
  4. Цель 4 а для .card-category задайте коэффициент растягивания 1.
×

Карточка курса, часть 2 [25/28]

Пришло время добавить вторую карточку. Её код уже есть в разметке.

Для управления раскладкой карточек превратим их родительский блок в флекс-контейнер.

И теперь уже карточки стали одновременно и флекс-элементами, и флекс-контейнерами.


  1. Цель 1 Для блока .cards задайте раскладку флексбокса,
  2. Цель 2 затем карточкам .card задайте внешний отступ 10px.
×

Карточка курса, часть 3 [26/28]

Карточки выстроились в один ряд и теперь их высота одинакова. Это произошло потому, что их родительский элемент — флекс-контейнер с поперечным выравниванием stretch.

Сейчас мы сделаем так, чтобы кнопки «Пройти курс» выравнивались по нижнему краю карточки. Для этого:

Вспомните, как на первом шаге мы сделали карточки флекс-контейнерами. Без этого нельзя было бы растянуть вложенные блоки «в высоту» с помощью flex-grow.


  1. Цель 1 Для .card-content задайте коэффициент растягивания 1,
  2. Цель 2 затем раскладку флексбокса
  3. Цель 3 и направление главной оси сверху вниз.
  4. Цель 4 А для кнопки .card-button задайте внешний отступ сверху auto.
×

Много карточек [27/28]

На последнем шаге мы поработаем с раскладкой карточек.

Сделаем так, чтобы карточки переносились на новую строку, если им не хватает места в контейнере. А если свободное место на строке осталось, то карточки будут его занимать.

А чтобы было видно, как будут вести себя несколько карточек, мы добавили специальную обёртку с зумом.


  1. Цель 1 Разрешите перенос флекс-элементов в блоке .cards.
  2. Цель 2 Затем у карточки .card удалите максимальную ширину, задайте ей базовый размер 300px
  3. Цель 3 и коэффициент растягивания 1.
  4. Цель 4 После этого уменьшите ширину .cards до 700px. Обратите внимание, как перестроятся карточки.
×

Испытание: гибкий поток [28/28]

Теперь вы знаете достаточно, чтобы пройти финальное испытание.

В нём снова нужно создать гибкую раскладку, но на этот раз задача усложнилась. Теперь блоков стало больше, они расположены не в один ряд и у них разные размеры.

Вам понадобится подобрать базовые размеры, отступы, некоторые коэффициенты и пару других флексовых свойств.

Подсказка: как всегда отступы и базовые размеры (до перераспределения свободного места) кратны 5.

До встречи на следующих курсах. Продолжение следует!