Оригинал: http://tutorialzine.com/2017/03/css-grid-vs-flexbox/
Перевод: Влад Мержевич
Ещё недавно макет для всех страниц HTML верстался с помощью таблиц, float и других свойств CSS, которые не очень хорошо подходят для стилизации сложных веб-страниц.
Затем появился Flexbox — режим вёрстки, который был специально разработан для создания надёжных адаптивных страниц. Flexbox упростил правильное выравнивание элементов и их содержимого и теперь является предпочтительной системой CSS для большинства веб-разработчиков.
Но теперь у нас есть новый претендент на титул за звание «лучшей системы для вёрстки макетов HTML» (название титула ещё в процессе разработки»). Это CSS Grid и в ближайшее время эта система будет доступна в браузерах Firefox 52 и Chrome 57, а вскоре, как я надеюсь, и в других браузерах.
Базовый макет
Чтобы понять, каково это — создавать макеты на каждой системе, мы сделаем одну и ту же HTML-страницу дважды — один раз с помощью Flexbox, а затем на CSS Grid. Вы можете скачать оба проекта отсюда или проверить их в этой демонстрационной версии.

Уменьшенный макет веб-страницы
Дизайн довольно простой — он состоит из выровненного по центру контейнера, внутри которого у нас есть шапка, основной раздел, боковая панель и подвал. Вот главные «испытания», которые мы должны провести, сохраняя CSS и HTML по возможности чистыми:
- Разместить четыре основных раздела макета.
- Сделать страницу адаптивной (боковая панель опускается ниже основного содержимого на маленьких экранах).
- Выровнять содержимое шапки — навигация слева, кнопка справа.
Как вы можете видеть, ради сравнения мы оставили всё максимально простым. Начнём с первого испытания.
Испытание 1. Размещение разделов страницы
Решение на Flexbox
Добавляем display: flex к контейнеру и задаём направление дочерних элементов по вертикали. Это позиционирует все разделы друг под другом.
.container { display: flex; flex-direction: column; }
Теперь нам нужно сделать так, чтобы основной раздел и боковая панель располагались рядом. Поскольку flex-контейнеры обычно однонаправлены, нам нужно добавить дополнительный элемент.
<header></header> <div class="main-and-sidebar-wrapper"> <section class="main"></section> <aside class="sidebar"></aside> </div> <footer></footer>
Затем мы устанавливаем этому элементу display: flex и flex-direction с противоположным направлением.
.main-and-sidebar-wrapper { display: flex; flex-direction: row; }
Последний шаг — задать размеры основного раздела и боковой панели. Мы хотим, чтобы основное содержимое было в три раза шире боковой панели, что несложно сделать с помощью flex или процентов.
.main { flex: 3; margin-right: 60px; } .sidebar { flex: 1; }
Как вы можете видеть, Flexbox сделал всё хорошо, но нам кроме этого понадобилось довольно много свойств CSS плюс дополнительный элемент HTML. Давайте посмотрим, как будет работать CSS Grid.
Решение на CSS Grid
Существует несколько вариантов использования CSS Grid, но мы воспользуемся синтаксисом grid-template-areas, как наиболее подходящего для наших целей.
Сперва мы определим четыре grid-area, по одному на каждый раздел страницы:
<header></header> <!-- Обратите внимание, что в этот раз нет дополнительных элементов --> <section class="main"></section> <aside class="sidebar"></aside> <footer></footer>
header { grid-area: header; } .main { grid-area: main; } .sidebar { grid-area: sidebar; } footer { grid-area: footer; }
Теперь мы можем настроить нашу сетку и определить расположение каждой области. Вначале код может показаться довольно сложным, но как только вы познакомитесь с системой сетки, он становится проще для понимания.
.container { display: grid; /* Определяем размер и число колонок нашей сетки. Единица fr работает подобно Flexbox: колонки делят свободное пространство в строке согласно их значениям. У нас будет две колонки — первая в три раза больше второй. */ grid-template-columns: 3fr 1fr; /* Связываем сделанные ранее области с местами в сетке. Первая строка — шапка. Вторая строка делится между основным разделом и боковой панелью. Последняя строка — подвал. */ grid-template-areas: "header header" "main sidebar" "footer footer"; /* Интервал между ячейками сетки будет 60 пикселей */ grid-gap: 60px; }
Вот и всё! Наш макет теперь будет соответствовать указанной выше структуре и мы его настроили так, что нам не придётся иметь дело с margin или padding.
Испытание 2. Делаем страницу адаптивной
Решение на Flexbox
Выполнение этого шага строго связано с предыдущим. Для решения на Flexbox нам придётся изменить flex-direction и отрегулировать margin.
@media (max-width: 600px) { .main-and-sidebar-wrapper { flex-direction: column; } .main { margin-right: 0; margin-bottom: 60px; } }
Наша страница довольно простая, поэтому в медиа-запросе мало работы, но в более сложном макете придётся много чего переделывать.
Решение на CSS Grid
Поскольку мы уже определили grid-areas, нам просто нужно переопределить их порядок в медиа-запросе. Мы можем использовать ту же настройку колонок.
@media (max-width: 600px) { .container { /* Выравнивание областей сетки для мобильного макета */ grid-template-areas: "header header" "main main" "sidebar sidebar" "footer footer"; } }
Или можем переопределить весь макет с нуля, если считаем, что это решение чище.
@media (max-width: 600px) { .container { /* Переделываем сетку в одноколоночный макет */ grid-template-columns: 1fr; grid-template-areas: "header" "main" "sidebar" "footer"; } }
Испытание 3. Выравнивание компонентов шапки
Наша шапка включает некоторые ссылки навигации и кнопку. Мы хотим, чтобы навигация была слева, а кнопка справа. Ссылки внутри навигации должны быть выровнены относительно друг друга.
Решение на Flexbox
<header> <nav> <li><a href="#"><h1>Logo</h1></a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> </nav> <button>Button</button> </header>
Мы уже делали похожий макет на Flexbox в одной из наших старых статей — Простейший способ создания адаптивной шапки. Техника довольно простая:
header { display: flex; justify-content: space-between; }
Теперь список навигации и кнопка выровнены правильно. Осталось только разместить пункты внутри <nav> по горизонтали. Проще это сделать с помощью display: inline-block, но поскольку мы собираемся целиком использовать Flexbox, применим решение только для него:
header nav { display: flex; align-items: baseline; }
Только две строки! Совсем неплохо. Давайте посмотрим, как с этим справится CSS Grid.
Решение на CSS Grid
Чтобы разделить навигацию и кнопку, мы должны добавить display: grid к header и настроить двухколоночную сетку. Нам также понадобятся две дополнительные строки в CSS, чтобы позиционировать всё на соответствующих границах.
header{ display: grid; grid-template-columns: 1fr 1fr; } header nav { justify-self: start; } header button { justify-self: end; }
Что касается ссылок в одну строку внутри навигации, у нас не получилось сделать это корректно с CSS Grid. Вот как выглядит наша лучшая попытка:
Ссылки строчные, но они не могут быть выровнены правильно, поскольку не существует варианта baseline, как у align-items. Мы также должны определить ещё одну вложенную сетку.
header nav { display: grid; grid-template-columns: auto 1fr 1fr; align-items: end; }
Понятно, что CSS Grid не справилась с этой частью макета, но это и не удивительно — основное внимание уделяется выравниванию контейнеров, а не содержимому внутри них. Эта система не для нанесения последних штрихов.
Выводы
Если вы прочитали статью целиком (а это отличная работа!), выводы не должны вас удивить. На деле нет лучшей системы — и Flexbox и CSS Grid хороши по своему и должны использоваться совместно, а не как альтернатива друг другу.
Для тех из вас, кто перепрыгнул непосредственно к выводам этой статьи (не волнуйтесь, мы тоже так делаем), вот краткий итог сравнения:
- CSS Grid отлично подходит для создания большой картины. Эта система облегчает управление макетом страницы и даже может иметь дело с нестандартным и асимметричным дизайном.
- Flexbox отлично подходит для выравнивания содержимого внутри элементов. Используйте эту систему для размещения мелких деталей дизайна.
- Используйте CSS Grid для двумерных макетов (строк И колонок).
- Flexbox лучше работает только в одном измерении (со строками ИЛИ с колонками).
- Нет причин применять только CSS Grid или только Flexbox. Изучайте их и используйте совместно.
htmlbook.ru
Flexbox так и напрашивается на то, чтобы создавать по нему визуальные шпаргалки. Сегодня мы предлагаем вам перевод статьи Скотта Домеса «Как работает Flexbox – в больших, ярких анимированных гифках», своего рода наглядное пособие.
Flexbox обещает избавить нас от недостатков стандартного CSS (таких как вертикальное выравнивание).
Следует признать, что Flexbox действительно справляется с поставленной задачей. Однако освоение этой новой модели может вызвать некоторые затруднения.
Попробуем продемонстрировать, как функционирует Flexbox, позволяя создавать более совершенные макеты страниц.
Основной принцип Flexbox — гибкие и интуитивные макеты страниц. Это достигается за счет того, что контейнеры сами равномерно распределяют свои дочерние элементы — включая их размер и пространство между ними.
Идея, в принципе, неплохая. Но давайте посмотрим, как это реализуется на практике. В этой статье мы рассмотрим 5 основных свойств Flexbox. Мы опишем, для чего они нужны, как вы можете их использовать, и к каким результатам они в итоге приводят.
Свойство № 1: Display: Flex
Вот наша интернет-страница в качестве примера:

У вас есть четыре разноцветных блока различных размеров в сером контейнере. На данный момент для каждого блока по умолчанию определено display: block. Каждый квадрат таким образом занимает всю ширину своей линии.
Чтобы начать работу с Flexbox, вам надо превратить свой контейнер в flex-контейнер. Это делается следующим образом:
#container { display: flex; }
На первый взгляд изменения незначительны — ваши блоки отображаются теперь в инлайновом виде, только и всего. Между делом вы сделали большой шаг. Вы создали для своих блоков так называемый flex-контекст.
Теперь вы можете размещать их в этом контексте — это намного проще, чем при работе с традиционным CSS.
Свойство № 2: Flex Direction
У flexbox-контейнера есть две оси: главная ось и перпендикулярная ось, которые по умолчанию выглядят следующим образом:
По умолчанию flex-элементы выстраиваются вдоль главной оси, слева направо. Поэтому ваши квадраты по умолчанию будут располагаться в горизонтальный ряд, как только вы примените display: flex. Flex-direction, однако, позволяет вращать главную ось.
#container { display: flex; flex-direction: column; }
Следует подчеркнуть: flex-direction: column не располагает квадраты на перпендикулярной оси вместо главной оси. Это свойство меняет направление самой главной оси из горизонтального в вертикальное.
У flex-direction есть и другие значения: row-reverse и column-reverse.
Свойство № 3: Justify Content
Justify Content задаёт выравнивание элементов по главной оси.
Здесь различие главной и перпендикулярной осей следует рассмотреть подробнее. Сначала вернемся к flex-direction: row.
#container { display: flex; flex-direction: row; justify-content: flex-start; }
У Justify Content есть пять значений:
- Flex-start
- Flex-end
- Center
- Space-between
- Space-around
Space-around и space-between наименее интуитивны. Space-between выравнивает элементы так, чтобы они располагались на одинаковом расстоянии относительно друг друга, но не относительно контейнера.
Space-around задает одинаковый отступ вокруг элемента со всех сторон. Это означает, что пространство между крайними квадратами и контейнером вдвое меньше, чем пространство между двумя квадратами (все отступы имеют одинаковую величину и не накладываются друг на друга, соответственно, промежуток между квадратами получается двойной).
И напоследок: помните, что justify-content выравнивает элементы вдоль главной оси, а flex-direction меняет положение самой главной оси. Это будет важно, когда вы перейдете к…
Свойство № 4: Align Items
Если вы освоили justify-content, align-items не вызовет у вас затруднений.
В то время как justify-content применяется для главной оси, align-items задаёт выравнивание элементов по перпендикулярной оси.
Зададим для flex-direction изначальное значение row, чтобы оси выглядели следующим образом.
Затем перейдем к командам align-items.
- flex-start
- flex-end
- center
- stretch
- baseline
Первые три действуют так же, как и для justify-content, так что с ними все просто.
Следующие две несколько отличаются.
При заданном значении stretch элементы занимают всё свободное пространство по перпендикулярной оси. Если задано baseline, основания тегов абзаца выравниваются.
(Для align-items важно следующее: при значении stretch надо задать высоту квадратов автоматически, иначе она будет переопределять ширину.)
Что касается baseline, имейте в виду: если вы убираете теги абзаца, то будут выравниваться основания квадратов, как в примере:
Чтобы лучше продемонстрировать функционирование главной и перпендикулярной осей, скомбинируем justify-content и align-items и посмотрим, как значение center влияет на каждую из команд flex-direction:
При row квадраты выравниваются вдоль горизонтальной главной оси. При column они располагаются вдоль вертикальной главной оси.
Даже если квадраты центрированы и вертикально и горизонтально в обоих случаях, эти две команды не взаимозаменяемы!
Свойство № 5: Align Self
Align Self позволяет вручную управлять выравниванием одного конкретного элемента.
Это свойство аннулирует значения align-items для выбранного квадрата. Все свойства — те же, но по умолчанию выставляется auto, при котором значения аналогичны align-items контейнера.
#container { align-items: flex-start; } .square#one { align-self: center; } // Only this square will be centered.
Давайте посмотрим, как это будет выглядеть. Вы применяете align-self к двум квадратам, а для остальных применяете align-items: center и flex-direction: row.
Заключение
Хотя мы только поверхностно затронули работу с Flexbox, рассмотренные команды позволят вам осуществлять большинство базовых выравниваний и вертикальное выравнивание элементов.
Спасибо за внимание!
habr.com
Свойства flex-контейнера
- row – слева направо (по умолчанию);
- row-reverse – справа налево;
- column – сверху вниз;
- column-reverse – снизу вверх.
- nowrap – flex-элементы выстраиваются в одну строку, если не помещаются в контейнер, то выходят за его границы (по умолчанию);
- wrap – flex-элементы выстраиваются в несколько строк, если не помещаются в одну;
- wrap-reverse – похоже на wrap, но перенос происходит снизу вверх.
Например, flex-flow: column wrap;
- flex-start – flex-элементы прижимаются к началу главной оси (по умолчанию);
- flex-end – flex-элементы прижимаются к концу главной оси;
- center – flex-элементы выравниваются по центру главной оси;
- space-between – flex-элементы распределяются вдоль главной оси, при этом первый элемент прижат к началу оси, а последний — к концу;
- space-around – flex-элементы распределяются вдоль главной оси, при этом свободное пространство делится поровну между элементами. Но стоит отметить, что промежутки суммируются и расстояние между элементами в два раза больше, чем расстояние между краями контейнера и крайними элементами.
Пример
- flex-start – flex-элементы прижимаются к началу поперечной оси (по умолчанию);
- flex-end – flex-элементы прижимаются к концу поперечной оси;
- center – flex-элементы выравниваются по центру поперечной оси;
- baseline – flex-элементы выравниваются по своей базовой линии. Базовая линия – это воображаемая линия, проходящая по нижнему краю символов без учёта свисаний, таких как у букв «д», «р», «ц», «щ»;
- stretch – flex-элементы растягиваются, занимая все доступное место по поперечной оси. Но если для элементов задана высота, то stretch будет проигнорирован.
- flex-start – строки flex-элементов прижимаются к началу поперечной оси (по умолчанию);
- flex-end – строки flex-элементов прижимаются к концу поперечной оси;
- center – fстроки flex-элементов выравниваются по центру поперечной оси;
- space-between – строки flex-элементов распределяются вдоль поперечной оси, при этом первая строка прижата к началу оси, а последняя — к концу;
- space-around – строки flex-элементов распределяются вдоль поперечной оси, при этом свободное пространство делится поровну между строками. Но стоит отметить, что промежутки суммируются и расстояние между строками в два раза больше, чем расстояние между краями контейнера и крайними строками.
- stretch – строки flex-элементов растягиваются, занимая все доступное место по поперечной оси. Но если для элементов задана высота, то stretch будет проигнорирован.
Пример
Это свойство не работает для однострочного flex-контейнера.
Свойства flex-элементов |
|
order | Определяет порядок следования отдельно взятого flex-элемента внутри flex-контейнера. Задается целым числом. По умолчанию равно 0, тогда элементы следуют друг за другом в порядке естественного потока. Значение order задает вес позиции элемента в последовательности, а не абсолютную позицию.
Пример |
flex-basis | Определяет базовый размер flex-элемента перед распределением пространства в контейнере. Может быть задан в px, %, em и остальных единицах измерения. По сути это своего рода отправная точка, относительно которой происходит растягивание или сжатие элемента. Значение по умолчанию – auto, при этом размер элемента зависит от размера внутреннего контента.
В спецификации CSS Flexible Box Layout Module Level 1 приведена наглядная диаграмма для трех flex-элементов со значениями flex-grow 1, 1, 2 соответственно: Пример flex-basis: 0 Пример flex-basis: auto |
flex-grow | Определяет, какую долю свободного места внутри контейнера добавит к своему базовому размеру flex-элемент. Задается целым числом, служащим пропорцией. По умолчанию равно 0. Если у всех элементов flex-grow: 1, то все они будут одинакового размера. Если одному flex-элементу задать значение 2, то к его базовому размеру добавится в два раза больше, чем к другим.
Пример |
flex-shrink | Определяет, на сколько в случае недостатка места будет уменьшаться flex-элемент относительно уменьшения соседних элементов внутри flex-контейнера. Задается целым числом, служащим пропорцией. По умолчанию равно 1. Если одному flex-элементу задать значение flex-shrink: 2, то из его базового размера вычтется в два раза больше, чем из других, если контейнер меньше, чем сумма базовых размеров входящих в него элементов.
Пример |
flex | Определяет сразу три параметра: flex-grow, flex-shrink, flex-basis. Например, flex: 1 1 200px; |
align-self | Переопределяет выравнивание, заданное по умолчанию или в align-items, для конкретного flex-элемента. Возможные значения:
Пример |
Особенности применения Flexbox на практике
1. Выравнивание по правому краю
Чтобы прижать заголовок сайта влево, а номер телефона вправо, то заголовку надо задать flex: 1.
.header { display: flex; } .header .title { flex: 1; }
Если же по какой-то причине тянуть заголовок на всю ширину нельзя, то блоку с номером телефона надо задать margin-left: auto.
.header { display: flex; } .header .phone { margin-left: auto; }
Для наглядности блокам добавлены пунктирные границы.
2. Сжатие блоков с длинными словами
Есть блок, состоящий из названия услуги и номера телефона, по которому ее можно заказать. Описание услуги использует столько пространства, сколько может, а затем переходит на следующую строку.
.serv { display: flex; } .serv .description { font-size: 30px; } .serv .call { margin-left: auto; width: 120px; text-align: center; align-self: center; }
Теперь в описании услуги появляется длинное слово.
Красной границей обозначена ширина смартфона, и если переполнение скрыто (overflow: hidden), то кнопку «Оставить заявку» никто не увидит и заказать услугу не сможет.
Дело в том, что минимальная ширина (min-width) блока description по умолчанию имеет значение auto, что в данном случае равняется ширине слова «пенополистиролбетонных». Значит, flex-элемент не может быть уже, чем это слово.
Решение данной проблемы – указать для flex-элемента нулевую минимальную ширину (min-width: 0). Теперь элемент может быть уже, чем его содержимое. А длинное слово можно просто перенести.
.serv { display: flex; } .serv .description { font-size: 30px; min-width: 0; word-wrap: break-word; } .serv .call { margin-left: auto; width: 120px; text-align: center; align-self: center; }
3. Гарантированная ширина
Кнопка «Оставить заявку» по ширине совсем не 120px, как было указано в стилях. Дело в том, что по умолчанию flex-элемент сжимается, если места недостаточно.
Следующие три комбинации разработчики Flexbox посчитали наиболее часто используемыми и присвоили им ключевые слова:
flex: 0 1 auto | Элемент сжимается, если места не хватает, но не тянется шире, чем ему надо. Соответствует flex: initial и является значением по умолчанию. |
flex: 1 1 auto | Элемент сжимается, если места не хватает и тянется для заполнения всего доступного пространства. Соответствует flex: auto. |
flex: 0 0 auto | Элемент не меняет свои размеры. Соответствует flex: none. |
Итак, чтобы ширина кнопки «Оставить заявку» равнялась именно 120px, надо ей добавить flex: none.
.serv { display: flex; } .serv .description { font-size: 30px; min-width: 0; word-wrap: break-word; } .serv .call { margin-left: auto; width: 120px; flex: none; text-align: center; align-self: center; }
4. Несколько полезных замечаний
Надо не забывать, что:
- вертикальное выравнивание (vertical-align) не влияет на flex-элемент,
- для flex-элементов следует полностью избегать использования margin или padding в %,
- отступы (margin) соседних flex-элементов никогда не объединяются,
- z-index на flex-элементе работает даже при position: static,
- для вертикального выравнивания flex-элементов с различным размером шрифта лучше установить align-items: baseline.
htmlweb.ru
Разница между «flex» и «inline-flex»
Короткий ответ:
Один из них встроен, а другой в основном отвечает как элемент блока (но имеет некоторые из его собственных отличий).
Более длинный ответ:
Inline-Flex — встроенная версия flex позволяет элементу и его дочерним элементам иметь свойства гибкости, сохраняя при этом постоянный поток документа/веб-страницы. В принципе, вы можете разместить два встроенных гибких контейнера в одной строке, если ширина была достаточно маленькой, без какого-либо избыточного стиля, чтобы позволить им существовать в той же строке. Это очень похоже на «встроенный блок».
Flex. Контейнер и его дети имеют свойства гибкости, но контейнер резервирует строку, поскольку она вынимается из нормального потока документа. Он реагирует как элемент блока с точки зрения потока документов. Два контейнера flexbox не могли существовать в одной строке без лишнего стилей.
Проблема, с которой вы можете столкнуться
Из-за элементов, которые вы указали в своем примере, хотя я предполагаю, я думаю, что вы хотите использовать flex для отображения элементов, перечисленных в строке по очереди, но продолжайте видеть элементы бок о бок.
Причина, по которой у вас возникают проблемы, заключается в том, что flex и inline-flex имеют свойство по умолчанию «flex-direction», заданное как «row». Это отобразит детей бок о бок. Изменение этого свойства на «столбец» позволит вашим элементам стекаться и резервировать пространство (ширину), равное ширине его родительского элемента.
Ниже приведены некоторые примеры, показывающие, как работает flex vs inline-flex, а также краткое описание того, как работают встроенные и блокирующие элементы…
display: inline-flex; flex-direction: row;
Fiddle
display: flex; flex-direction: row;
Fiddle
display: inline-flex; flex-direction: column;
Fiddle
display: flex; flex-direction: column;
Fiddle
display: inline;
Fiddle
display: block
Fiddle
Кроме того, отличный справочный документ: Полное руководство по flexbox — css трюкам
qaru.site
Основы
Т.к. flexbox — это целый модуль, а не просто единичное свойство, он объединяет в себе множество свойств. Некоторые из них должны применяться к контейнеру (родительскому элементу, так называемому flex-контейнеру), в то время как другие свойства применяются к дочерним элементам, или flex-элементам.
Если обычный лейаут основывается на направлениях потоков блочных и инлайн-элементов, то flex-лейаут основывается на «направлениях flex-потока». Ознакомьтесь с этой схемой из спецификации, разъясняющей основную идею flex-лейаутов.
В основном элементы будут распределяться либо вдоль главной оси (от main-start до main-end), либо вдоль поперечной оси (от cross-start до cross-end).
- main-axis — главная ось, вдоль которой располагаются flex-элементы. Обратите внимание, она необязательно должна быть горизонтальной, всё зависит от свойства
flex-direction
(см. ниже). - main-start | main-end — flex-элементы размещаются в контейнере от позиции main-start до позиции main-end.
- main size — ширина или высота flex-элемента в зависимости от выбранной основной величины. Основная величина может быть либо шириной, либо высотой элемента.
- cross axis — поперечная ось, перпендикулярная к главной. Её направление зависит от направления главной оси.
- cross-start | cross-end — flex-строки заполняются элементами и размещаются в контейнере от позиции
cross-start
и до позицииcross-end
. - cross size — ширина или высота flex-элемента в зависимости от выбранной размерности равняется этой величине. Это свойство совпадает с
width
илиheight
элемента в зависимости от выбранной размерности.
Свойства
display: flex | inline-flex;
Применяется к: родительскому элементу flex-контейнера.
Определяет flex-контейнер (инлайновый или блочный в зависимости от выбранного значения), подключает flex-контекст для всех его непосредственных потомков.
display: other values | flex | inline-flex;
Имейте в виду:
- CSS-столбцы
columns
не работают с flex-контейнером float
,clear
иvertical-align
не работают с flex-элементами
flex-direction
Применяется к: родительскому элементу flex-контейнера.
Устанавливает главную ось main-axis
, определяя тем самым направление для flex-элементов, размещаемых в контейнере.
flex-direction: row | row-reverse | column | column-reverse
row
(по умолчанию): слева направо дляltr
, справа налево дляrtl
;row-reverse
: справа налево дляltr
, слева направо дляrtl
;column
: аналогичноrow
, сверху вниз;column-reverse
: аналогичноrow-reverse
, снизу вверх.
flex-wrap
Применяется к: родительскому элементу flex-контейнера.
Определяет, будет ли контейнер однострочным или многострочным, а также направление поперечной оси, определяющей направление, в котором будут располагаться новые строки.
flex-wrap: nowrap | wrap | wrap-reverse
nowrap
(по умолчанию): однострочный / слева направо дляltr
, справа налево дляrtl
;wrap
: многострочный / слева направо дляltr
, справа налево дляrtl
;wrap-reverse
: многострочный / справа налево дляltr
, слева направо дляrtl
.
flex-flow
Применяется к: родительскому элементу flex-контейнера.
Это сокращение для свойств flex-direction
и flex-wrap
, вместе определяющих главную и поперечную оси. По умолчанию принимает значение row nowrap
.
flex-flow: <'flex-direction'> || <'flex-wrap'>
justify-content
Применяется к: родительскому элементу flex-контейнера.
Определяет выравнивание относительно главной оси. Помогает распределить оставшееся свободное место в случае, когда элементы строки не «тянутся», либо тянутся, но уже достигли своего максимального размера. Также позволяет в некотором роде управлять выравниванием элементов при выходе за границы строки.
justify-content: flex-start | flex-end | center | space-between | space-around
flex-start
(по умолчанию): элементы сдвигаются к началу строки;flex-end
: элементы сдвигаются к концу строки;center
: элементы выравниваются по центру строки;space-between
: элементы распределяются равномерно (первый элемент в начале строки, последний — в конце);space-around
: элементы распределяются равномерно с равным расстоянием между собой и границами строки.
align-items
Применяется к: родительскому элементу flex-контейнера.
Определяет поведение по умолчанию для того, как flex-элементы располагаются относительно поперечной оси на текущей строке. Считайте это версией justify-content
для поперечной оси (перпендикулярной к основной).
align-items: flex-start | flex-end | center | baseline | stretch
flex-start
: границаcross-start
для элементов располагается на позицииcross-start
;flex-end
: границаcross-end
для элементов располагается на позицииcross-end
;center
: элементы выравниваются по центру поперечной оси;baseline
: элементы выравниваются по своей базовой линии;stretch
(по умолчанию): элементы растягиваются, заполняя контейнер (с учётомmin-width
/max-width
).
align-content
Применяется к: родительскому элементу flex-контейнера.
Выравнивает строки flex-контейнера при наличии свободного места на поперечной оси аналогично тому, как это делает justify-content
на главной оси.
Замечание: это свойство не работает с однострочным flexbox.
align-content: flex-start | flex-end | center | space-between | space-around | stretch
flex-start
: строки выравниваются относительно начала контейнера;flex-end
: строки выравниваются относительно конца контейнера;center
: строки выравниваются по центру контейнера;space-between
: строки распределяются равномерно (первая строка в начале строки, последняя — в конце);space-around
: строки распределяются равномерно с равным расстоянием между собой;stretch
(по умолчанию): строки растягиваются, заполняя свободное пространство.
order
Применяется к: дочернему элементу / flex-элементу.
По умолчанию flex-элементы располагаются в исходном порядке. Тем не менее, свойство order
может управлять порядком их расположения в контейнере.
order: <integer>
flex-grow
Применяется к: дочернему элементу / flex-элементу.
Определяет для flex-элемента возможность «вырастать» при необходимости. Принимает безразмерное значение, служащее в качестве пропорции. Оно определяет, какую долю свободного места внутри контейнера элемент может занять.
Если у всех элементов свойство flex-grow
задано как 1
, то каждый потомок получит внутри контейнера одинаковый размер. Если вы задали одному из потомков значение 2
, то он заберёт в два раза больше места, чем другие.
flex-grow: <number> (по умолчанию 0)
Отрицательные числа не принимаются.
flex-shrink
Применяется к: дочернему элементу / flex-элементу.
Определяет для flex-элемента возможность сжиматься при необходимости.
flex-shrink: <number> (default 1)
Отрицательные числа не принимаются.
flex-basis
Применяется к: дочернему элементу / flex-элементу.
Определяет размер по умолчанию для элемента перед распределением пространства в контейнере.
flex-basis: <length> | auto (default auto)
flex
Применяется к: дочернему элементу / flex-элементу.
Это сокращение для flex-grow
, flex-shrink
и flex-basis
. Второй и третий параметры (flex-shrink
, flex-basis
) необязательны. Значение по умолчанию — 0 1 auto
.
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
align-self
Применяется к: дочернему элементу / flex-элементу.
Позволяет переопределить выравнивание, заданное по умолчанию или в align-items
, для отдельных flex-элементов.
Обратитесь к описанию свойства align-items
для лучшего понимания доступных значений.
align-self: auto | flex-start | flex-end | center | baseline | stretch
Примеры
Начнём с очень-очень простого примера, встречающегося практически каждый день: выравнивание точно по центру. Нет ничего проще, если использовать flexbox.
.parent { display: flex; height: 300px; /* Или что угодно */ } .child { width: 100px; /* Или что угодно */ height: 100px; /* Или что угодно */ margin: auto; /* Магия! */ }
Этот пример основывается на том, что margin
во flex-контейнере, заданный как auto
, поглощает лишнее пространство, поэтому задание отступа таким образом выровняет элемент ровно по центру по обеим осям.
Теперь давайте используем какие-нибудь свойства. Представьте набор из 6 элементов фиксированного размера (для красоты), но с возможностью изменения размера контейнера. Мы хотим равномерно распределить их по горизонтали, чтобы при изменении размера окна браузера всё выглядело хорошо (без @media
-запросов!).
.flex-container { /* Сначала создадим flex-контекст */ display: flex; /* Теперь определим направление потока и хотим ли мы, чтобы элементы переносились на новую строку * Помните, что это тоже самое, что и: * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /* Теперь определим, как будет распределяться пространство */ justify-content: space-around; }
Готово. Всё остальное — уже дело оформления. Ниже размещён CodePen, демонстрирующий этот пример. Обязательно попробуйте растянуть/сжать окно браузера и посмотрите, что произойдёт.
Check out this Pen!
Давайте попробуем что-нибудь ещё. Представьте, что нам нужна выровненная по правому краю навигация в самом верху нашего сайта, но мы хотим, чтобы она выравнивалась по центру для экранов среднего размера и превращалась в один столбец на маленьких. Всё достаточно просто.
/* Большие экраны */ .navigation { display: flex; flex-flow: row wrap; /* Сдвигает элементы к концу строки по главной оси */ justify-content: flex-end; } /* Экраны среднего размера */ @media all and (max-width: 800px) { .navigation { /* Для экранов среднего размера мы выравниваем навигацию по центру, равномерно распределяя свободное место между элементами */ justify-content: space-around; } } /* Маленькие экраны */ @media all and (max-width: 500px) { .navigation { /* На маленьких экранах вместо строки мы располагаем элементы в столбце */ flex-direction: column; } }
Check out this Pen!
Давайте попробуем кое-что получше и поиграем с гибкостью flex-элементов! Как насчёт ориентированного на мобильные устройства трёхколоночного макета с полноширинной шапкой и подвалом? И другим порядком расположения.
.wrapper { display: flex; flex-flow: row wrap; } /* Задаём всем элементам ширину в 100% */ .header, .main, .nav, .aside, .footer { flex: 1 100%; } /* В этом случае мы полагаемся на исходный порядок для ориентации на * мобильные устройства: * 1. header * 2. nav * 3. main * 4. aside * 5. footer */ /* Экраны среднего размера */ @media all and (min-width: 600px) { /* Оба сайдбара располагаются в одной строке */ .aside { flex: 1 auto; } } /* Большие экраны */ @media all and (min-width: 800px) { /* Мы меняем местами элементы .aside-1 и .main, а также сообщаем * элементу .main забирать в два раза больше места, чем сайдбары. */ .main { flex: 2 0px; } .aside-1 { order: 1; } .main { order: 2; } .aside-2 { order: 3; } .footer { order: 4; } }
Check out this Pen!
Другие ресурсы
- Flexbox in the CSS specifications
- Flexbox at MDN
- Flexbox at Opera
- Diving into Flexbox by Bocoup
- Mixing syntaxes for best browser support on CSS-Tricks
- Flexbox by Raphael Goetter (FR)
- Flexplorer by Bennett Feely
frontender.info
Поддержка браузерами технологии CSS Flexbox
Технология Flexbox поддерживается уже почти всеми используемые на сегодняшний момент браузерами (с использованием префиксов: IE10+, Edge12+, Firefox 2+, Chrome 4+, Safari 3.1+, Opera 12.1+, iOS Safari 3.2, Opera mini, Android 2.1+, Blackberry 7+).
Основы Flexbox (сетка)
В основу Flexbox положена сетка. Она состоит всего из 2 элементов. Первый элемент – это flex-контейнер. Создание flex-контейнера осуществляется посредством добавления к необходимому HTML элементу CSS-свойства display
со значением flex
или flex-inline
.
После этого все непосредственные дочерние элементы flex-контейнера (дети) автоматически становятся flex-элементами (2 элемент flexbox сетки).
HTML разметка:
<div class="flex-container"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div>
CSS-стили:
.flex-container { display: flex; /* flex || inline-flex */ }

Flex-элементы по умолчанию занимают всю высоту flex-контейнера.
Значение flex
или flex-inline
определяет то, как flex-контейнер будет представлен на странице. Если его необходимо представить как блок, то используйте значение flex
. Если элемент необходимо представить как строчный, то используйте значение flex-inline
. В этом случае он будет занимать столько места странице, сколько необходимо для отображения его элементов.
Направление выстраивания flex-элементов
Указание направления выстраивания flex-элементов внутри flex-контейнера осуществляется посредством осей.

Во flexbox выделяют 2 оси. Первая ось называется основной или главной (по умолчанию направлена вправо). Вторая — поперечная (по умолчанию направлена вниз).
Элементы во flex-контейнере располагаются в одну линию (по умолчанию) даже тогда, когда им не хватает места. Выстраиваются flex-элементы в flex-контейнере по направлению основной оси.

В CSS Flexbox разрешить перенос flex-элементов на новые линии (если им не хватает места в текущей линии) осуществляется с помощью установки flex-контейнеру CSS свойства flex-wrap
со значением wrap
или wrap-reverse
.
flex-wrap: wrap; /* nowrap (в одну линию - по умолчанию) wrap (разрешить перенос flex-элементов на новые линии) wrap-reverse (осуществлять перенос flex-элементов в обратном порядке) */
Значения wrap
и wrap-reverse
CSS-свойства flex-wrap
определяют направление поперечной оси.
Установка направления главной оси flexbox осуществляется с помощью CSS-свойства flex-direction
.
flex-direction: row; /* row (вправо) - по умолчанию row-reverse (налево) column (вниз) column-reverse (вверх) */
С помощью этого свойства можно сделать так, чтобы flex-элементы располагались не горизонтально (строками), а вертикально (колонками).

Свойства flex-direction
и flex-wrap
можно указать с помощью универсального CSS свойства flex-flow
:
flex-flow: row nowrap; /* 1 значение - flex-direction, 2 значение - flex-wrap */
Выравнивание flex-элементов
Во Flexbox выравнивание элементов внутри контейнера осуществляется по двум направлениям (осям).
Выравнивание flex-элементов по направлению главной оси
Выравнивание элементов вдоль основной оси осуществляется с помощью CSS свойства justify-content
:
justify-content: flex-start; /* flex-start (flex-элементы выравниваются относительно начала оси) – по умолчанию flex-end (flex-элементы выравниваются относительно конца оси) center (по центру flex-контейнера) space-between (равномерно, т.е. с одинаковым расстоянием между flex-элементами) space-around (равномерно, но с добавлением половины пространства перед первым flex-элементом и после последнего) */

Выравнивание flex-элементов вдоль поперечной оси
Выравнивание flex-элементов во flex-контейнере по направлению поперечной оси осуществляется с помощью CSS-свойства align-items
:
align-items: stretch; /* stretch (растягиваются по всей длине поперечной оси) – по умолчанию flex-start (относительно начала поперечной оси) flex-end (относительно конца поперечной оси) baseline (относительно базовой линии) center (по центру) */

Выравнивание линий flex-контейнера
CSS Flexbox позволяет выравнивать не только сами flex-элементы, но и линии на которых они расположены.
align-content: stretch /* stretch (растягиваются по всей длине поперечной оси) – по умолчанию flex-start (относительно начала поперечной оси) flex-end (относительно конца поперечной оси) center (по центру) space-between (равномерно, т.е. с одинаковым расстоянием между линиями) space-around (равномерно, но с добавлением половины пространства перед первой линией и после последней) */

Свойство align-content
имеет смысл использовать только тогда, когда flex-элементы во flex-контейнере располагаются на нескольких линиях. Чтобы это произошло, необходимо, во-первых, чтобы ширина всех flex-элементов была больше ширины flex-контейнера, а во-вторых flex-контейнер должен иметь в качестве CSS-свойства flex-wrap
значение wrap
или wrap-reverse
.
CSS-свойство align-self
Свойство align-self
в отличие от предыдущих (justify-content
, align-items
и align-content
) предназначено для flex-элементов. Оно позволяет изменить выравнивание flex-элемента вдоль направления поперечной оси. Свойство align-self
может принимать такие же значения как align-items
.
align-items: stretch; /* auto (по умолчанию) || stretch || flex-start || flex-end || baseline || center */
Пример:
<div class="flex-container"> <div class="flex-container_element-1"> 1 </div> <div class="flex-container_element-2"> 2 </div> <div class="flex-container_element-3"> 3 </div> <div class="flex-container_element-4"> 4 </div> </div>
CSS:
.flex-container { display: flex; width: 300px; height: 150px; align-items: center; padding: 10px; background-color: #efefef; } .flex-container_element-1, .flex-container_element-2, .flex-container_element-3, .flex-container_element-4 { flex-basis: 70px; text-align: center; padding: 15px; font-size: 30px; } .flex-container_element-1 { align-self: flex-start; background: #fe4; } .flex-container_element-2 { align-self: flex-end; background: pink; } .flex-container_element-3 { align-self: stretch; background: lime; } .flex-container_element-4 { align-self: auto; background: cyan; }

Изменение порядка следования flex-элементов
По умолчанию flex-элементы отображаются во flex-контейнере в том порядке, в котором они расположены в HTML коде. Для изменения порядка следования одних flex-элементов относительно других в CSS Flexbox можно использовать свойство order
. Данное CSS свойство выстраивает flex-элементы во flex-контейнере в порядке возрастания их номеров.
order: 0; /* 0 (по умолчанию) целое положительное или отрицательное число */
Например:
<div class="flex-container"> <div class="flex-container_element-1">...</div> <div class="flex-container_element-2">...</div> <div class="flex-container_element-3">...</div> <div class="flex-container_element-4">...</div> </div> CSS: .flex-container { display: flex; } /* переместим 2 flex-элемент в конец */ .flex-container_element-2 { order: 2; } /* передвинем 3 элемент до 2 */ .flex-container_element-3 { order: 1; } /* расположим 4 flex-элемент до 1 */ .flex-container_element-4 { order: -1; }

Управление шириной flex-элемента
Во Flexbox есть несколько CSS свойств, определяющих то, какая ширина может быть у flex-элемента.
CSS-свойство flex-basis
Данное свойство предназначено для установления начальной ширины flex-элементу. Задавать значение ширины можно посредством различных единиц измерения, таких как px, %, em и др. По умолчанию данное свойство имеет значение auto
(в этом случае ширина элемента будет рассчитываться автоматически на основании его содержимого).
Конечная ширина flex-элемента будет определяться в зависимости от значений CSS-свойств flex-grow
и flex-shrink
, которые установлены не только для этого элемента, но и для других flex-элементов этого flex-контейнера.
CSS-свойство flex-grow
Это свойство определяет, может ли начальная ширина flex-элемента увеличиваться (расти). Увеличение ширины flex-элемента осуществляется за счёт свободного пространства линии. В качестве значения CSS-свойства flex-grow
указывается целое число. Именно это значение и определяет (если оно больше или равно 1) какую часть свободного пространства flex-элемент заберёт себе.
Например:
<div class="flex-container"> <div class="flex-container_element-1">...</div> <div class="flex-container_element-2">...</div> </div> CSS: .flex-container { display: flex; width: 600px; } .flex-container_element-1 { flex-basis: 40%; flex-grow: 1; } .flex-container_element-2 { flex-basis: 40%; flex-grow: 4; }

В этом примере, если flex-элементы расположены на одной линии и в ней есть свободное пространство (600×(1-0,8)=120px):
- к ширине элемента
.flex-container_element-1
добавится 1/5 часть этого пространства (120×1/5=24px); - к ширине элемента
.flex-container_element-2
добавится 4/5 части этого пространства (120×4/5=96px).
Другими словами, CSS свойство flex-grow
позволяет не просто указать, что ширина flex-элемента может вырасти, но и задать, насколько эта величина может вырасти по отношению к другим элементам.
По умолчанию CSS свойство flex-grow имеет значение 0. Это означает, что flex-элемент не может расти (увеличивать свою ширину).
CSS-свойство flex-shrink
Данное свойство определяет, может ли ширина flex-элемента уменьшиться. Уменьшение ширины flex-элемента будет осуществляться только в том случае, если ширины линии будет не достаточно для отображения всех flex-элементов, расположенных в ней. Необходимая ширина рассчитывается на основании начальной ширины, который имеет каждый flex-элемент в ней.
Например:
<div class="flex-container"> <div class="flex-container_element-1">...</div> <div class="flex-container_element-2">...</div> </div> CSS: .flex-container { display: flex; width: 500px; } .flex-container_element-1 { flex-basis: 300px; flex-shrink: 1; } .flex-container_element-2 { flex-basis: 300px; flex-shrink: 3; }

Ширина flex-контейнера 500px. Для отображения flex-элементов необходимо 600px. В итоге не хватает 100px. В этом примере уменьшаться могут 2 flex-элемента (.flex-container_element-1
и .flex-container_element-2
). Ширина первого flex-элемента .flex-container_element-1
в данном случае составит 300 – 1/4*100= 275px. Ширина второго flex-элемента .flex-container_element-2
в данном случае составит 300 – 3/4*100= 225px.
Значение по умолчанию:
flex-shrink: 1;
Если вам необходимо запретить уменьшение ширины flex-элементу, то в качестве значения свойства flex-shrink
необходимо указать число 0.
CSS-свойство flex
Для удобной установки flex-grow
, flex-shrink
и flex-basis
можно использовать CSS свойство flex
.
Значение по умолчанию:
flex: 0 1 auto; /* 0 - flex-grow (1 значение) 1 - flex-shrink (2 значение) auto - flex-basis (3 значение) */
Верстка макета страницы на CSS Flexbox
В этом разделе создадим простой адаптивный макет на Flexbox.
Структура макета будет состоять из 3 секций:
- header (для вывода заголовка и основного меню);
- main (для отображения основной части);
- footer (для футера).
Основную часть (main) в свою очередь разделим ещё на 2 раздела (их позиционирование будем осуществлять с помощью CSS Flexbox). На больших экранах (>=992px) эти разделы выстроим горизонтально, а на остальных — вертикально (<992px).
<header class="container"> [Шапка страницы...] </header> <main class="container"> <div class="row-flex"> <article class="main_article col-flex"> [Основная часть...] </article> <aside class="main_aside col-flex"> [Дополнительная часть...] </aside> </div> </main> <footer class="container"> [Футер...] </footer>
CSS:
/* контейнер (устанавливает ширину блока в зависимости от ширины viewport) */ .container { position: relative; margin-left: auto; margin-right: auto; padding-right: 15px; padding-left: 15px; } @media (min-width: 576px) { .container { width: 540px; max-width: 100%; } } @media (min-width: 768px) { .container { width: 720px; max-width: 100%; } } @media (min-width: 992px) { .container { width: 960px; max-width: 100%; } } @media (min-width: 1200px) { .container { width: 1140px; max-width: 100%; } } /* flex-контейнер */ .row-flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; } /* CSS настройки flex-элементов */ .col-flex { position: relative; width: 100%; min-height: 1px; padding-right: 15px; padding-left: 15px; } /* ширина блоков article и aside по умолчанию */ .main_article, .main_aside { -webkit-box-flex: 0; -webkit-flex: 0 0 100%; -ms-flex: 0 0 100%; flex: 0 0 100%; max-width: 100%; } /* ширина блоков article и aside для больших экранов */ @media (min-width: 992px) { /* 2/3 от ширины контейнера */ .main_article { -webkit-box-flex: 0; -webkit-flex: 0 0 66.666667%; -ms-flex: 0 0 66.666667%; flex: 0 0 66.666667%; max-width: 66.666667%; } /* 1/3 от ширины контейнера */ .main_aside { -webkit-box-flex: 0; -webkit-flex: 0 0 33.333333%; -ms-flex: 0 0 33.333333%; flex: 0 0 33.333333%; max-width: 33.333333%; } }
Для поддержки макета большинством браузеров добавим в CSS необходимые префиксы и max-width
.
Для «превращения» блока во flex-контейнер будем использовать класс row-flex
. Установку ширины каждому flex-элементу (main_article
и main_aside
) внутри flex-контейнера будем осуществлять с помощью CSS-свойства flex
.

В качестве примера разметим посредством Flexbox ещё блок «Футер» и секцию раздела main-article
«Интересненькое на сайте».
Секцию «Футер» разделим на 4 равные части (минимальная ширина одной части — 200px), а «Интересненькое на сайте» на 3 части (минимальная ширина одной части — 300px).
<header class="container"> [Шапка страницы...] </header> <main class="container"> <div class="row-flex"> <article class="main_article col-flex"> [Основная часть...] <!-- Секция "Интересненькое на сайте --> <div class="row-flex"> <div class="main_other_article col-flex" style="min-width:300px"> [Ещё 1...] </div> <div class="main_other_article col-flex" style="min-width:300px"> [Ещё 2...] </div> <div class="main_other_article col-flex" style="min-width:300px"> [Ещё 3...] </div> </div> </article> <aside class="main_aside col-flex"> [Дополнительная часть...] </aside> </div> </main> <footer class="container"> <div class="row-flex"> <div class="footer_block col-flex" style="min-width:200px"> [Секция футера 1...] </div> <div class="footer_block col-flex" style="min-width:200px"> [Секция футера 2...] </div> <div class="footer_block col-flex" style="min-width:200px"> [Секция футера 3...] </div> <div class="footer_block col-flex" style="min-width:200px"> [Секция футера 4...] </div> </div> </footer>
Дополнительный CSS:
.footer_block, .main_other_article { -webkit-flex-basis: 0; -ms-flex-preferred-size: 0; flex-basis: 0; -webkit-box-flex: 1; -webkit-flex-grow: 1; -ms-flex-positive: 1; flex-grow: 1; max-width: 100%; }
Демо макета страницы на Flexbox
itchief.ru