Полное руководство по css flex + опыт использования

Выравнивание flex-элементов

Во Flexbox выравнивание элементов внутри контейнера осуществляется по двум направлениям (осям).

Выравнивание flex-элементов по направлению главной оси

Выравнивание элементов вдоль основной оси осуществляется с помощью CSS свойства :

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

Выравнивание flex-элементов вдоль поперечной оси

Выравнивание flex-элементов во flex-контейнере по направлению поперечной оси осуществляется с помощью CSS-свойства :

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 (равномерно, но с добавлением половины  пространства перед первой линией и после последней) */

Свойство имеет смысл использовать только тогда, когда flex-элементы во flex-контейнере располагаются на нескольких линиях. Чтобы это произошло, необходимо, во-первых, чтобы ширина всех flex-элементов была больше ширины flex-контейнера, а во-вторых flex-контейнер должен иметь в качестве CSS-свойства значение или .

CSS-свойство align-self

Свойство в отличие от предыдущих (, и ) предназначено для flex-элементов. Оно позволяет изменить выравнивание flex-элемента вдоль направления поперечной оси. Свойство может принимать такие же значения как .

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;
}

Когда не стоит использовать флексы?

Мы рассмотрели некоторые причины, по которым думаю, cтоит выбирать флексы вместо раскладки на гридах, поэтому можем посмотреть на некоторые случаи, когда флекс — не лучший вариант. Мы уже посмотрели на пример с флексом против грида, где элементы выровнены по горизонтали и вертикали в отличие от элементов, которые занимают место построчно. И это различие стоит учитывать в первую очередь.

Вот пример грида с двумерной раскладкой. Раскладка одновременно и в строках, и в колонках. Пример на флексах — это одномерная раскладка. Мы позволили перенос флекс-строк, но распределение места на строке ведётся построчно. Каждая строка естественно ведёт себя как новый флекс-контейнер по направлению главной оси.

Следовательно, если компоненту нужна двумерная раскладка, лучше будет использовать гриды вместо флексов

Неважно, большой или маленький у вас компонент. Если запомните из этой статьи только одно, пусть это будет следующее: выкиньте из головы идею о том, что гриды предназначены только для основной раскладки страницы, а флексы — для компонентов

У вас может быть крошечный компонент, которому требуется двумерная раскладка, и структура главной страницы, которой лучше подойдёт одномерная раскладка.

Ещё один хороший пример, где гриды будут лучшим решением: если вы задаёте ширину или базовый размер флекса по главной оси — как единицу длины для ваших элементов, для того чтобы выровнять их с другим рядом таких же элементов, или чтобы каким-то образом ограничить гибкость. Довольно часто это показатель того, что вам нужна двумерная раскладка, или того, что вашей раскладке лучше подойдёт контроль со стороны контейнера сетки.

Например, мы можем сделать нашу раскладку на флексах более похожей на гриды, ограничив гибкость элементов. Задайте свойство  и выставите размеры элементов в процентах, подобно тому, как мы поступали с размерами элементов в раскладке на флоатах. Если обнаружите, что поступаете так, предположу, что раскладка на гридах подойдёт вам лучше, ведь она и была создана для этого.

See the Pen Smashing Flexbox Series 4: wrapped flex items with percentage widths by rachelandrew (@rachelandrew) on CodePen.

Принимая во внимание всё вышесказанное, помните, что часто нет чёткого правильного или неправильного ответа. Иногда единственное, что можно сделать — это попробовать разные варианты и посмотреть, что лучше всего подходит этому компоненту

Помните, что также можно переключаться между методами раскладки, используя флексы на одной контрольной точке и гриды на другой.

Свойство Flex-Grow

flex-grow устанавливает коэффициент роста, который позволяет flex элементу увеличиваться и заполнять доступное пространство. Значение flex-grow принимает только целое число

Обратите внимание на следующее

<div class="wrapper">
  <div class="item item-1"></div>
  <div class="item item-2"></div>
  <div class="item item-3"></div>
</div>
.wrapper {
    display: flex;
    flex-wrap: wrap;
}

.item {
    flex-grow: 1;
}

Обратите внимание, что без использования flex-grow ширина элементов flex по умолчанию будет равна их начальной ширине. Однако при использовании flex-grow: 1 доступное пространство распределялось между ними

Вам может быть интересно, как пространство распределяется между flex элементами? Что ж, это хороший вопрос, и я скоро на него отвечу.

На приведенном ниже рисунке показано, как элементы выглядят без flex-grow. Другими словами, это их естественный размер.

Чтобы понять, как рассчитывается ширина flex элемента, см. уравнение ниже. Я узнал об уравнении из этого поста Саманты Минг (Спасибо!).

Давайте посчитаем размер элемента, содержащего текст «CSS».

Ширина элемента (width) = ( (flex-grow / общее кол-во flex-grow) * доступное пространство) + начальная ширина элементов

Flex-grow: коэффициент увеличения flex для элемента

Total flex-grow: суммирование значения flex-grow для всех flex элементов

Available space: перед применением flex-grow

Item width: начальная ширина элемента

—> Item width = ( (1 / 3) * 498) + 77 = 241

Множественные 

В предыдущем примере значение flex-grow одинаково для всех flex элементов. Давайте попробуем добавить flex-grow: 2 для первого элемента. Как это будет рассчитываться? Имейте в виду, что доступное пространство для нашего примера составляет 498 пикселей.

Надеюсь, теперь стало понятнее.

Можем ли мы использовать 0 как значение ?

Конечно! Поскольку свойство flex-grow принимает целочисленные значения, можно использовать 0 как способ предотвратить использование flex элемента для расширения на доступное пространство.

Это может быть полезно в особых случаях, когда мы хотим, чтобы flex элемент оставался с его начальной шириной.

Flex Grow не делает Flex элементы одинаковыми

Существует распространенное заблуждение, что использование flex-grow сделает элементы равными по ширине. Это неверно. Идея использования flex-grow заключается в распределении доступного пространства. Как вы видели в уравнении, ширина каждого гибкого элемента рассчитывается на основе его начальной ширины (ширина до применения flex-grow).

Если вы хотите, чтобы flex элементы были одинаковой ширины, это можно сделать с помощью flex-basis. Я объясню это в следующих разделах.

Случаи использования

Аватар пользователя

Типичный вариант использования flexbox — пользовательский компонент. Аватар и текстовое содержимое должны находиться в одной строке.

<div class="user">
	<img class="user__avatar" src="shadeed.jpg" alt="" />
	<div>
		<h3>Ahmad Shadeed</h3>
		<p>Author of Debugging CSS</p>
	</div>
</div>
.user {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
}

.user__avatar {
    flex: 0 0 70px;
    width: 70px;
    height: 70px;
}

Обратите внимание, что я добавил для аватара flex: 0 0 70px

Это важно, поскольку в некоторых старых браузерах изображение может выглядеть сжатым, если не установлен параметр flex. Кроме того, flex имеет более высокий приоритет, чем свойство width (в случае flex-direction: row) или height (в случае flex-direction: column)

Кроме того, flex имеет более высокий приоритет, чем свойство width (в случае flex-direction: row) или height (в случае flex-direction: column).

Если мы изменим размер аватара, настроив только свойство flex, width будет проигнорирована браузером.

.user__avatar {
    /* width будет 100px, а не 70px */
    flex: 0 0 100px;
    width: 70px;
    height: 70px;
}

Заголовок раздела

У вас есть title для заголовка раздела, и он должен занимать все доступное пространство. В этом случае идеально подходит flex: 1.

.page-header {
    display: flex;
    flex-wrap: wrap;	
}

.page-header__title {
    flex: 1;
}

Элемент Input для отправки сообщений

Это очень распространено в приложениях для обмена сообщениями, таких как Facebook Messenger или Twitter. Входные данные должны заполнять доступное пространство с фиксированной шириной для кнопки отправки.

form {
    display: flex;
    flex-wrap: wrap;	
}

input {
    flex: 1;
    /* Другие стили */
}

Приведенные выше примеры являются полезными примерами использования flex-grow. Однако некоторые случаи игнорируются или вообще не упоминаются в некоторых статьях по flex. Давайте рассмотрим их!

Выравнивание элементов на двух картах

Предположим, что CSS-сетка имеет макет из двух столбцов. Проблема в том, что положение дат не совпадают. Они должны быть на одной линии (красной).

Мы можем сделать это с помощью flexbox.

<div class="card">
	<img src="thumb.jpg" alt="">
	<h3 class="card__title">Title short</h3>
	<time class="card__date"></time>
</div>

Устанавливая flex-direction: column мы можем использовать flex-grow для заголовка, чтобы он заполнял доступное пространство и, таким образом, размещал дату в конце, даже если заголовок короткий.

.card {
    display: flex;
    flex-direction: column;
}

/* Первое решение */
.card__title {
    flex-grow: 1;
}

Кроме того, это возможно без использования flex-grow. Благодаря auto margins и flexbox! Я написал подробную статью об auto в CSS, если вы хотите вникнуть в подробности.

/* Второе решение */
.card__date {
    margin-top: auto;
}

Wrapping Flex Lines Forward and in Reverse

This section is an introduction to flex-wrap property whose default value is nowrap.

flex-wrap property can be set to nowrap, wrap and wrap-reverse.

All 3 values produce different results. Let’s take a look at visual examples of what happens here.

By default flex container will not wrap your content. In which case it acts as a weird imitation of something similar to overflow: hidden;, except it doesn’t really stop rendering your content. No matter how many items you have they will «overflow» off the edge of your main container.

Here’s an example of flex container with too many items to fit on one line:

A
B
C
D
E
F

And here is the same flex example with flex-wrap set to wrap:

A
B
C
D
E
F

A value of wrap-reverse will produce the following result:

A
B
C
D
E
F

The first item is now positioned in lower left corner and the items wrap upward. Note that the direction flow of items (from left to right) is still identical to previous example. We only changed direction of the wrap, not direction of the items on the axis lane.

We’ve taken first step toward creating grid-like flex layouts!

There is more to flex direction and flex wrap. You can use a shorthand property flex-flow which allows you to set them together. And if you want to learn that, expand the next section.

Insert flex-flow content here

Next thing you want to learn is align-content property.

Управление потоком внутри Flex-контейнера

В стандартной блочной модели CSS элементы обычно отображаются в том порядке, в котором они объявлены в основной разметке HTML. Flex-модель позволяет контролировать очередность элементов внутри гибкого контейнера таким образом, чтобы элементы можно было размещать в любом направлении потока влево, вправо, вниз или даже вверх.

Поток flex-элементов во flex-контейнере можно указать с помощью свойства . Значением этого свойства по умолчанию является , оно совпадает с текущим режимом объявления элементов в документе или с направлением текста, например, слева направо на английском языке.

Аналогично, вы можете отображать flex-элементы внутри flex-контейнера в столбцах, а не в строке, используя значение для свойства , например так:

Две оси

Главную ось, которую определяет , мы уже видели. Поперечная ось – это другое измерение. Если установлено , то главная ось идет горизонтально, а поперечная – вертикально. При   – наоборот. Но все не так просто!

В модели Flexbox строки не всегда идут слева направо, а столбцы – снизу вверх.

Направление письма

Английский язык (как и русский) имеет горизонтальное направление письма. Это значит, что флексбокс-ряд соответствует обычной горизонтальной строке. В этом случае будет слева – там, где в английском (и русском) начинаются предложения.

Если вы работаете с арабским языком (направление письма справа налево), то строка (а вместе с ней и флексбокс-ряд) будет начинаться справа:

See the Pen
Smashing Flexbox Series 1: row with rtl text by rachelandrew (@rachelandrew)
on CodePen.

В языках с вертикальным направлением письма строки идут сверху вниз и флексбокс-ряды тоже. Попробуйте добавить флекс-контейнеру свойство и установите  – вы получаете вертикальный столбец элементов.

See the Pen
Smashing Flexbox Series 1: row with a vertical writing mode by rachelandrew (@rachelandrew)
on CodePen.

Таким образом, ряд может идти горизонтально, слева или справа, а также вертикально сверху. И это все еще , даже если нам, привыкшим к горизонтальному тексту, сложно это понять!

Это измерение строки, а еще есть измерение блоков. Оно соответствует тому, как в тексте размещаются абзацы. В английском, русском и арабском языке – сверху вниз. Расположить флекс-элементы в этом измерении можно с помощью значений  или  для свойства .

При вертикальном направлении письма блочное измерение проходит по горизонтали. Если вы создадите столбец в режиме , то элементы будут отображаться слева направо:

See the Pen
Smashing Flexbox Series 1: column in vertical-lr writing mode by rachelandrew (@rachelandrew)
on CodePen.

Независимо от того, как отображаются блоки, если вы работаете со значением , вы работаете в блочном измерении.

Очень важно понимать, что расположение флекс-элементов определяется направлением письма конкретного языка. Запомните следующее:

Запомните следующее:

  • flex-direction: row
    • главная ось — строчное измерение
    • — место, где начинается предложение
    • поперечная ось — блочное измерение
  • flex-direction: column
    • главная ось — блочное измерение
    • — место, где начинаются блоки
    • поперечная ось — инлайновое измерение

Запасное выравнивание

Для каждого метода выравнивания описан запасной вариант — что произойдёт, если заданное выравнивание невозможно. Например, если у вас есть только один элемент в контейнере, а вы указали justify-content: space-between , что должно произойти? В этом случае применяется запасное выравнивание flex-start — один элемент будет выровнен по началу контейнера. В случае justify-content: space-around используется запасное выравнивание center .

В текущей спецификации вы не можете изменить запасное выравнивание. Есть примечание к спецификациям, которое допускает возможность указания произвольного запасного варианта в будущих версиях.

Свойства flex-контейнера

Существует шесть основных CSS-свойств для работы с flex-контейнером:

  • ;
  • ;
  • ;
  • ;
  • ;
  • .

Но прежде чем мы рассмотрим каждый более подробно, поговорим об осях, присутствующих во flex-контейнере. Их две: главная (основная) ось по умолчанию располагается горизонтально — слева направо, и распределение flex-элементов, добавляемых в контейнер, происходит вдоль нее. Поперечная ось расположена перпендикулярно основной и служит для выравнивания содержимого контейнера по вертикали.

Flex-direction

Мы уже говорили о направлении главной оси по умолчанию (слева-направо) — это не строгое правило. Направлением можно управлять, то есть переопределять расположение гибких блоков с помощью свойства . Оно имеет четыре значения:

1( значение по умолчанию), построение элементов слева направо:

Свойство flex-direction: row выстраивает элементы слева направо

2: при таком значении строка переворачивается и flex-элементы становятся в обратном порядке, теперь уже справа налево:

Свойство flex-direction: row-reverse выстраивает элементы справа налево

3: при таком значении основная ось становится вертикальной, располагая все свои элементы сверху вниз (в столбик):

Свойство flex-direction: column располагает элементы сверху вниз

4: переворачивает наш столбик, расположив элементы в обратном направлении:

Свойство flex-direction: column-reverse переворачивает столбик

Flex-wrap

Используя это свойство, не поместившиеся в одну линию элементы можно переместить на следующую строчку. Это полезно применять в адаптивных макетах, когда при изменении размера экрана гибкие элементы автоматически меняют свое положение. По умолчанию для параметра  установлено значение .

Например, создадим шесть flex-элементов внутри нашего контейнера, чтобы посмотреть, как работает этот параметр и выясним, какие значения он может принимать.

1:

Свойство flex-wrap: wrap перемещает блоки на строку ниже

Мы видим, что два блока переместились на строчку ниже, сохранив необходимый интервал.

2:

Свойство flex-wrap: nowrap — элементы могут выйти за границы контейнера

Если ничего не менять и оставить значение по умолчанию, элементы выстроятся в одну строку и, возможно, выйдут за границы контейнера, что и случилось на изображении выше.

3:

Свойство flex-wrap: wrap-reverse зеркально отразит элементы

Такое значение понадобится, если мы захотим перенести блоки на другую строчку, но в обратном порядке. Так получится зеркальное отражение, прямо как в нашем примере.

Flex-flow

Свойство объединяет выше рассмотренные и В нем значение каждого параметра пишется через пробел:

Свойства пишутся через пробел

Justify-content

Используя свойство , мы можем выровнять элементы flexbox по горизонтали. Оно имеет пять основных значений:

1:

Свойство justify-content: center центрирует блоки

Нетрудно догадаться из названия параметра, что при таком значении свойства блоки во flex-контейнере выравниваются по центру (центрируются).

2:

Свойство justify-content: flex-start выстраивает элементы относительно начала главной оси

Это значение по умолчанию, при котором элементы контейнера выстраиваются относительно начала главной оси.

3:

Свойство justify-content: flex-end сдвинет элементы к концу главной базовой линии контейнера

При таком значении все внутренние элементы сдвинутся к концу главной базовой линии контейнера.

4:

Свойство justify-content: space-between расставит блоки на одинаковом расстоянии

Свойство  расставит наши блоки в строке на одинаковом расстоянии, при этом первый элемент находится в самом начале строки, а последний — прижимается к концу.

5:

Свойство justify-content: space-around создаст вокруг элементов одинаковые интервалы

При предоставлении параметра вокруг элементов образовались одинаковые интервалы. Но тут надо помнить, что у первого элемента левый интервал будет равен х, а правый — 2x. Это получилось, поскольку у следующего за ним элемента также будет интервал x — и поэтому они складываются. То же правило применяется к последнему элементу.

align-self

Copied!

Copied!

Copied!

Copied!

Copied!

Свойство align-self выравнивает флекс-элементы текущей строки, переписывая значение align-items.

Применяется кo: flex элементам.

Значение по умолчанию: auto.

flex-start
Элемент выравнивается в начале поперечной оси контейнера.
flex-end
Элемент выравнивается в конце поперечной оси контейнера.
center
Элемент выравнивается по центральной линии на поперечной оси.
baseline
Элемент выравнивается по базовой линии текста.
Stretch
Элемент растягивается таким образом, чтобы занять всё свободное пространство контейнера по поперечной оси.

Flex items can be aligned in the cross axis of the current line of the flex container, similar to justify-content but in the perpendicular direction. align-items sets the default alignment for all of the flex container’s items, including anonymous flex items. align-self allows this default alignment to be overridden for individual flex items. (For anonymous flex items, align-self always matches the value of align-items on their associated flex container.)

If either of the flex item’s cross-axis margins are align-self has no effect.

On absolutely positioned elements, a value of auto computes to itself. On all other elements, a value of auto for align-self computes to the value of align-items on the element’s parent, or stretch if the element has no parent. The alignments are defined as:

Applies to: flex items.

Initial: auto.

flex-start
The cross-start margin edge of the flex item is placed flush with the cross-start edge of the line.
flex-end
The cross-end margin edge of the flex item is placed flush with the cross-end edge of the line.
center
The flex item’s margin box is centered in the cross axis within the line. (If the cross size of the flex line is less than that of the flex item, it will overflow equally in both directions.)
baseline
If the flex item’s inline axis is the same as the cross axis, this value is identical to flex-start. Otherwise, it participates in baseline alignment: all participating flex items on the line are aligned such that their baselines align, and the item with the largest distance between its baseline and its cross-start margin edge is placed flush against the cross-start edge of the line.
Stretch
If the cross size property of the flex item computes to auto, and neither of the cross-axis margins are auto, the flex item is stretched. Its used value is the length necessary to make the cross size of the item’s margin box as close to the same size as the line as possible, while still respecting the constraints imposed by ///. Note: If the flex container’s height is constrained this value may cause the contents of the flex item to overflow the item.The cross-start margin edge of the flex item is placed flush with the cross-start edge of the line.
Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Люкс-хост
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: