Це повне керівництво пояснює все про flexbox, зосереджуючись на всіх можливих властивосях для батьківського елемента (контейнер flex) та дочірніх елементів (елементи flex). Воно також включає в себе історію, демонстрації, шаблони і таблицю підтримки браузерів.
Передумови
Модуль Flexbox Layout (Flexible Box) ( W3C Candidate Recommendation від жовтня 2017 г.) спрямований на забезпечення ефективнішого способу розміщення, вирівнювання і розподілу простору між елементами в контейнері, навіть якщо їх розмір невідомий та/або динамічний (Flex означає «гнучкий»).
Основна ідея flex layout полягає в тому, щоб дати контейнеру можливість змінювати ширину/висоту його елементів (і порядок), щоб найкращим чином заповнити доступний простір (головним чином, для відображення на всіх типах пристроїв з будь-яким розміром екрану). Flex контейнер розширює елементи, щоб заповнити доступний вільний простір, або стискає їх, щоб запобігти переповнення.
Найважливішим є те, що макет flexbox не залежить від напрямку, на відміну від звичайних макетів (block на вертикальній основі та inline на горизонтальній основі). Хоча вони добре працюють для сторінок, їм не вистачає гнучкості (без каламбуру) для підтримки великих або складних застосунків (особливо коли мова йде про зміну орієнтації, зміні розміру, розтягу, стиску і т.д.).
Примітка: Flexbox layout найбільше підходить для компонентів програми та дрібномасштабних макетів, а Grid layout призначений для макетів більшого масштабу.
Основи і термінологія
Оскільки flexbox - це цілий модуль, а не одна властивість, він включає в себе безліч елементів з набором властивостей. Деякі з них призначені для установки в контейнері (батьківський елемент прийнято називати «flex контейнер»), в той час як інші призначені для установки в дочірніх елементах (так звані «flex елементи»).
Якщо «звичайна» компоновка заснована як на блочному, так і на inline напрямках, flex layout заснована на «напрямках flex-flow». Будь ласка, подивіться на цей малюнок зі специфікації, яка пояснювала б основну ідею гнучкого макета.Елементи будуть розташовані або в напрямку головної осі ( main axis від main-start
до main-end
) або в напрямку поперечної осі ( cross axis від cross-start
до cross-end
).
- main axis - головна вісь flex контейнера - це головна вісь, уздовж якої розташовуються flex елементи. Будьте уважні, ця вісь не обов'язкова горизонтальна; це залежить від властивості
flex-direction
(див. нижче). - main-start | main-end - flex елементи поміщаються в контейнер, починаючи з
main-start
і закінчуючиmain-end
. - main size - ширина або висота flex елемента, в залежності від того, що знаходиться в основному вимірі. Визначається основним розміром flex елементів тобто властивістю 'width' або 'height', в залежності від того, що знаходиться в основному вимірі.
- cross axis - вісь перпендикулярна головній осі, називається поперечною віссю. Її напрямок залежить від напрямку головної осі.
- cross-start | cross-end - flex рядки заповнюються елементами і поміщаються в контейнер, починаючи від
cross-start
flex контейнера у напрямку доcross-end
. - cross size - ширина або висота flex елемента. Залежно від css властивості
flex-direction
, це ширина або висота елемента. Це завжди поперечний розмір flex елементів.
Властивості для Батьківського елемента (flex контейнер)
display
Визначає flex контейнер; inline або block в залежності від заданого значення. Включає flex контекст для всіх нащадків першого рівня.
.container { display: flex; /* or inline-flex */ }
Зверніть увагу, що CSS-стовпці columns не впливають на flex контейнер.
flex-direction
Встановлює основну вісь, таким чином визначаючи напрям flex елементів, які розміщені в flex контейнер. Flexbox - це (крім додаткової упаковки) концепція односпрямованого макета. Думайте про flex елементи, як про первинні розкладки в горизонтальних рядах або вертикальних шпальтах.
.container { flex-direction: row | row-reverse | column | column-reverse; }
- row (за замовчуванням): зліва направо в
ltr
; справа наліво вrtl
- row-reverse справа наліво
ltr
; зліва направо вrtl
- column: так само, як і row але зверху вниз
- column-reverse: те ж саме, row-reverse але знизу вгору
flex-wrap
За замовчуванням гнучкі елементи будуть намагатися вміститися на одному рядку. Ви можете змінити це і дозволити елементам переходити на новий рядок у міру необхідності за допомогою цієї властивості.
.container{ flex-wrap: nowrap | wrap | wrap-reverse; }
- nowrap (за замовчуванням): всі flex елементи будуть в одному рядку
- wrap: flex-елементи будуть перенесені на кілька рядків зверху вниз.
- wrap-reverse: flex-елементи будуть перенесені на кілька рядків від низу до верху.
Подивитися візуальні демоверсії поведінки flex-wrap можна тут .
flex-flow (Застосовується до: батьківського елементу flex-контейнера)
Це скорочення для flex-direction
і flex-wrap
властивостей, які разом визначають основні і поперечні осі flex контейнера. Значення за замовчуванням row nowrap
.
flex-flow: ||
justify-content
Ця властивість визначає вирівнювання вздовж головної осі. Він сприяє ефективному розподілу додатковий залишок вільного простору, коли-небудь все flex елементи в рядку негнучкі, або гнучкі, але досягли свого максимального розміру. Це також забезпечує деякий контроль над вирівнюванням елементів, коли вони переповнюють лінію.
.container { justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe; }
- flex-start (за замовчуванням): елементи зрушені в початок flex-direction напрямку.
- flex-end: елементи зрушені ближче до кінця flex напрямку.
- start: елементи зрушені до початку
writing-mode
напрямку. - end: елементи зрушені в кінці
writing-mode
напрямку. - left: елементи зрушені в напрямку до лівого краю контейнера, але якщо це не має сенсу з
flex-direction
, тоді він веде себе якstart
. - right: елементи зрушені в напрямку до правого краю контейнера, але якщо це не має сенсу з
flex-direction
, тоді він веде себе якstart
. - center: елементи центровані уздовж лінії
- space-between: елементи рівномірно розподілені по лінії; перший елемент знаходиться на початку рядка, останній елемент в кінці рядка
- space-around: елементи рівномірно розподілені по лінії з однаковим простором навколо них. Зверніть увагу, що візуально простори не рівні, оскільки всі елементи мають однаковий простір по обидва боки. Перший елемент матиме одну одиницю простору навпроти краю контейнера, але дві одиниці простору між наступним елементом, тому що у наступного елемента є свій власний інтервал, який застосовується.
- space-evenly: елементи розподіляються таким чином, щоб відстань між будь-якими двома елементами (і відстань до країв) було однаковим.
Зверніть увагу, що підтримка браузером цих значень має свої нюанси. Наприклад, space-between
ніколи не підтримувався в Edge, а start/end/left/right ще не підртимується в Chrome. У MDN є докладні графіки. Найбезпечніші значення це flex-start
, flex-end
і center
.
Є також два додаткових ключових слова, які ви можете пов'язати з цими значеннями: safe
та unsafe
. Використання safe
гарантує, що як би ви не займалися цим типом позиціонування, ви не зможете розташувати елемент таким чином, щоб він відображався за межами екрану (наприклад, зверху) так, щоб вміст не можна було прокручувати (це називається «втрата даних»).
align-items
Це властивість визначає поведінку за замовчуванням того, як flex елементи розташовуються уздовж поперечної осі на поточній лінії. Думайте про це як про justify-content
версії для поперечної осі (перпендикулярної головної осі).
.container { align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe; }
- stretch (за замовчуванням): розтягувати, щоб заповнити контейнер (все ще дотримуються
min-width
/max-width
) - flex-start / start / self-start: елементи розміщуються на початку поперечної осі. Різниця між ними невелика і полягає в дотриманні
flex-direction
абоwriting-mode
правил. - flex-end / end / self-end: елементи розташовуються в кінці поперечної осі. Різниця знову-таки тонка і полягає в дотриманні
flex-direction
абоwriting-mode
правил. - center: елементи центровані по поперечній осі
- baseline: елементи вирівняні по їх базової лінії
safe
та unsafe
ключові слова модифікаторів можуть бути використані в поєднанні з усіма з цих ключових слів ( хоча це підтримується не всіма браузерами ), це допомагає запобігти вирівнюванню елементів таким чином, що зміст стає недоступним.
align-content
Ця властивість вирівнює лінії в межах flex контейнера, коли є додатковий простір на поперечній осі, подібно до того, як justify-content
вирівнює окремі елементи в межах головної осі.
Примітка: ця властивість не діє, коли є тільки один рядок flex елементів.
.container { align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe; }
- flex-start / start: елементи, зрушені в початок контейнера.
flex-start
який має більшу підтримку використовує,flex-direction
в той час якstart
використовуєwriting-mode
напрямок. - flex-end / end: елементи, зрушені в кінець контейнера.
flex-end
який має більшу підтримку використовуєflex-direction
в той час якend
використовує напрямокwriting-mode
. - center: елементи вирівняні по центру в контейнері
- space-between: елементи рівномірно розподілені; перший рядок знаходиться на початку контейнера, а останній - в кінці
- space-around: елементи рівномірно розподілені з рівним простором навколо кожного рядка
- space-evenly: елементи розподілені рівномірно, навколо них однаковий простір
- stretch (за замовчуванням): лінії розтягуються, щоб зайняти простір який залишився
safe
і unsafe
ключові слова модифікаторів можуть бути використані в поєднанні з усіма з цих ключових слів (хоча це підтримується не всіма браузерами), це допомагає запобігти вирівнюванню елементів таким чином, що зміст став недоступним.
Властивості для перших дочірніх елементів (flex елементи)
order
За замовчуванням flex елементи розташовуються в початковому порядку. Однак властивість order управляє порядком їх появи в контейнері flex.
.item { order: ; /* default is 0 */ }
flex-grow
Ця властивість визначає здатність flex елемента розтягуватися в разі потреби. Воно приймає значення від нуля, яке служить пропорцією. Це вказує яку кількість доступного простору всередині гнучкого контейнера повинен займати елемент.
Якщо для всіх елементів flex-grow
встановлено значення 1, вільний простір в контейнері буде рівномірно розподілено між усіма дочірніми елементами. Якщо один з дочірніх елементів має значення 2, цей елемент займе в два рази більше місця, ніж інші (або принаймні спробує).
.item { flex-grow: ; /* default 0 */ }
Негативні числа не підтримуються.
flex-shrink
Ця властивість визначає здатність гнучкого елемента стискатися при необхідності.
.item { flex-shrink: ; /* default 1 */ }
Негативні числа не підтримуються.
flex-basis
Ця властивість визначає розмір елемента за замовчуванням перед розподілом простору, що залишився. Це може бути довжина (наприклад, 20%, 5rem і т.д.) Або ключове слово. Ключове слово auto
означає «дивись на моє значення width або height». Ключове слово content
означає «розмір на основі вмісту елемента» - це ключове слово все ще не дуже добре підтримується, так що важко перевірити що для нього використовується max-content
, min-content
або fit-content
.
.item { flex-basis: | auto; /* default auto */ }
Якщо встановлено значення 0 , додатковий простір навколо вмісту не враховується. Якщо встановлено значення auto
, додатковий простір розподіляється в залежності від його значення flex-grow
.
flex
Це скорочення для використання flex-grow
, flex-shrink
і flex-basis
разом. Другий і третій параметри (flex-shrink
і flex-basis
) є необов'язковими. За замовчуванням це 0 1 auto
.
.item { flex: none | [ ? || ] }
Рекомендується використовувати цю скорочену властивість , а не встановлювати окремі властивості. Це скорочення розумно встановлює інші значення.
align-self
Ця властивість дозволяє перевизначити вирівнювання за замовчуванням (або вказане за допомогою align-items
) для окремих елементів flex.
Дивіться на властивість align-items
, щоб зрозуміти доступні значення.
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
Зверніть увагу що властивості float
, clear
і vertical-align
не впливають на flex елементи.
Приклади
Давайте почнемо з дуже простого прикладу, вирішення майже щоденної проблеми: ідеальне центрування. Найпростіше рішення для цього завдання - це використовувати flexbox.
.parent { display: flex; height: 300px; /* Або що завгодно */ } .child { width: 100px; /* Або що завгодно */
height: 100px; /* Або що завгодно */
margin: auto; /* Магія! */ }
Так відбувається завдяки тому, що властивість вертикального вирівнювання margin встановлена в auto
у flex контейнері, поглинає додатковий простір. Таким чином, установка margin в auto
зробить об'єкт ідеально відцентрувати по обох осях.
Тепер давайте використаємо ще кілька властивостей. Розглянемо список з 6 елементів, всі з фіксованими розмірами, але можуть бути і автоматично масштабовані. Ми хочемо, щоб вони були рівномірно розподілені по горизонтальній осі, щоб при зміні розміру браузера все масштабувати добре і без медіа запитів.
.flex-container { /* Спочатку ми створюємо flex контест */ display: flex; /* Далі ми визначаємо flex-direction і дозволяємо елементам переходити на нові рядки * Запам'ятайте що це не те саме що і: * 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 елементів! Як щодо 3-колонкового макета в повну висоту сторінки з хедором і футером. І незалежного від вихідного порядку елементів.
.wrapper { display: flex; flex-flow: row wrap; } /* Ми вказуємо, що всі елементи мають ширину 100% через flex-base */ .wrapper > * { flex: 1 100%; } /* Ми використовуємо вихідний порядок для першого мобільно варіанти * 1. header * 2. article * 3. aside 1 * 4. aside 2 * 5. footer */ /* Середні екрани */ @media all and (min-width: 600px) { /* Ми говоримо обом бічним панелям розділити один рядок*/ .aside { flex: 1 auto; } } /* Великі екрани */ @media all and (min-width: 800px) { /* Ми інвертуємо порядок першої бічної панелі і основної
* та говоримо головному елементу, щоб він займав вдвічі більшу ширину, ніж дві інші бічні панелі */ .main { flex: 2 0px; } .aside-1 { order: 1; } .main { order: 2; } .aside-2 { order: 3; } .footer { order: 4; } }
Результат:
Великі екрани
Середні екрани
Маленькі екрани
Префікс для Flexbox
Flexbox вимагає префікса для кращої підтримки в різних браузерах. Він не тільки включає в себе попередні налаштування з префіксом вендора, в ньому є абсолютно різні імена властивостей і значень. Це пов'язано з тим, що специфікації Flexbox з часом змінювалися, існують «старі», «tweener» і «нові» версії.
Можливо, найкращий спосіб впоратися з цим - написати новий (і останній) синтаксис і запустити свій CSS через Autoprefixer, який дуже добре справляється з fallback.
Крім того, ось 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); }
Помилки
Flexbox, звичайно, не без помилок. Краща колекція з них, яку я бачив, - це Flexbugs Філіпа Уолтона і Грега Вітворта. Це сховище з відкритим вихідним кодом для відстеження їх всіх, тому я думаю, що краще за все просто послатися на нього.
Підтримка в браузерах
Розбита по «версії» flexbox:
- (new) означає недавній синтаксис зі специфікації (наприклад display: flex; )
- (tweener) означає дивний неофіційний синтаксис з 2011 року (наприклад display: flexbox; )
- (old) означає старий синтаксис з 2009 року (наприклад display: box; )
Blackberry Browser 10+ підтримує новий синтаксис.
Для отримання додаткової інформації про те, як змішувати синтаксиси, щоб отримати кращу підтримку браузера, будь ласка, зверніться до цієї статті (CSS-хитрості) або цієї статті (DevOpera) .
Джерело: css-tricks.com
Ще немає коментарів