Вёрстка с помощью CSS Flexbox. Что такое Flexbox? Описание всех css свойств, основные принципы, преимущества и недостатки Строчный флекс контейнер
В этой статье познакомимся с технологией CSS Flexbox, предназначенной для создания гибких макетов веб-страниц.
Назначение CSS Flexbox
CSS Flexbox предназначен для создания гибких макетов . С помощью этой технологии можно очень просто и гибко расставить элементы в контейнере, распределить доступное пространство между ними, и выровнять их тем или иным способом даже если они не имеют конкретных размеров.
CSS Flexbox позволяет создать адаптивный дизайн намного проще, чем с использованием Float и позиционирования.
Flexbox можно использовать как для CSS разметки целой страницы, так и её отдельных блоков.
Поддержка CSS Flexbox браузерами
CSS Flexbox поддерживается всеми используемые на сегодняшний момент современными браузерами (с использованием префиксов: IE10+, Edge12+, Firefox 2+, Chrome 4+, Safari 3.1+, Opera 12.1+, iOS Safari 3.2, Opera mini, Android 2.1+, Blackberry 7+).
Основы CSS Flexbox
Создание CSS разметки с помощью Flexbox начинается с установки необходимому HTML элементу CSS-свойства display со значением flex или flex-inline .
После этого данный элемент становится flex-контейнером , а все его непосредственные дочерние элементы – flex-элементами . При этом когда мы говорим о flexbox то подразумеваем под этим только элемент с display:flex или display:flex-inline и все элементы непосредственно расположенные в нём. Таким образом в CSS Flexbox имеется всего два типа элементов: flex-контейнер и flex-элемент.
В CSS для поддержки макета большинством браузеров добавлены свойства с префиксами и max-width .
Для «превращения» блока во flex-контейнер используется класс row . Установку ширины flex-элементам.col__article и.col__aside внутри flex-контейнера выполнено с использованием CSS-свойства flex .
В качестве примера разметим посредством flexbox ещё футер и создадим в элементе.col__article блок состоящий из трёх элементов (минимальная ширина одного элемента - 300px). В футере разместим четыре блока (минимальная ширина одного блока - 200px).
CSS flexbox (Flexible Box Layout Module) — модуль макета гибкого контейнера — представляет собой способ компоновки элементов, в основе лежит идея оси.
Flexbox состоит из гибкого контейнера (flex container) и гибких элементов (flex items) . Гибкие элементы могут выстраиваться в строку или столбик, а оставшееся свободное пространство распределяется между ними различными способами.
Модуль flexbox позволяет решать следующие задачи:
- Располагать элементы в одном из четырех направлений: слева направо, справа налево, сверху вниз или снизу вверх.
- Переопределять порядок отображения элементов.
- Автоматически определять размеры элементов таким образом, чтобы они вписывались в доступное пространство.
- Решать проблему с горизонтальным и вертикальным центрированием.
- Переносить элементы внутри контейнера, не допуская его переполнения.
- Создавать колонки одинаковой высоты.
- Создавать прижатый к низу страницы .
Flexbox решает специфические задачи — создание одномерных макетов, например, навигационной панели, так как flex-элементы можно размещать только по одной из осей.
Список текущих проблем модуля и кросс-браузерных решений для них вы можете прочитать в статье Philip Walton .
Что такое flexbox
Поддержка браузерами
IE: 11.0, 10.0 -ms-
Firefox: 28.0, 18.0 -moz-
Chrome: 29.0, 21.0 -webkit-
Safari: 6.1 -webkit-
Opera: 12.1 -webkit-
iOS Safari: 7.0 -webkit-
Opera Mini: 8
Android Browser: 4.4, 4.1 -webkit-
Chrome for Android: 44
1. Основные понятия
Рис. 1. Модель flexboxДля описания модуля Flexbox используется определенный набор терминов. Значение flex-flow и режим записи определяют соответствие этих терминов физическим направлениям: верх / право / низ / лево, осям: вертикальная / горизонтальная и размерам: ширина / высота.
Главная ось (main axis) — ось, вдоль которой выкладываются flex-элементы. Она простирается в основном измерении.
Main start и main end — линии, которые определяют начальную и конечную стороны flex-контейнера, относительно которых выкладываются flex-элементы (начиная с main start по направлению к main end).
Основной размер (main size ) — ширина или высота flex-контейнера или flex-элементов, в зависимости от того, что из них находится в основном измерении, определяют основной размер flex-контейнера или flex-элемента.
Поперечная ось (cross axis) — ось, перпендикулярная главной оси. Она простирается в поперечном измерении.
Cross start и cross end — линии, которые определяют начальную и конечную стороны поперечной оси, относительно которых выкладываются flex-элементы.
Поперечный размер (cross size) — ширина или высота flex-контейнера или flex-элементов, в зависимости от того, что находится в поперечном измерении, являются их поперечным размером.
Рис. 2. Режим строки и колонки
2. Flex-контейнер
Flex-контейнер устанавливает новый гибкий контекст форматирования для его содержимого. Flex-контейнер не является блочным контейнером, поэтому для дочерних элементов не работают такие CSS-свойства, как float , clear , vertical-align . Также, на flex-контейнер не оказывают влияние свойства column-* , создающие колонки в тексте и псевдоэлементы::first-line и::first-letter .
Модель flexbox-разметки связана с определенным значением CSS-свойства display родительского html-элемента, содержащего внутри себя дочерние блоки. Для управления элементами с помощью этой модели нужно установить свойство display следующим образом:
Flex-container { /*генерирует flex-контейнер уровня блока*/ display: -webkit-flex; display: flex; } .flex-container { /*генерирует flex-контейнер уровня строки*/ display: -webkit-inline-flex; display: inline-flex; }
После установки данных значений свойства каждый дочерний элемент автоматически становится flex-элементом, выстраиваясь в один ряд (вдоль главной оси). При этом блочные и строчные дочерние элементы ведут себя одинаково, т.е. ширина блоков равна ширине их содержимого с учетом внутренних полей и рамок элемента.
Рис. 3. Выравнивание элементов в модели flexbox
Если родительский блок содержит текст или изображения без оберток, они становятся анонимными flex-элементами. Текст выравнивается по верхнему краю блока-контейнера, а высота изображения становится равной высоте блока, т.е. оно деформируется.
3. Flex-элементы
Flex-элементы — блоки, представляющие содержимое flex-контейнера в потоке. Flex-контейнер устанавливает новый контекст форматирования для своего содержимого, который обуславливает следующие особенности:
- Для flex-элементов блокируется их значение свойства display . Значение display: inline-block; и display: table-cell; вычисляется в display: block; .
- Пустое пространство между элементами исчезает: оно не становится своим собственным flex-элементом, даже если межэлементный текст обернут в анонимный flex-элемент. Для содержимого анонимного flex-элемента невозможно задать собственные стили, но оно будет наследовать их (например, параметры шрифта) от flex-контейнера.
- Абсолютно позиционированный flex-элемент не участвует в компоновке гибкого макета.
- Поля margin соседних flex-элементов не схлопываются.
- Процентные значения margin и padding вычисляются от внутреннего размера содержащего их блока.
- margin: auto; расширяются, поглощая дополнительное пространство в соответствующем измерении. Их можно использовать для выравнивания или раздвигания смежных flex-элементов.
- Автоматический минимальный размер flex-элементов по умолчанию является минимальным размером его содержимого, то есть min-width: auto; . Для контейнеров с прокруткой автоматический минимальный размер обычно равен нулю.
4. Порядок отображения flex-элементов и ориентация
Содержимое flex-контейнера можно разложить в любом направлении и в любом порядке (переупорядочение flex-элементов внутри контейнера влияет только на визуальный рендеринг).
4.1. Направление главной оси: flex-direction
Свойство относится к flex-контейнеру. Управляет направлением главной оси, вдоль которой укладываются flex-элементы, в соответствии с текущим режимом записи. Не наследуется.
flex-direction | |
---|---|
Значения: | |
row | Значение по умолчанию, слева направо (в rtl справа налево). Flex-элементы выкладываются в строку. Начало (main-start) и конец (main-end) направления главной оси соответствуют началу (inline-start) и концу (inline-end) оси строки (inline-axis). |
row-reverse | Направление справа налево (в rtl слева направо). Flex-элементы выкладываются в строку относительно правого края контейнера (в rtl — левого). |
column | Направление сверху вниз. Flex-элементы выкладываются в колонку. |
column-reverse | Колонка с элементами в обратном порядке, снизу вверх. |
initial | |
inherit |
Рис. 4. Свойство flex-direction для left-to-right языков
Синтаксис
Flex-container { display: -webkit-flex; -webkit-flex-direction: row-reverse; display: flex; flex-direction: row-reverse; }
4.2. Управление многострочностью flex-контейнера: flex-wrap
Свойство определяет, будет ли flex-контейнер однострочным или многострочным, а также задает направление поперечной оси, определяющее направление укладки новых линий flex-контейнера.
По умолчанию flex-элементы укладываются в одну строку, вдоль главной оси. При переполнении они будут выходить за пределы ограничивающей рамки flex-контейнера. Свойство не наследуется.
Рис. 5. Управление многострочностью с помощью свойства flex-wrap для LTR-языков
Синтаксис
Flex-container { display: -webkit-flex; -webkit-flex-wrap: wrap; display: flex; flex-wrap: wrap; }
4.3. Краткая запись направления и многострочности: flex-flow
Свойство позволяет определить направления главной и поперечной осей, а также возможность переноса flex-элементов при необходимости на несколько строк. Представляет собой сокращённую запись свойств flex-direction и flex-wrap . Значение по умолчанию flex-flow: row nowrap; . свойство не наследуется.
Синтаксис
Flex-container { display: -webkit-flex; -webkit-flex-flow: row wrap; display: flex; flex-flow: row wrap; }
4.4. Порядок отображения flex-элементов: order
Свойство определяет порядок, в котором flex-элементы отображаются и располагаются внутри flex-контейнера. Применяется к flex-элементам. Свойство не наследуется.
Первоначально все flex-элементы имеют order: 0; . При указании значения от -1 для элемента он перемещается в начало сроки, значение 1 — в конец. Если несколько flex-элементов имеют одинаковое значение order , они будут отображаться в соответствии с исходным порядком.
Синтаксис
Flex-container {
display: -webkit-flex;
display: flex;
}
.flex-item {
-webkit-order: 1;
order: 1;
}
Рис. 6. Порядок отображения flex-элементов
5. Гибкость flex-элементов
Определяющим аспектом гибкого макета является возможность «сгибать» flex-элементы, изменяя их ширину / высоту (в зависимости от того, какой размер находится на главной оси), чтобы заполнить доступное пространство в основном измерении. Это делается с помощью свойства flex . Flex-контейнер распределяет свободное пространство между своими дочерними элементами (пропорционально их коэффициенту flex-grow) для заполнения контейнера или сжимает их (пропорционально их коэффициенту flex-shrink), чтобы предотвратить переполнение.
Flex-элемент будет полностью «негибок», если его значения flex-grow и flex-shrink равны нулю, и «гибкий» в противном случае.
5.1. Задание гибких размеров одним свойством: flex
Свойство является сокращённой записью свойств flex-grow , flex-shrink и flex-basis . Значение по умолчанию: flex: 0 1 auto; . Можно указывать как одно, так и все три значения свойств. Свойство не наследуется.
Синтаксис
Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex: 3 1 100px; -ms-flex: 3 1 100px; flex: 3 1 100px; }
5.2. Коэффициент роста: flex-grow
Свойство определяет коэффициент роста одного flex-элемента относительно других flex-элементов в flex-контейнере при распределении положительного свободного пространства. Если сумма значений flex-grow flex-элементов в строке меньше 1, они занимают менее 100% свободного пространства. Свойство не наследуется.
Рис. 7. Управление свободным пространством в панели навигации с помощью flex-grow
Синтаксис
Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex-grow: 3; flex-grow: 3; }
5.3. Коэффициент сжатия: flex-shrink
Свойство указывает коэффициент сжатия flex-элемента относительно других flex-элементов при распределении отрицательного свободного пространства. Умножается на базовый размер flex-basis . Отрицательное пространство распределяется пропорционально тому, насколько элемент может сжаться, поэтому, например, маленький flex-элемент не уменьшится до нуля, пока не будет заметно уменьшен flex-элемент большего размера. Свойство не наследуется.
Рис. 8. Сужение flex-элементов в строке
Синтаксис
Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex-shrink: 3; flex-shrink: 3; }
5.4. Базовый размер: flex-basis
Свойство устанавливает начальный основной размер flex-элемента до распределения свободного пространства в соответствии с коэффициентами гибкости. Для всех значений, кроме auto и content , базовый гибкий размер определяется так же, как width в горизонтальных режимах записи. Процентные значения определяются относительно размера flex-контейнера, а если размер не задан, используемым значением для flex-basis являются размеры его содержимого. Не наследуется.
Синтаксис
Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex-basis: 100px; flex-basis: 100px; }
6. Выравнивание
6.1. Выравнивание по главной оси: justify-content
Свойство выравнивает flex-элементы по главной оси flex-контейнера, распределяя свободное пространство, незанятое flex-элементами. Когда элемент преобразуется в flex-контейнер, flex-элементы по умолчанию сгруппированы вместе (если для них не заданы поля margin). Промежутки добавляются после расчета значений margin и flex-grow . Если какие-либо элементы имеют ненулевое значение flex-grow или margin: auto; , свойство не будет оказывать влияния. Свойство не наследуется.
Значения: | |
flex-start | Значение по умолчанию. Flex-элементы выкладываются в направлении, идущем от начальной линии flex-контейнера. |
flex-end | Flex-элементы выкладываются в направлении, идущем от конечной линии flex-контейнера. |
center | Flex-элементы выравниваются по центру flex-контейнера. |
space-between | Flex-элементы равномерно распределяются по линии. Первый flex-элемент помещается вровень с краем начальной линии, последний flex-элемент — вровень с краем конечной линии, а остальные flex-элементы на линии распределяются так, чтобы расстояние между любыми двумя соседними элементами было одинаковым. Если оставшееся свободное пространство отрицательно или в строке присутствует только один flex-элемент, это значение идентично параметру flex-start . |
space-around | Flex-элементы на линии распределяются так, чтобы расстояние между любыми двумя смежными flex-элементами было одинаковым, а расстояние между первым / последним flex-элементами и краями flex-контейнера составляло половину от расстояния между flex-элементами. |
initial | Устанавливает значение свойства в значение по умолчанию. |
inherit | Наследует значение свойства от родительского элемента. |
Рис. 9. Выравнивание элементов и распределение свободного пространства с помощью свойства justify-content
Синтаксис
Flex-container { display: -webkit-flex; -webkit-justify-content: flex-start; display: flex; justify-content: flex-start; }
6.2. Выравнивание по поперечной оси: align-items и align-self
Flex-элементы можно выравнивать по поперечной оси текущей строки flex-контейнера. align-items устанавливает выравнивание для всех элементов flex-контейнера, включая анонимные flex-элементы. align-self позволяет переопределить это выравнивание для отдельных flex-элементов. Если любое из поперечных margin flex-элемента имеет значение auto , align-self не имеет никакого влияния.
6.2.1. Align-items
Свойство выравнивает flex-элементы, в том числе и анонимные flex-элементы по поперечной оси. Не наследуется.
Значения: | |
flex-start | |
flex-end | |
center | |
baseline | Базовые линии всех flex-элементов, участвующих в выравнивании, совпадают. |
stretch | |
initial | Устанавливает значение свойства в значение по умолчанию. |
inherit | Наследует значение свойства от родительского элемента. |
Синтаксис
Flex-container { display: -webkit-flex; -webkit-align-items: flex-start; display: flex; align-items: flex-start; }
6.2.2. Align-self
Свойство отвечает за выравнивание отдельно взятого flex-элемента по высоте flex-контейнера. Переопределяет выравнивание, заданное align-items . Не наследуется.
Значения: | |
auto | Значение по умолчанию. Flex-элемент использует выравнивание, указанное в свойстве align-items flex-контейнера. |
flex-start | Верхний край flex-элемента помещается вплотную с flex-линией (или на расстоянии, с учетом заданных полей margin и рамок border элемента), проходящей через начало поперечной оси. |
flex-end | Нижний край flex-элемента помещается вплотную с flex-линией (или на расстоянии, с учетом заданных полей margin и рамок border элемента), проходящей через конец поперечной оси. |
center | Поля flex-элемента центрируется по поперечной оси в пределах flex-линии. |
baseline | Flex-элемент выравнивается по базовой линии. |
stretch | Если поперечный размер flex-элемента вычисляется как auto и ни одно из поперечных значений margin не равно auto , элемент растягивается. Значение по умолчанию. |
initial | Устанавливает значение свойства в значение по умолчанию. |
inherit | Наследует значение свойства от родительского элемента. |
Рис. 11. Выравнивание отдельных flex-элементов
Синтаксис
Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-align-self: center; align-self: center; }
6.3. Выравнивание строк flex-контейнера: align-content
Свойство выравнивает строки в flex-контейнере при наличии дополнительного пространства на поперечной оси, аналогично выравниванию отдельных элементов на главной оси с помощью свойства justify-content . Свойство не влияет на однострочный flex-контейнер. Не наследуется.
Значения: | |
flex-start | Строки укладываются по направлению к началу flex-контейнера. Край первой строки помещается вплотную к краю flex-контейнера, каждая последующая — вплотную к предыдущей строке. |
flex-end | Строки укладываются по направлению к концу flex-контейнера. Край последней строки помещается вплотную к краю flex-контейнера, каждая предыдущая — вплотную к последующей строке. |
center | Строки укладываются по направлению к центру flex-контейнера. Строки расположены вплотную друг к другу и выровнены по центру flex-контейнера с равным расстоянием между начальным краем содержимого flex-контейнера и первой строкой и между конечным краем содержимого flex-контейнера и последней строкой. |
space-between | Строки равномерно распределены в flex-контейнере. Если оставшееся свободное пространство отрицательно или в flex-контейнере имеется только одна flex-линия, это значение идентично flex-start . В противном случае край первой строки помещается вплотную к начальному краю содержимого flex-контейнера, край последней строки — вплотную к конечному краю содержимого flex-контейнера. Остальные строки распределены так, чтобы расстояние между любыми двумя соседними строками было одинаковым. |
space-around | Строки равномерно распределены в flex-контейнере с половинным пробелом на обоих концах. Если оставшееся свободное пространство отрицательно, это значение идентично цент center . В противном случае строки распределяются таким образом, чтобы расстояние между любыми двумя соседними строками было одинаковым, а расстояние между первой / последней строками и краями содержимого flex-контейнера составляло половину от расстояния между строками. |
stretch | Значение по умолчанию. Строки flex-элементов равномерно растягиваются, заполняя все доступное пространство. Если оставшееся свободное пространство отрицательно, это значение идентично flex-start . В противном случае свободное пространство будет разделено поровну между всеми строками, увеличивая их поперечный размер. |
initial | Устанавливает значение свойства в значение по умолчанию. |
inherit | Наследует значение свойства от родительского элемента. |
Синтаксис
Flex-container { display: -webkit-flex; -webkit-flex-flow: row wrap; -webkit-align-content: flex-end; display: flex; flex-flow: row wrap; align-content: flex-end; height: 100px; }
Flexbox по праву можно назвать удачной попыткой решения огромного спектра проблем при построении лейаутов в css. Но прежде чем перейти к его описанию, давайте выясним, что же не так со способами верстки, которыми мы пользуемся сейчас?
Любой верстальщик знает несколько путей выровнять что-либо по вертикали или сделать 3-х колоночный макет с резиновой средней колонкой. Но давайте признаем, что все эти способы довольно странные, похожи на хак, подходят не во всех случаях, сложны для восприятия и не работают при несоблюдении определенных магических условий, которые сложились исторически.
Случилось так потому, что html и css развивались эволюционно. В начале веб-страницы были похожи на однопоточные текстовые документы, чуть позже разбиение страницы на блоки делали таблицами, затем стало модным верстать float-ами, а после официальной смерти ie6 добавились еще и приемы с inline-block. В итоге мы получили в наследство гремучую смесь всех этих приемов, используемую для построения лейаутов 99,9% всех существующих веб-страниц.
Многострочная организация блоков внутри flex-контейнера.
flex-wrap
Все примеры, которые мы приводили выше, были построены с учетом однострочного (одностолбцового) расположения блоков. Надо сказать, что по умолчанию flex-контейнер всегда будет располагать блоки внутри себя в одну линию. Однако, спецификацией также поддерживается многострочный режим. За многострочность внутри flex-контейнера отвечает CSS свойство flex-wrap .
Доступные значения flex-wrap :
- nowrap (значение по умолчанию) : блоки расположены в одну линию слева направо (в rtl справа налево)
- wrap: блоки расположены в несколько горизонтальных рядов (если не помещаются в один ряд). Они следуют друг за другом слева направо (в rtl справа налево)
- wrap-reverse: то-же что и wrap , но блоки располагаются в обратном порядке.
flex-flow – удобное сокращение для flex-direction + flex-wrap
По сути, flex-flow предоставляет возможность в одном свойстве описать направление главной и многострочность поперечной оси. По умолчанию flex-flow: row nowrap .
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
CSS
/* т.е. ... */ .my-flex-block{ flex-direcrion:column; flex-wrap: wrap; } /* это то же самое, что... */ .my-flex-block{ flex-flow: column wrap; }align-content
Существует также свойство align-content , которое определяет то, каким образом образовавшиеся ряды блоков будут выровнены по вертикали и как они поделят между собой все пространство flex-контейнера.
Важно: align-content работает только в многострочном режиме (т.е. в случае flex-wrap:wrap; или flex-wrap:wrap-reverse;)
Доступные значения align-content :
- flex-start: ряды блоков прижаты к началу flex-контейнера.
- flex-end: ряды блоков прижаты к концу flex-контейнера
- center: ряды блоков находятся в центре flex-контейнера
- space-between: первый ряд блоков располагается в начале flex-контейнера, последний ряд блоков блок – в конце, все остальные ряды равномерно распределены в оставшемся пространстве.
- space-around: ряды блоков равномерно распределены в от начала до конца flex-контейнера, разделяя все свободное пространство поровну.
- stretch (значение по умолчанию) : Ряды блоков растянуты, дабы занять все имеющееся пространство.
СSS свойства flex-wrap и align-content должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.
Демо свойств многострочности в flex
CSS правила для дочерних элементов flex-контейнера (flex-блоков)
flex-basis – базовый размер отдельно взятого flex-блока
Задает изначальный размер по главной оси для flex-блока до того, как к нему будут применены преобразования, основанные на других flex-факторах. Может быть задан в любых единицах измерения длинны (px , em , % , …) или auto (по умолчанию). Если задан как auto – за основу берутся размеры блока (width, height), которые, в свою очередь, могут зависеть от размера контента, если не указанны явно.
flex-grow – “жадность” отдельно взятого flex-блока
Определяет то, на сколько отдельный flex-блок может быть больше соседних элементов, если это необходимо. flex-grow принимает безразмерное значение (по умолчанию 0)
Пример 1 :
- Если все flex-блоки внутри flex-контейнера имеют flex-grow:1 , то они будут одинакового размера
- Если один из них имеет flex-grow:2 , то он будет в 2 раза больше, чем все остальные
Пример 2 :
- Если все flex-блоки внутри flex-контейнера имеют flex-grow:3 , то они будут одинакового размера
- Если один из них имеет flex-grow:12 , то он будет в 4 раза больше, чем все остальные
Т.е абсолютное значение flex-grow не определяет точную ширину. Оно определяет его степень “жадности” по отношению к другим flex-блокам того же уровня.
flex-shrink – фактор “сжимаемости” отдельно взятого flex-блока
Определяет, насколько flex-блок будет уменьшаться относительно соседних эдементов внутри flex-контейнера в случае недостатка свободного места. По умолчанию равен 1 .
flex – короткая запись для свойств flex-grow, flex-shrink и flex-basis
flex: none | [ <"flex-grow"> <"flex-shrink">? || <"flex-basis"> ]
CSS
/* т.е. ... */ .my-flex-block{ flex-grow:12; flex-shrink:3; flex basis: 30em; } /* это то же самое, что... */ .my-flex-block{ flex: 12 3 30em; }Демо для flex-grow, flex-shrink и flex-basis
align-self – выравнивание отдельно взятого flex-блока по поперечной оси.
Делает возможным переопределять свойство flex-контейнера align-items для отдельного flex-блока.
Доступные значения align-self (те же 5 вариантов, что и для align-items)
- flex-start: flex-блок прижат к началу поперечной оси
- flex-end: flex-блок прижат к концу поперечной оси
- center: flex-блок располагаются в центре поперечной оси
- baseline: flex-блок выравнен по baseline
- stretch (значение по умолчанию) : flex-блок растянут, чтобы занять все доступное место по поперечной оси, при этом учитываются min-width / max-width , если таковые заданы.
order – порядок следования отдельно взятого flex-блока внутри flex-контейнера.
По умолчанию все блоки будут следовать друг за другом в порядке, заданном в html. Однако этот порядок можно изменить с помощью свойства order . Оно задается целым числом и по умолчанию равно 0 .
Значение order не задает абсолютную позицию элемента в последовательности. Оно определяет вес позиции элемента.
HTML
В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: item5, item1, item3, item4, item2
Демо для align-self и order
margin: auto по вертикали . Мечты сбываются!
Flexbox можно любить хотя бы за то, что привычное всем выравнивание по горизонтали через margin:auto здесь работает и для вертикали!
My-flex-container { display: flex; height: 300px; /* Или что угодно */ } .my-flex-block { width: 100px; /* Или что угодно */ height: 100px; /* Или что угодно */ margin: auto; /* Магия! Блок отцентрирован по вертикали и горизонтали! */ }
Вещи, которые следует помнить
- Не следует использовать flexbox там, где в этом нет необходимости.
- Определение регионов и изменение порядка контента во многих случаях все-таки полезно делать зависимым от структуры страницы. Продумывайте это.
- Разберитесь в flexbox и знайте его основы. Так намного легче достичь ожидаемого результата.
- Не забывайте про margin-ы. Они учитываются при установке выравнивания по осям. Также важно помнить, что margin-ы в flexbox не “коллапсятся”, как это происходит в обычном потоке.
- Значение float у flex-блоков не учитывается и не имеет значения. Это, наверно, как-то можно использовать для graceful degradation при переходе на flexbox.
- flexbox очень хорошо подходит для верстки веб-компонентов и отдельных частей веб-страниц, но показал себя не с лучшей стороны при верстке базовых макетов (расположение article, header, footer, navbar и т.п.). Это все еще спорный момент, но эта статья довольно убедительно показывает недостатки xanthir.com/blog/b4580
В заключение
Я думаю, что flexbox, конечно же, не вытеснит все остальные способы верстки, но, безусловно, в ближайшее время займет достойную нишу при решении огромного количества задач. И уж точно, пробовать работать с ним нужно уже сейчас. Одна из следующих статей будет посвящена конкретным примерам работы с flex-версткой. Подписывайтесь на новости;)
На примере формы из реального тестового задания, я покажу вам, как верстать по БЭМ , используя flexbox . Вы спросите: "Почему обязательно верстать по БЭМ + Flexbox ?" Это требование исходит от работодателя. Цитата из ТЗ: "Старайтесь верстать без фреймворков (желательно на flexbox ), просто и понятно: избегайте громоздких конструкций и лишнего кода, используйте методологию БЭМ ."
Фрагмент макета секции с формой
Мои правила верстки
- Разделить макет на логические секции
- Каждую секцию начинать с тега section
- Отделять секции и CSS правили друг от друга, пустой строкой
- Каждому тегу присвоить класс
- Название класса для блока или элемента, отвечает на вопрос - Что это ?
- Имя модификатора отвечает на вопрос - Какой ?
HTML разметка
Сначала я делаю разметку, определяю вложенность блоков и придумываю названия классам. В представленном ниже коде, у нас имеются два строчных тега - h2 и input . Строчные теги - это головная боль и причина стресса, у начинающих верстальщиков. Почему? Они очень плохо себя ведут - пытаются занять всю доступную ширину, не дают установить цвет фона и размеры у всего блока.
Личная информация
Что в таком случае делает плохой верстальщик? Он оборачивает строчные элементы в блочные теги div и все нужные свойства задаёт тегу обертке. Дочерние строчные элементы, наследуют эти свойства. А стоит ли городить огород из лишнего кода? Как поступит грамотный верстальщик? Он переопределит строчный элемент в блочный или строчно-блочный, в CSS правилах.
Display: block; // для тега input
display: inline-block; // для тега h2
Логика вложенности и названия блоков
Мы видим секцию с личной информацией, так и называем класс секции - info . Секция состоит из трех дочерних элементов:
Иконка // название класса info__icon
заголовок // info__title
форма // info__form
Суть в названии классов по БЭМ , состоит в принадлежности дочернего элемента к родителю. Нельзя назвать элемент, icon . Это не просто какая-то иконка, а иконка из секции info .
Дочка и родитель в одном лице
Блок info__form , у нас особенный - он вложен в секцию info , но в тоже время, содержит поля формы. Название этому явлению - многоуровневая вложенность. Блок с формой, несет чисто оберточную функцию для инпутов, чтобы легко можно было задать внешние отступы. Ведь строчные инпуты ведут себя, как дети (кем они и являются), совсем не слушаются. Причем второй инпут, короче всех остальных и отличается только шириной.
Задаем один класс для всех инпутов с одинаковыми свойствами, кроме ширины - info__input . Обычным инпутам, добавим модификатор info__input_long , а короткому инпуту - модификатор info__input_short . Напомню, что модификатор по БЭМ , должен отвечать на вопрос - Какой ?
CSS правила для модификаторов
.info__input_long {width: 520px;
}
Info__input_short {
width: 320px;
}
CSS код
В HTML разметке создается грубая структура сайта, в CSS , мы уже размещаем элементы, согласно макету. Сегодня, мы не будем касаться внешнего вида, а сосредоточимся на позиционировании элементов. В нашей секции, два флексовых контейнера. Надо сказать, что использование флексов, при расположении всех элементов по одному в строке, очень сомнительно. Единственная получаемая польза - это свойство justify-content , выравнивающее по центру, флекс элементы. Могу сказать в своё оправдание, что, затея с флексами бессмысленная, в контексте только этой секции. Настоящий макет для верстки, обычно имеет больше разнообразия.
Info {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-top: 77px;
height: 100%;
}
Info__form {
display: flex;
justify-content: center;
flex-direction: column;
height: 100%;
margin-top: 50px;
Ничто не стоит на месте, развиваются технологии и стандарты, появляются все новые приемы и методы верстки сайтов, к примеру, верстка табличными элементами, которую мы не рассматривали по объективным причинам сменилась версткой плавающими элементами.
У многих редакторов кода по умолчанию встроен, или доступен для скачивания удобный плагин для быстрой разметки Emmet , он позволяет сделать основную разметку этого примера следующим образом: section>div*3>lorem + Tab (значение lorem генерирует текст, который имеется на изображении ниже).
Обратите внимание, что не прилагая особых усилий мы получили размещение колонок нашего макета одинаковой высоты независимо от наполнения их содержимым и это замечательно. Элементы
не являются по умолчанию флекс элементами и расположены в потоке третьего элемента
Результат нашего примера:
Строчный флекс контейнер
По аналогии с блочными элементами флекс контейнеры могут быть строчными. Давайте разберем в чем заключается отличие строчных флекс контейнеров от блочных. В предыдущем примере мы рассмотрели использование блочного контейнера, как и обычный блочный элемент он занимает всю ширину экрана, и ведет себя как обычный элемент уровня блока. Что касается строчных флекс контейнеров, то они становятся обычными встроенными элементами, сохраняя при этом гибкость элементов.
В следующем примере мы рассмотрим это отличие, так как предыдущий пример не был бы показательным, по той причине, что дочерним флекс элементам не был явно задан размер, и как следствие, наш контейнер, будь он строчным, или блочным вел бы себя одинаково и занимал бы всю ширину экрана.
В этом примере мы разместили два строчных и два блочных флекс контейнера, внутри них мы разместили по пять элементов
Чтобы быстро сгенерировать подобную верстку с помощью Emmet наберите в редакторе следующее: div.inline-flex*2>div*5 + Tab , и тоже самое только с другим классом div.flex*2>div*5 + Tab .
Взгляните на результат нашего примера, разница между строчными и блочными флекс контейнерами теперь должна быть очевидна для Вас. Строчный контейнер ведет себя как встроенный элемент и занимает ширину, требуемую только его дочерними флекс элементам, а блочный флекс контейнер, не смотря на размер его дочерних флекс элементов занимает всю ширину экрана.
Результат нашего примера:
Рис. 205 Пример отличия inline-flex контейнеров от flex контейнеров.
Направление? Какое направление?
Направление флекс элементов формируется исходя из положения двух осей: главной оси флекс контейнера и его поперечной оси , которая всегда распологается перпендикулярно главной . Главная ось при направлении ltr (глобальный HTML атрибут dir , либо CSS свойство direction со значением ltr ) располагается слева направо, а поперечная – сверху вниз (это значение по умолчанию), для значения rtl отображается зеркально соответственно.