--- title: Flexbox slug: Learn/CSS/CSS_layout/Flexbox tags: - CSS - Обучение - Стилизация translation_of: Learn/CSS/CSS_layout/Flexbox ---
{{LearnSidebar}}
{{PreviousMenuNext("Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout/Grids", "Learn/CSS/CSS_layout")}}

Это новая технология, которая уже имеет достаточно широкую поддержку браузеров. Flexbox предоставляет инструменты для быстрого создания сложных, гибких макетов, и функции, которые были сложны в традиционных методах CSS. В этой статье объясняются все основы данной технологии.

Необходимые навыки: HTML основы (изучите Введение в HTML), знание того, как работает CSS (изучите Вступление в CSS).
Цель: Узнать, как использовать систему адаптируемых блоков Flexbox для создания веб-макетов.

Почему Flexbox?

Долгое время единственными надёжными инструментами CSS вёрстки были такие способы как Float (обтекание) и позиционирование.

С их помощью сложно или невозможно достичь следующих простых требований к макету:

Как вы увидите в последующих разделах, flexbox значительно облегчает работу с макетами. Погружаемся!

Разберём простой пример

В этой статье вы проработаете серию упражнений, которые помогут понять, как работает flexbox. Чтобы начать, скачайте на компьютер стартовый файл — flexbox0.html с нашего Github репозитория — загрузите его в современном браузере (Firefox или Chrome), а также в любимом редакторе кода. Также вы можете посмотреть его вживую.

Вы увидите элемент {{htmlelement("header")}} с заголовком верхнего уровня внутри, и элемент {{htmlelement("section")}} содержащий три элемента {{htmlelement("article")}}. Мы будем использовать их для создания стандартного трёхколоночного макета.

Определяем, какие элементы разместить в виде flex блоков

Для начала нам нужно выбрать, какие элементы следует выкладывать в виде flex блоков. Для этого мы устанавливаем специальное значение {{cssxref ("display")}} в родительском элементе тех элементов, которые вы хотите оформить. В нашем случае мы хотим расположить элементы {{htmlelement ("article")}}, поэтому мы устанавливаем это значение на {{htmlelement ("section")}} (который становится flex контейнером):

section {
  display: flex;
}

В результате у нас получится вот так:

Так, всего одно объявление делает всё, что нам нужно — здорово, правда? Мы получили 3-х колоночный макет с колонками равных размеров по ширине и высоте. Это связано с тем, что значения по умолчанию, заданные для flex элементов (дочерние элементы flex контейнера), настроены для решения основных задач. Подробнее об этом позже.

Примечание: вы также можете установить значение {{cssxref("display")}} inline-flex, если хотите расставить inline элементы как flex блоки.

Внутри flex модели

Когда элементы выложены как flex блоки, они располагаются вдоль двух осей:

flex_terms.png

Запомните эти термины, они пригодятся вам в последующих разделах.

Столбцы или строки?

В Flexbox есть свойство под названием {{cssxref("flex-direction")}}, которое определяет направление главной оси (в каком направлении располагаются flexbox-дочерние элементы) — по умолчанию ему присваивается значение row, т.е. располагать дочерние элементы в ряд слева направо (для большинства языков) или справа налево (для арабских языков).

Попробуйте добавить следующую строчку в ваш файл:

flex-direction: column

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

Примечание: вы можете также располагать flex элементы в обратном направлении, используя значения row-reverse и column-reverse. Попробуйте их тоже!

Перенос строк

Проблема может быть в том, что, если у вас фиксированная ширина или высота макета, ваши flexbox элементы переполнят контейнер и нарушат макет. Посмотрите на этот пример: flexbox-wrap0.html и посмотрите его вживую (сохраните его себе на компьютер, если хотите изучить этот пример):

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

flex-wrap: wrap

Попробуйте, и вы увидите, что так макет стал выглядеть гораздо лучше:

Теперь у нас в макете несколько рядов— все дети-блоки, которые не помещаются, переносятся на следующую строку, чтобы не было переполнения. Свойство flex: 200px, установленное на статьях, означает, что каждый блок должен быть минимум 200 пикселей в ширину. Мы обсудим это свойство более подробно позже. Вы также можете заметить, что несколько дочерних блоков в последней строке стали более широкими, так что вся строка стала заполнена.

Но мы можем пойти дальше. Прежде всего, попробуйте изменить значение свойства {{cssxref("flex-direction")}} на row-reverse — теперь у вас также макет в несколько строк, но он начинается из противоположного угла окна браузера и теперь выстраивается в обратном порядке.

flex-flow сокращение

На этом этапе нужно заметить, что существует сокращение для свойств {{cssxref("flex-direction")}} и {{cssxref("flex-wrap")}} — {{cssxref("flex-flow")}}. Например, вы можете заменить

flex-direction: row;
flex-wrap: wrap;

на

flex-flow: row wrap;

Гибкое изменение размеров flex элементов

Теперь давайте вернёмся к нашему первому примеру и посмотрим, как мы можем контролировать, в каких пропорциях flex элементы будут занимать место. Включите свою копию файла flexbox0.html, или скачайте flexbox1.html (просмотр).

Прежде всего, добавим следующее правило в конец вашего CSS кода:

article {
  flex: 1;
}

Это безразмерное значение пропорции, которое указывает, сколько свободного пространства на главной оси (main axis) каждый flex элемент сможет занять. В этом случае, мы даём каждому элементу {{htmlelement("article")}} значение 1, а это значит, что они будут занимать равное количество свободного места в макете, которое осталось после установки свойств padding и margin.

Теперь добавьте следующее правило в строку после предыдущего:

article:nth-of-type(3) {
  flex: 2;
}

Обновив страницу, вы увидите, что третий элемент {{htmlelement("article")}} занимает в два раза больше доступной ширины, чем два других — итого теперь доступно 4 единицы пропорции. Первые два flex элемента имеют по одной единице, поэтому берут 1/4 пространства каждый. А у третьего 2 единицы, так что он берёт 2/4 свободного места (или 1/2).

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

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

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

Настоящая ценность flexbox можно увидеть в его гибкости/отзывчивости — если изменить размер окна или добавить ещё элемент {{htmlelement("article")}}, макет будет и дальше выглядеть также хорошо.

flex: краткий код против развёрнутого

{{cssxref("flex")}} это сокращённое свойство, в которым можно задать до трёх разных свойств:

Мы не советуем использовать развёрнутые свойства flex, если вам в действительности это не нужно (например, переопределить ранее установленное). Они приводят к написанию большого количества дополнительного кода и могут запутать кого угодно.

Горизонтальное и вертикальное выравнивание

Flexbox также имеет функции для выравнивания flex элементов вдоль основной (main) или поперечной (cross) осей. Рассмотрим их на новом примере — flex-align0.html (просмотр) — который мы превратим в аккуратную, гибкую кнопочную панель инструментов. На данный момент вы видите горизонтальную панель меню, кнопки которой застряли в верхнем левом углу.

Сначала сделайте себе копию этого примера.

Теперь добавьте следующую строку в низ кода CSS:

div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

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

{{cssxref("align-items")}} контролирует, где на поперечной оси находятся flex элементы.

Вы можете переопределить {{cssxref("align-items")}} поведение для отдельных flex элементов, применив свойство {{cssxref("align-self")}} к ним. Например, попробуйте добавить эти строки в код:

button:first-child {
  align-self: flex-end;
}

Посмотрите, что произошло и удалите эти строки.

{{cssxref("justify-content")}} контролирует, где flex элементы располагаются на главной оси.

Попробуйте немного поиграть с этими значениями прежде чем продолжить

Порядок элементов flex

В Flexbox также есть возможность менять порядок расположения flex элементов, не влияя на исходный порядок. Это ещё одна вещь, которую невозможно сделать традиционными методами CSS.

Код здесь простой: попробуйте добавить следующий CSS вниз вашего кода примера:

button:first-child {
  order: 1;
}

и теперь вы увидите, что кнопка «Smile» переместилась в конец главной оси. Давайте теперь поговорим подробнее о том, как это работает:

Вы можете установить отрицательные значения , чтобы элементы отображались раньше, чем элементы с установленным 0. Например, вы можете сделать, чтобы кнопка «Blush» появлялась в начале основной оси, используя следующее правило:

button:last-child {
  order: -1;
}

Вложенные flex блоки

Можно создать несколько довольно сложных макетов с помощью flexbox. Совершенно нормально сделать flex элемент flex контейнером, чтобы его потомки также были flex блоками. Посмотрите на complex-flexbox.html (см. вживую).

HTML для этого довольно простой. У нас есть элемент {{htmlelement ("section")}}, содержащий три {{htmlelement ("article")}}. Третий {{htmlelement ("article")}} содержит ещё три {{htmlelement ("div")}}.

section - article
          article
          article - div - button
                    div   button
                    div   button
                          button
                          button

Давайте посмотрим на код, который мы использовали для макета.

Прежде всего, мы устанавливаем дочерние элементы {{htmlelement ("section")}} в виде flex блоков.

section {
  display: flex;
}

Затем мы устанавливаем несколько значений на самих {{htmlelement ("article")}}. Обратите внимание на второе правило: мы устанавливаем третий {{htmlelement ("article")}}, чтобы его дети были в макете в виде flex блоков, но на этот раз мы располагаем их как столбец.

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 3 200px;
  display: flex;
  flex-flow: column;
}

Затем мы берём первый {{htmlelement ("div")}}. Сначала мы пишем flex: 1 100px; чтобы дать ему минимальную высоту 100px, потом мы устанавливаем его дочерние элементы (элементы {{htmlelement ("button")}}) также в виде flex блоков. Им мы назначаем перенос блоков и выравниваем их по центру доступного пространства, как это было в примере с кнопкой.

article:nth-of-type(3) div:first-child {
  flex: 1 100px;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: space-around;
}

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

button {
  flex: 1;
  margin: 5px;
  font-size: 18px;
  line-height: 1.5;
}

Совместимость с браузерами

Поддержка Flexbox доступна в большинстве новых браузеров: Firefox, Chrome, Opera, Microsoft Edge и IE 11, более поздних версиях Android / iOS и т. д.. Однако помните, что до сих пор используются более старые браузеры, которые не поддерживают Flexbox ( или поддерживают, но старую версию.)

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

Flexbox немного сложнее, чем некоторые функции CSS. Например, если в браузере отсутствует поддержка CSS тени, сайт по-прежнему будет можно использовать. А вот неподдерживаемые функции flexbox, возможно, полностью сломают макет, что сделает сайт непригодным.

Мы обсудим возможности преодоления проблем поддержки кросс-браузерности в следующем модуле.

Подытожим

Мы завершаем нашу статью по основам flexbox. Надеемся, что вам понравилось, и вы хорошо развлечётесь, путешествуя дальше и изучая его. Далее мы рассмотрим ещё один важный аспект макетов CSS - grid-системы.

{{PreviousMenuNext("Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout/Grids", "Learn/CSS/CSS_layout")}}