Повне керівництво по Flexbox

Повне керівництво по Flexbox
16 хв. читання
11 жовтня 2020

Це повне керівництво пояснює все про 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». Будь ласка, подивіться на цей малюнок зі специфікації, яка пояснювала б основну ідею гнучкого макета.Повне керівництво по FlexboxЕлементи будуть розташовані або в напрямку головної осі ( 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 контейнер)

Повне керівництво по Flexbox

display

Визначає flex контейнер; inline або block в залежності від заданого значення. Включає flex контекст для всіх нащадків першого рівня.

.container {
  display: flex; /* or inline-flex */
}

Зверніть увагу, що CSS-стовпці columns не впливають на flex контейнер.

flex-direction

Повне керівництво по FlexboxВстановлює основну вісь, таким чином визначаючи напрям 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

Повне керівництво по FlexboxЗа замовчуванням гнучкі елементи будуть намагатися вміститися на одному рядку. Ви можете змінити це і дозволити елементам переходити на новий рядок у міру необхідності за допомогою цієї властивості.

.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

Повне керівництво по FlexboxЦя властивість визначає вирівнювання вздовж головної осі. Він сприяє ефективному розподілу додатковий залишок вільного простору, коли-небудь все 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

Повне керівництво по FlexboxЦе властивість визначає поведінку за замовчуванням того, як 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

Повне керівництво по FlexboxЦя властивість вирівнює лінії в межах 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 елементи)

Повне керівництво по Flexbox

order

Повне керівництво по FlexboxЗа замовчуванням flex елементи розташовуються в початковому порядку. Однак властивість order управляє порядком їх появи в контейнері flex.

.item {
  order: ; /* default is 0 */
}

flex-grow

Повне керівництво по FlexboxЦя властивість визначає здатність 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.

Повне керівництво по Flexbox

flex

Це скорочення для використання flex-growflex-shrink і flex-basis разом. Другий і третій параметри (flex-shrink і flex-basis) є необов'язковими. За замовчуванням це 0 1 auto .

.item {
  flex: none | [  ? ||  ]
}

Рекомендується використовувати цю скорочену властивість , а не встановлювати окремі властивості. Це скорочення розумно встановлює інші значення.

align-self

Повне керівництво по FlexboxЦя властивість дозволяє перевизначити вирівнювання за замовчуванням (або вказане за допомогою align-items) для окремих елементів flex.

Дивіться на властивість align-items, щоб зрозуміти доступні значення.

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

Зверніть увагу що властивості floatclear і 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;
}

Готово. Все інше - це просто стайлінг.Повне керівництво по FlexboxЯкщо змінити роздільну здатність екрана чи масштаб, то буде так:Повне керівництво по FlexboxДавайте спробуємо що-небудь ще. Уявіть, що у нас є вирівняні по правому краю елементи навігації у верхній частині нашого веб-сайту, але ми хочемо, щоб вони були вирівняні по ширині на екранах середнього розміру і розташовувалися в один стовпець на невеликих пристроях. Це досить просто.

/* Великі екрани */
.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;
  }
}

Результат:

Великі екрани

Повне керівництво по Flexbox

Середні екрани

Повне керівництво по Flexbox

Маленькі екрани

Повне керівництво по Flexbox

Давайте спробуємо щось ще краще, граючи з гнучкістю 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Префікс для 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; )

Повне керівництво по FlexboxBlackberry Browser 10+ підтримує новий синтаксис.

Для отримання додаткової інформації про те, як змішувати синтаксиси, щоб отримати кращу підтримку браузера, будь ласка, зверніться до цієї статті (CSS-хитрості) або цієї статті (DevOpera) .

Джерело: css-tricks.com

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація