Модуль Flexbox-лейауту (flexible box — «гнучкий блок», на даний момент W3C Candidate Recommendation) ставить завдання запропонувати ефективніший спосіб верстки, вирівнювання та розподілу вільного місця між елементами в контейнері, навіть коли їх розмір невідомий та/або динамічний (звідси слово «Гнучкий»).
Головна задумка flex-верстки у наділенні контейнера здатністю змінювати ширину/висоти (і порядок) своїх елементів для найкращого заповнення простору (у більшості випадків — для підтримки всіх видів дисплеїв та розмірів екранів). Flex-контейнер розтягує елементи для заповнення вільного місця або стискає їх, щоб запобігти виходу за кордон.
Найважливіше, flexbox-лейаут не залежить від напрямку на відміну від звичайних лейаутів (блоки, що розташовуються вертикально, та інлайн-елементи, що розташовуються горизонтально). У той час, як звичайний лейаут відмінно підходить для веб-сторінок, йому не вистачає гнучкості (ніякого каламбуру) для підтримки великих або складних програм (особливо коли справа доходить до зміни орієнтації екрану, зміни розміру, розтягування, стиснення тощо) .
Примітка: Flexbox-лейаут найкраще підходить для складових частин програми та дрібномасштабних лейаутів, у той час як Grid-лейаут більше використовується для лейаутів великого масштабу.
Основи
Так як 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: <integer>
flex-grow
Застосовується до: дочірнього елемента/flex-елементу.
Визначає для flex-елемента можливість «виростати» за потреби. Приймає безрозмірне значення, що є пропорцією. Воно визначає, яку частку вільного місця всередині контейнера може зайняти елемент.
Якщо у всіх елементів властивість flex-grow встановлено як 1, то кожен нащадок отримає всередині контейнера однаковий розмір. Якщо ви задали одному з нащадків значення 2, він забере вдвічі більше місця, ніж інші.
flex-grow: <number> (за замовчуванням 0)
Негативні числа не приймаються.
flex-shrink
Застосовується до: дочірнього елемента/flex-елементу.
Визначає для flex-елемента можливість при необхідності стискатися.
flex-shrink: <number> (<b>default</b> 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;
}
Готово. Решта — вже справа оформлення.
Тепер уявіть, що нам потрібна вирівняна праворуч навігація в самому верху нашого сайту, але ми хочемо, щоб вона вирівнювалася по центру для екранів середнього розміру і перетворювалася на один стовпець на маленьких. Все досить просто.
/* Великі екрани */
.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;
}
}
Давайте спробуємо щось краще і пограємо з гнучкістю 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; }
}
Підтримка браузерами
- (modern) означає підтримку нового синтаксису зі специфікації (display: flex;)
- (hybrid) означає підтримку старого неофіційного синтаксису з 2011 року (display: flexbox;)
- (old) означає підтримку старого синтаксису з 2009 року (display: box;)
|
Браузер Blackberry версії 10+ підтримує новий синтаксис.
Для отримання детальнішої інформації про те, як і коли використовувати різні синтаксиси для забезпечення кращої підтримки браузерами, зверніться до цієї статті (CSS-Tricks) або цієї статті (DevOpera).
SASS-@mixin для полегшення болю:
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}