Какой самый лучший способ понять Flexbox? Изучить основы и написать кучу разных штук. Именно этим мы и займемся.

Но сначала стоит кое-что уточнить:

  • Эта статья написана для разработчиков среднего уровня и предполагает, что вы уже имеете представление о Флексбоксах. Но…
  • Если вы в курсе, что такое CSS, но не имели дела с Флексбокс, то здесь находится исчерпывающий гид по технологии (статья в открытом доступе, необходимо, примерно, 45 минут на чтение).
  • А если вы не особо хороши в CSS, то я рекомендую вам Полное (Практическое) введение в CSS (платный курс, 74 лекции, английский язык).
  • Примеры из статьи можно реализовывать в произвольном порядке.
  • Флексбокс – всего лишь технология разметки. Реальные проекты одной только разметкой не ограничиваются.
  • Обозначения типа div.ohans означают что это элемент div с классом ohans.

Пример 1. Как сделать фотогалерею на Флексбокс

Разместить фотографии по строкам и столбцам на Флексбокс гораздо проще, чем многим кажется.
Рассмотрим простую сетку:

У нас есть main.gallery и 10 изображений в нем.
Убедимся, что main.gallery растягивается на весь доступный экран:

Кое-что об изображениях

По умолчанию все изображения inline-block элементы. У них есть ширина и высота. Они выстроятся в линию (только если они не слишком большие и могут все поместиться)

На старт

Сейчас наша галерея будет выглядеть следующим образом:

Размеры всех 10 изображений остались нетронутыми. При необходимости картинки переместятся на вторую строку. Послушные ребята =)

А теперь, на сцену выходит Флексбокс:

С этого момента поведение изображений изменилось. Из inline-block элементов они стали flex-items.
В результате применения Флексбокс к .gallery все картинки уместились в одну линию. Да еще и растянулись по вертикали, вот так:

Картинки теперь уместились все в одну линию, да еще и растянулись по вертикали. Жалкое зрелище =(

Все это результат стандартного поведения Флексбокс:

  1. Сплющить все дочерние элементы в одну линию и никуда их не переносить. Не самое лучшее решение для галереи, так что изменим его:

    Это разрешит перенос элементов на другую строку как и полагается

    Изображения перенесены

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

    Изменим его:

    Это защитит картинки от растягивания.
    Кроме того они выровнены относительно начала вертикальной оси:

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

Наша мощная флексбокс-галерея готова.

Преимущества использования Флексбокс

Сейчас преимущества использования Флексбокс не особо заметны, ведь тот же самый вид был и до его подключения.
Кроме легко получаемой адаптивности, преимущество флексбокс заключается в возможностях выравнивания.
Флекс-контейнер .gallery имеет несколько свойств для настройки выравнивания: flex-direction: row , justify-content: flex-start и align-items: flex-start.
Разметку галереи можно легко поменять поигравшись со следующим значением:

Теперь изображения идеально отцентрованы по горизонтали

Кроме того, картинки могут быть отцентрованы и по горизонтали и по вертикали .gallery.

А теперь изображения выровнены не только горизонтально, но и вертикально

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

Можете посмотреть на действующую Флексбокс галерею здесь.

Пример 2: Как сделать карточки на Флексбокс

Карточки очень популярны в интернете. Гугл, Твиттер, Пинтерест и прочие им подобные – все используют карточки.
В UI-дизайне карточка – это шаблон, объединяющий схожую информацию в адаптивный контейнер. Внешне он напоминает игральную карту.
Существует много хороших способов применения Карточек. Например, сетка с ценами.

Простая сетка цен

Давайте сделаем такую.

Разметка

Каждая карточка построена следующим образом:

У нас будет как минимум три карточки. Обернем их в div.cards

Теперь у нас есть родственные элементы.
В этом примере родственные элементы будут заполнять вcе доступное окно просмотра

Установка Флексбокс

Следующий код инициализирует Флексбокс в контексте блока .card

Если вы помните предыдущий пример, flex-wrap позволяет элементам flex-items располагаться в несколько линий, если они не помещаются в контейнер. Давайте зададим .card исходную ширину, используя Флексбокс

Это свойство устанавливает значения flex-grow и flex-shrink равными 0. Значение flex-basis будет равным 250px.
В том виде, что у нас есть сейчас карточки будут выровнены относительно начала страницы и растянуты по вертикали

Изображения выровнены относительно начала страницы

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

Поведение флекс-контейнеров по умолчанию

Вид наших карточек является результатом стандартного поведения флекс-контейнеров.
Карточки располагаются в начале страницы (top left) потому что у justify-content установлено значение flex-start.
Кроме того, карточки растянуты на всю высоту родительского элемента, потому что у свойства align-items значение по умолчанию stretch.

Изменение стандартных значений

Мы можем получить впечатляющий результат, изменив стандартные значения флексбокс свойств.
Смотрите сами:

align-items: flex-start; justify-content: center

align-items: flex-end; justify-content: center

align-items: center; justify-content: center

Мы можете посмотреть код примера на Codepen.

Пример 3: Как сделать сетку на Флексбокс

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

Что такое сетка?

Сетка – это набор прямых пересекающихся вертикальных и горизонтальных линий, использующихся для структурирования контента

Набор пересекающихся прямых (вертикальных, горизонтальных) направляющих линий

Если вам знакомы CSS-фреймворки, такие как Bootstrap, то вы точно использовали сетки раньше.

Давайте начнем с базовой сетки

Базовая сетка

Базовая сетка с равномерно расположенными столбцами

Некоторые свойства этой сетки:

  1. Ячейки клетки располагаются равномерно и растянуты по всей ширине линии.
  2. Все ячейки одинаковой высоты.

Этого очень легко добиться, используя Флейксбокс

Каждая строка .row будет флекс-контейнером.
Каждый элемент внутри .row станет флекс-элементом. Все флех-элементы равномерно распределяются по линии.
С точки зрения дизайна не важно, будет ли у нас три вложенных элемента

Или 6:

Или 12:

Решение

Чтобы получить этот результат необходимы всего два шага.

  1. Инициализировать Флексбокс
  2. Каждому flex-item позволить заполнять строку в равных пропорциях

Вот и все.

Объяснение решения

flex – это сокращенное имя свойства, объединяющего в себе flex-grow, flex-shrink и flex-basis.
flex: 1 – установлено только одно значение для свойства и оно задается свойству flex-grow.
flex-shrink и flex-basis будут равны 1 и 0

Ячейки определенного размера

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

Сетка с ячейками в 2 и в 3 раза большими остальных

Решение довольно просто.
Для конкретно этой ячейки необходимо изменить класс следующим образом:

Затем включите класс в разметку:

Ячейка с классом .row__cell–2 будет в два раза больше ячейки по умолчанию.

Для ячейки, занимающей треть свободного пространства код будет следующий:

Ячейки с определенным выравниванием

Благодаря Флекбоксу не нужно для каждой ячейки задавать определенное выравнивание, каждая может иметь свое собственное значение

Используйте следующее свойство:

Таким образом определенная ячейка будет выровнена по верху row.

После добавления класса .row_cell — top ячейка будет выровнена относительно верха строки

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

Ниже приведены другие примеры выравнивания

После добавления класса .row_cell — bottom ячейка будет выровнена относительно низа строки

 

После добавления класса .row_cell — center ячейка будет выровнена относительно центра строки

Общее выравнивание внутри строк

Выровнены могут быть не только ячейки, но и все дочерние элементы блока.
Измените класс следующим образом:

Все ячейки сетки выровнены относительно верха строки

Очень важно, чтобы измененный класс .row–top был добавлен элементу row или родительскому флекс-контейнеру.

Ниже приведены другие варианты выравнивания:

Все ячейки сетки выровнены относительно центра строки

 

Все ячейки сетки выровнены относительно низа строки

Вложенные сетки

Без лишних действий элементы row могут быть вложены друг в друга.

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

Здесь расположены готовые сетки.

Пример 3: Как сделать макет сайта, используя Флексбокс

Строительство макетов полностью на Флексбокс не особо одобряется сообществом разработчиков.
И, разделяя данное мнение, я все же считаю, что бывают ситуации, когда это допустимо.
Самый главный совет, который я могу вам дать: Используйте флексбокс, когда это имеет смысл.
Я объясню это на следующем примере.

Макет сайта “святой Грааль”

Самый наистандартнейший макет страницы на свете

Макет “святой Грааль” – хэдер, футер и 3 контейнера для контента

Есть два способа попытаться построить этот макет с помощью Flexbox.
Начнем с первого. Для него нужно разместить во флекс-контейнере header, footer, nav, article и aside.

Разметка

Так выглядит наша разметка:

Среди прочих, в стандартнейшей разметке есть особое правило: центральная колонка, article в разметке должна идти перед обоими сайдбарами nav и aside.

Article должен идти в разметке первым, но располагаться по центру макета

Подключаем флексбокс

Поскольку дочерние элементы должны идти сверху вниз, изменим стандартное направление флексбокс

  1. header и footer должны быть фиксированной ширины
  2. main должен занимать все свободное пространство в контейнере

Надеюсь, вы помните, что запись flex: 1 означает тоже самое что и flex-grow: 1, flex-shrink: 1 и flex-basis: 0

Это приведет к тому, что main вырастет и займет все доступное ему место

На этом этапе необходимо позаботиться о содержимом main – блоках article, nav и aside.
Сделаем main флекс-контейнером

А для nav и aside установим значение width

Убедимся, что article занимает все доступное ему пространство

Теперь article занимает все свободное место

Осталось сделать всего одну вещь. Поменяем значения flex-order, чтобы nav отображался первым

Готовый вариант

Свойство order используется, чтобы переопределить порядок flex-items.
Все элементы flex-items внутри контейнера отображаются в порядке возрастания значения order. Элемент с наименьшим значением будет отображаться первым.
По умолчанию значение order для всех flex-items равно 0.

Второе решение для макета

Предудышее решение использует flex-container для всего контейнера. Макет очень сильно зависит от flexbox.
Посмотрим на более разумный подход. Еще раз взглянем на результат, который должен у нас получиться.

Макет “святой Грааль”

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

Что означает, что флекс-контейнер необходим только для main.
Единственная сложность здесь заключается в том, что вам необходимо самим вычислить высоту блока main. Он должен занимать все свободное пространство между header и footer

Рассмотрим этот код. Он использует CSS функцию calc для того, чтобы вычислить высоту main.
Высота блока должна быть равна calc (100vh – высота хэдера – высота футера).
В предыдущем случае вы должны были задать фиксированную высоту футеру и хэдеру. Теперь вы поступаете таким же образом только с main.
Здесь лежит готовый результат.

Макет сайта в 2 колонки

Двухколоночный макет очень распространен. Их тоже очень легко строить на флексбокс.

Макет сайта в две колонки (сайдбар и основной контент)

Вот наша верстка:

Инициализируем флексбокс

Задаем блоку aside фиксированную ширину

И, наконец, убедимся, что main занимает все доступное пространство

Вот, в общем-то, и все, что нужно сделать.

Пример 5. Медиа-объекты на Флексбокс

Медиа-объекты повсюду: от твитов до постов в Фейсбуке.

Обычный пост в Твитере и Фейсбуке

Внимательно посмотрим на верстку

Как вы догадались, .media станет нашим основным флекс-контейнером

По умолчанию flex-items контейнера растягивается по вертикали, чтобы занять всю доступную высоту.
Убедимся, что .media-body заполняет все свободное пространство

Раздел слева занимает все свободное пространство экрана. Тело медиа-объекта занимает оставшееся горизонтальное пространство внутри медиа-объекта (белого цвета)

Давайте зафиксируем тянущийся бокс

Флекс-элементы теперь выровнены по началу медиа-объекта. Размер изображения по умолчанию и никаких странных растяжений =)

Вот и все.

Перевернутый медиа-объект

У перевернутого медиа-объекта изображение располагается с другой стороны (справа), относительно тела объекта

Нет никакой необходимости вносить изменения в html-код, чтобы повернуть медиа-объект.
Просто поменяем местами элементы flex-items вот так:

Теперь картинки будут располагаться после .media-body и media-heading

Вложенные медиа-объекты

Вы можете сделать вложенные медиа-объекты без изменения CSS-стилей, написанных ранее!

Все работает!

Медиа-объект, вложенный в медиа-объект

Unicode медиа-объекты

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

Я поместил сюда смайлик

Медиа-объект с эмодзи-смайлом

Чтобы получить этот результат мы просто заменили img на div. А вот здесь вы можете подсмотреть юникоды некоторых смайликов-эмодзи.

Медиа-объект с HTML

А еще вы можете использовать html-объекты как в примере ниже

В качестве html-объекта в примере используется ☎ и на картинке вы можете видеть результат

&phone

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

Пример 6. Как сделать компоненты форм на Флексбокс

Очень сложно найти сайты, которые не используют формы в том или ином виде

Поля формы могут иметь не только место для ввода, но и другие элементы

Посмотрим на код

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

Инициализируем флексбокс-контекст

Убедимся, что поле занимает все доступное ему пространство

Наконец, по своему желанию, вы можете добавить стили для кнопок и блоков с текстом

Код из этих примеров есть на Codepen.

Пример 7. Как сделать макет мобильного приложения на Флексбокс

В этом примере рассмотрим построение вот такого макета мобильного приложения.

Макет мобильного приложения, который мы соберем на Флексбокс

Но этот пример будет немного отличаться от предыдущих. Я объясню процесс построения макета при помощи псевдокода, а вы его сделаете.
Считайте это практикой, чтобы вы не расслаблялись.

Шаг 1.
Отделите макет от картинки iPhone и получите следующее:

Скелет макета

Шаг 2.
Определите body как флекс-контейнер.

Инициируйте Флексбокс

Шаг 3.
По умолчанию flex-direction контейнера установлен как row. Но в нашем случае, нужен column.

Измените порядок дочерних флекс-элементов

Шаг 4.
Задайте элементам 1 и 3 фиксированные значения высоты height: 50px.

Шаг 5.
Элемент 2 должен занимать все доступное пространство. Используйте свойство flex-grow или короткую запись flex; 1.

Шаг 6.
Наконец, определите каждый блок контента медиа-объектом, как в предыдущем примере.

Сделайте блоки контента медиа-объектами

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

Заключение

По моему опыту работы в UI рано или поздно вы столкнетесь с одним из вышеперечисленных примеров.

А теперь идите и напишите что-нибудь шикарное! 🙂

Оригинал статьи


 

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Рубрики: CSSHTML

15 комментариев

Malikero · 04.01.2018 в 22:19

Всем привет! С новым годом, желаю всем счастья, здоровья и удачи в этом году!

Отличный у вас сайт, многие посты очень познавательные.

Joni · 16.02.2018 в 18:15

Здравствуйте. Помогите, пожалуйста, выровнять зеленые блоки по красной линии.http://joxi.ru/gmvzWdDtxWRwdm

    keynikel · 16.02.2018 в 18:25

    Добрый день. К сожалению, не видя кода я не могу вам помочь. Если вы заведете песочницу на codepen, к примеру, и дадите ссылку, я с удовольствием взгляну и попробую что-нибудь сделать.

Dmitry · 05.03.2018 в 21:06

Невероятная полезная статья. Спасибо, за предостережение о верстке основных компонентов сайта.

    keynikel · 06.03.2018 в 10:51

    Рада была помочь. Оставайтесь с нами 🙂

Stepan · 02.07.2018 в 06:45

В начале статьи идет речь о галерее (в качестве примера). А вот как сделать чтоб выравнивание элементов было по обоим краям , как это происходит при justify-content: space-between;, но при этом последняя (незаполненная) строчка не растягивалась на весь контейнер, а элементы в ней располагались с такимже интервалом как и в заполненной строке, начиная с левого края?

    keynikel · 20.07.2018 в 10:36

    Здравствуйте. Верно ли я понимаю, что вы хотите, грубо говоря, чтобы первая строка вела себя как при justify-content: space-between, а вторая незаполненная, как при justify-content: flex-start?
    К сожалению, возможностями flex так сделать не получится. Тут нет как таковых “строк”, и поведение определяется для всего набора элементов, независимо, в одной они строке, в двух или пятнадцати.
    Для того, что вы хотите сделать, думаю, вам больше подойдут CSS Grid.

Анатолий · 18.07.2018 в 15:10

Подскажите, по-вашему мнению правильно ли использовать flexbox-разметку, как вот тут paratapok.ru/frontend/5148_css3-flexbox/ (в самом низу страницы), для верстки макетов из psd? Правильно ли так делать?

    keynikel · 20.07.2018 в 10:32

    Добрый день.
    Вообще, я считаю, что для раскладок лейаутов уже можно и нужно использовать гриды. Это их основное предназначение, у них есть отличные фишки, упрощающие жизнь. Флексы же лучше использовать для стилизации каких-то внутренних блоков.
    С другой стороны, все, что напрямую не запрещено спецификацией – разрешено, поэтому, если вы не знаете гриды, то учите используйте флексы

Michaeldox · 19.07.2018 в 15:01

Актуально. Подскажите, где я могу найти больше информации по этому вопросу?

    keynikel · 20.07.2018 в 10:27

    Добрый день. Могу посоветовать курсы htmlacademy (из платных) или посмотреть примеры кода на Scrimba
    Материалов же просто “на почитать” в сети предостаточно.
    Удачи!

Иггорь · 26.05.2019 в 22:44

Хорошо продемонстрировано назначения флексов, а самое главное описано откуда у них ноги растут, а именно из сеток, просто долго разбирался с флэксами без сетки – это вызывало затруднения , а теперь все очень понятно.Спасибо!

Песчаный Воин · 10.03.2020 в 15:24

Добрый день!
Пытаюсь разобраться с тестовым сайтом на поддомене следуя вашей статье и ничего не получается. Какой-то момент упускаю.
https://test.voin-zen.ru/
На основном сайте я все сделал быстро и просто, хочу добиться такого же результат с помощью flexbox.
https://voin-zen.ru/

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

.news-list-flex-cards {
display: flex;
flex-wrap: wrap;
flex-direction:row;
align-items: flex-start;
justify-content: space-between;
min-height: 100vh;
}

.news-item-flex-card {
flex: 0 0 250px;

}

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

a.news-a {
display:block;
width:299px;
height:189px;
overflow:hidden;

}
a.news-a img {
object-fit: cover;
width: 100%;
height: 189px;
}

    keynikel · 10.03.2020 в 16:17

    Добрый день!
    У вас в шаблоне есть div c id = “container”, который определяет ширину контентной части страницы. Некий шаблон задает ему width, равный 980px, который все и портит.
    Поведение флексовых потомков напрямую зависит от поведения родителя, но, если родитель не меняется, то и потомкам делать нечего. Замените стиль на max-width, если вам нужно, чтобы область начала уменьшаться.

writeessay · 11.05.2018 в 03:25

Very good posts. With thanks.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Похожие записи

CSS

Подсказки о доступности подсказок

Возможно, совсем недавно вы читали статью Адриана Розелли “Отскребая соженный тост” или “Обсуждение подсказок” Криса Койлера. Или, возможно, изучали гит-репозитории “Стандартного UI-элемента – тост” и ветку его обсуждения в WICG. В конце концов, вы можете Подробнее…

CSS

Плейсхолдеры в полях делают больно

Статья достаточно старая (2014 год), но разработчики форм косячат снова и снова. В общем, не баян, а классика Если коротко: плейсхолдеры вместо ярлыков увеличивают количество ошибок и нагружают память пользователей. А еще, мешают людям с Подробнее…

CSS

Блок со скошенными углами на CSS

Несколько дней назад мы опубликовали скошенный hero-компонент, модификатор простого блока. Его можно использовать для дизайна, основанного исключительно на прямоугольных сечениях. Летс ду ит! Есть видеоурок, где объясняются различные способы реализации скосов у блока (а тут Подробнее…

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: