Полное руководство по flexbox

Основы

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

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

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

Браузеры с поддержкой последней спецификации flexbox:

  • Chrome 29+
  • Firefox 28+
  • Internet Explorer 11+
  • Opera 17+
  • Safari 6.1+ (с префиксом )
  • Android 4.4+
  • iOS 7.1+ (с префиксом )

Более детальную поддержку и совместимость с браузерами можно посмотреть здесь.

Основы CSS Flexbox

Создание CSS разметки с помощью Flexbox начинается с установки необходимому HTML элементу CSS-свойства со значением или .

После этого данный элемент становится flex-контейнером, а все его непосредственные дочерние элементы – flex-элементами. При этом когда мы говорим о flexbox то подразумеваем под этим только элемент с или и все элементы непосредственно расположенные в нём. Таким образом в CSS Flexbox имеется всего два типа элементов: flex-контейнер и flex-элемент.

<style>
.flex-container {
  display: flex; /* flex || inline-flex */
}
<style>

<!-- flex-контейнер -->
<div class="flex-container">
  <div>flex-элемент #1</div>
  <div>flex-элемент #2</div>
  <div>flex-элемент #3</div>
</div>

По умолчанию flex-элементы во flex-контейнере занимают всю его высоту.

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

Устройство flex-контейнера. Направление осей

На рисунке представлена схема устройства flex-контейнера:

Направление расположение flex-элементы в flex-контейнере определяется посредством осей.

В CSS Flexbox имеются две оси. Первая ось называется главной (по умолчанию она направлена слева направо). Вторая — поперечная (по умолчанию направлена сверху вниз), она всегда перпендикулярно главной. Главная ось задаёт основное направление flex-элементов во flex-контейнере, а поперечная ось определяет их направление при переносе на новую линию.

По умолчанию элементы во flex-контейнере располагаются вдоль направления главной оси (т.е. слева направо) на одной линии.

Направление главной оси можно изменить, осуществляется это с помощью CSS-свойства .

flex-direction: row; 
/* row (слева направо) - по умолчанию
   row-reverse (справа налево)
   column (сверху вниз)
   column-reverse (снизу вверх) */

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

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

Но это можно изменить. Разрешить перенос flex-элементов на новые линии осуществляется с помощью установки flex-контейнеру CSS свойства со значением или .

flex-wrap: wrap; 
/* nowrap (только на одной линии - по умолчанию) 
   wrap (разрешить перенос flex-элементов на новые линии) 
   wrap-reverse (осуществлять перенос flex-элементов в обратном порядке) */

Значения и CSS-свойства определяют направление поперечной оси.

Свойства и можно указать с помощью универсального CSS свойства :

flex-flow: row nowrap; /* 1 значение - flex-direction, 2 значение - flex-wrap */

Обработка размеров flex-элемента

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

  • flex-grow: 0;
  • flex-shrink: 1;
  • flex-basis: auto.

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

Между тем, если flex-basis установить в auto а flex-grow: 1, то будет распределено только свободное пространство, т.е. пространство без контента.

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

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

Определение auto (defining auto)

Когда auto назначается как значение чего-нибудь в CSS, оно будет иметь очень специфическое значение в этом контексте, которое стоит посмотреть. Рабочая группа CSS тратит много времени на выяснение того, что означает auto в любом контексте, как объясняет этот разговор с редактором спецификаций Fantasai.

В спецификации мы можем найти информацию о том, что означает auto при использовании в качестве flex-basis. Термины, определенные выше, должны помочь нам проанализировать это утверждение.

Таким образом, если наш flex-basis установлен в auto, Flexbox просмотрит значение свойства main size. Мы должны иметь main size, если мы дали одному из наших flex-элементов ширину. В примере ниже, все элементы имеют ширину 110px, поэтому это значение используется в качестве main size т.к. начальное значение flex-basis — auto.

Однако в нашем первоначальном примере есть элементы, у которых нет ширины, это означает, что их main size — auto, и поэтому нам нужно перейти к рассмотрению следующего высказывания: “если это значение само по себе auto, то используется значение content.”

Теперь нам нужно посмотреть, что говорит спецификация о ключевом слове content. Это еще одно значение, которое вы можете использовать (при поддержке браузеров) для свойства flex-basis, например:

Спецификация определяет content следующим образом:

В нашем примере с flex-элементами, содержащими текст, мы можем игнорировать некоторые более сложные настройки и рассматривать content как размер max-content.

Это объясняет, почему, когда у нас есть небольшое количество текста в каждом элементе, текст не переносится. flex-элементы по умолчанию имеют auto размер, поэтому Flexbox берет их размер в свойстве max-content, элементы помещаются в контейнер такого размера, и работа выполнена!

На этом история не заканчивается, так как когда мы добавляем еще контент, элементы не остаются в размере max-content. Если бы они это делали, то вырвались бы из flex-контейнера и вызвали бы переполнение. Как только они заполнят контейнер, содержимое начинает переноситься, и элементы становятся разных размеров, основываясь на содержимом внутри них.

Что такое Flexbox?

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

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

На данный момент flexbox поддерживается практически всеми современными браузерами, включая Android и iOS.

Когда использовать Flexbox при верстке макета

В одной из предыдущих статей мы писали об использовании сеток в качестве метода для респонсивного дизайна. Хотя с помощью Flexbox технически можно сверстать полный макет для сайта, он не предназначен исключительно для этой цели. Скорее, он лучше подходит для стилизации отдельных контейнеров, таких как контейнер основного контента, боковая панель (сайдбар), хедер и другие подобные разделы. Все же сетки лучше подходят для создания всего макета.

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

Другими словами пользователь на доли секунды увидит совсем не тот макет, который планировался. Но после полной загрузки страницы все, конечно же, выравнивается.

Контейнеры, дочерние элементы и Flex

Прежде чем мы начнем писать код CSS с использованием flexbox, есть некоторые важные концепции, с которыми в первую очередь нужно ознакомиться:

  • flexbox – контейнер становится flexbox после того, как подключается свойство со значением или
  • flex item – дочерний элемент в flexbox
  • главная ось (main axis) – это основная ось, вдоль которой выравниваются элементы
  • перекрестная ось (cross axis) – ось, перпендикулярная главной оси. Также называется поперечной осью
  • главное начало/главный конец (main-start/main-end) – флекс элементы помещаются в контейнер, который начинается со стороны главного начала, и заканчивается к главному концу
  • перекрестное начало и конец (cross start/end) – флекс линии заполняются items (элементами) и помещаются в контейнер, который начинается со стороны перекрестного начала флекс контейнера и идет к перекрестному концу
  • свойство основного размера (main size) – ширина или высота флекс элемента, в зависимости от того, что находится в основном измерении главной оси, является основным размером элемента. Свойство основного размера элемента flex – это свойство ширины или высоты, в зависимости от того, что находится в основном измерении
  • свойство перекрестного размера (cross size) – ширина или высота флекс элемента, в зависимости от того, что находится в поперечной оси измерении, является перекрестным размером элемента. Свойство перекрестного размера зависит от ширины или высоты, которое находится в поперечном измерении

Графическое описание важных концепций для flexbox в CSS3

В CSS есть определенные свойства, на которые не влияет свойство flexbox, поскольку они фактически не делают контейнеры блоками:

column-*
float
clear
vertical-align
::first-line и ::first-letter

Создание HTML5 контейнера

Теперь мы можем начать строить макет, используя flexbox. Для этого создайте костяк html-страницы (или же в php, если вы используете CMS).

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Заголовок страницы</title>
  </head>
  <body>
  </body>
</html>

Создайте родительский контейнер внутри :

<div class="content">
</div>

Внутри этого контейнера вы можете добавить любой контент.

В качестве теста я создам три блока с небольшой информацией, и блок с основным контентом под ними.

<div class="content">
  <div class="blok">Блок информации №1</div>
  <div class="blok">Блок информации №2</div>
  <div class="blok">Блок информации №3</div>
  <article>Здесь основной контент.</article>
</div>

Теперь, чтобы придать этому костяку некоторых красок, добавим несколько основных стилей CSS (вы можете это сделать с помощью отдельного подключаемого файла css стилей, или же включить эти стили в тег в разделе ).

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

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

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

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

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

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

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

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

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

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

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

Свойства контейнера flexbox

Свойство display позволяет определить div в качестве контейнера:

.container
{
  display: flex;
}

Flex-direction

CSS flex direction позволяет определить направление, в котором дочерние элементы будут распространяться (четыре значения):

.container
{
  display: flex;
  flex-direction: row;
}
  • row — слева направо;
  • row-reverse — справа налево;
  • column — сверху вниз;
  • column-reverse — снизу вверх.

Пример слева направо

Пример справа налево

Пример сверху вниз

Пример снизу вверх

flex-wrap

По умолчанию flexbox располагает дочерние элементы в одну строку. Но, изменив значение flex-wrap, можно разрешить их перенос на новую строку:

.container
{
  display: flex;
  flex-wrap: nowrap;
}
  • nowrap — одна строка, слева направо;
  • wrap — несколько строк, слева направо;
  • wrap-reverse — несколько строк, справа налево.

Пример несколько строк слева направо

Пример несколько строк справа налево

flex-flow

Flex-flow позволяет объединить два описанных выше свойства в одно. Это сокращенное свойство, определяющее flex-direction и flex-wrap:

.container
{
  display: flex;
  flex-flow: row nowrap;
}

justify-content

Определяет, как размещаются внутри div контейнера дочерние элементы. Доступно пять различных значений этого свойства CSS flex:

  • flex-start — выравнивает элементы по началу контейнера;
  • flex-end — выравнивает элементы по концу контейнера;
  • center — выравнивает элементы по центру;
  • space-between — элементы размещаются с одинаковыми отступами друг от друга, первый элемент выравнивается по началу контейнера, последний элемент — по концу контейнера;
  • space-around — для элементов задаются одинаковые отступы со всех сторон.

Пример flex-start

Пример flex-end

Пример center

Пример space-between

Пример space-around

align-items

Align-items позволяет выровнять элементы по вертикальной оси. Доступно пять различных значений этого свойства CSS flex:

  • flex-start — выравнивает элементы по верху;
  • flex-end — выравнивает элементы по низу;
  • center — центрирует элементы по вертикали;
  • baseline — выравнивает элементы по базовому уровню;
  • stretch — растягивает элементы, чтобы они соответствовали размерам контейнера.

Пример flex-start

Пример flex-end

Пример center

Пример baseline

Пример stretch

align-content

Выравнивает контент и пространство между полями, когда контент перемещается на несколько строк. Доступно шесть значений этого свойства CSS flex 1:

  • flex-start — несколько строк будут смещены к началу контейнера;
  • flex-end — несколько строк будут смещены к концу контейнера;
  • center — несколько строк будут размещены по центру;
  • space-between — для нескольких строк будет задано одинаковое расстояние между ними;
  • space-around — для нескольких строк будет задано одинаковое расстояние вокруг них;
  • stretch — несколько строк будут растягиваться, чтобы занять все пространство.

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

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

Типичный вариант использования 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;
}

The align-items Property

The property is used to align
the flex items.

In these examples we use a 200 pixels high container, to better demonstrate the property.

Example

The value aligns the flex items in the middle of the
container:

.flex-container { 
display: flex;  height: 200px; 
align-items: center;}

Example

The value aligns the flex items at the top of the container:

.flex-container { 
display: flex;  height: 200px; 
align-items: flex-start;}

Example

The value aligns the flex items at the bottom of the container:

.flex-container { 
display: flex;  height: 200px; 
align-items: flex-end;}

Example

The value stretches the flex items to fill the container
(this is default):

.flex-container { 
display: flex;  height: 200px; 
align-items: stretch;}

Example

The value aligns the flex items such as their baselines aligns:

.flex-container { 
display: flex;  height: 200px; 
align-items: baseline;}

Note: the example uses different font-size to demonstrate that the items gets aligned by the text baseline:

2

Свойство flex

Свойство flex делает элементы адаптивными внутри контейнера flexbox, и с его помощью возможны некоторые действительно изящные эффекты. Представьте, что мы хотим, чтобы каждый элемент растягивался слева направо и чтобы каждый элемент занимал одинаковую ширину. Давайте применим это свойство CSS:

Скопировать

Теперь давайте сделаем один элемент в два раза шире остальных. Для этого установим элементу Services значение flex 2.

Скопировать

Благодаря свойству flex вы можете просто сделать один элемент резиновым, в то время как другие элементы сохранят фиксированную ширину. В приведенном ниже примере элемент About будет растягиваться и сжиматься при всех размерах экрана, в то время как Home и Services сохранят фиксированную ширину:

Скопировать

Мы также можем заставить два элемента увеличиваться и уменьшаться, в то время как третий элемент сохраняет фиксированную ширину. В следующем примере будет сохранена фиксированная ширина для элемента About, в то время как элементы Home и Services динамически увеличиваются и уменьшаются:

CSS Tutorial

CSS HOMECSS IntroductionCSS SyntaxCSS SelectorsCSS How ToCSS CommentsCSS Colors
Colors
RGB
HEX
HSL

CSS Backgrounds
Background Color
Background Image
Background Repeat
Background Attachment
Background Shorthand

CSS Borders
Borders
Border Width
Border Color
Border Sides
Border Shorthand
Rounded Borders

CSS Margins
Margins
Margin Collapse

CSS PaddingCSS Height/WidthCSS Box ModelCSS Outline
Outline
Outline Width
Outline Color
Outline Shorthand
Outline Offset

CSS Text
Text Color
Text Alignment
Text Decoration
Text Transformation
Text Spacing
Text Shadow

CSS Fonts
Font Family
Font Web Safe
Font Fallbacks
Font Style
Font Size
Font Google
Font Pairings
Font Shorthand

CSS IconsCSS LinksCSS ListsCSS Tables
Table Borders
Table Size
Table Alignment
Table Style
Table Responsive

CSS DisplayCSS Max-widthCSS PositionCSS OverflowCSS Float
Float
Clear
Float Examples

CSS Inline-blockCSS AlignCSS CombinatorsCSS Pseudo-classCSS Pseudo-elementCSS OpacityCSS Navigation Bar
Navbar
Vertical Navbar
Horizontal Navbar

CSS DropdownsCSS Image GalleryCSS Image SpritesCSS Attr SelectorsCSS FormsCSS CountersCSS Website LayoutCSS UnitsCSS SpecificityCSS !important

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector