Спецификация CSS Flexible Box Layout Module.

16.12.2022 08:58

    CSS flexbox (Flexible Box Layout Module) — модуль макета гибкого контейнера — представляет собой способ компоновки элементов, в основе лежит идея оси.

    Flexbox состоит из гибкого контейнера (flex container) и гибких элементов (flex items). Гибкие элементы могут выстраиваться в строку или столбец, а оставшееся свободное пространство распределяется между ними различными способами.

    Модуль flexbox позволяет решать следующие задачи:

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

    

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

    Главные составляющие компоновки flexbox:

  • flex-контейнер (flex container);

  • flex-элементы (flex items).

    При этом flex container -- это элемент, внутри которого располагаются flex-элементы.

    Flex-контейнер устанавливает новый гибкий контекст форматирования для его содержимого. 

    Flex-контейнер не является блочным контейнером, поэтому для дочерних элементов не работают такие CSS-свойства, как float, clear, vertical-align.     Также, на flex-контейнер не оказывают влияние свойства column-*, создающие колонки в тексте и псевдоэлементы ::first-line и ::first-letter.

    Flex-элементы — блоки, представляющие содержимое flex-контейнера в потоке. Flex-контейнер устанавливает новый контекст форматирования для своего содержимого,

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

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

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

    Соответственно, конец и начало центральной оси описывают термины main end/main start, ну а расстояние между между ними обозначают как main size.

    Однако существует не только основная ось, но и поперечная. Она перпендикулярна основной и именуется cross axis. Если элементы располагаются в виде строки, то cross axis направлена сверху вниз, если в виде столбца, -- слева направо. Начало поперечной оси -- это cross start, конец -- cross end, расстояние между ними -- cross size.

    Таким образом, когда элементы расположены в строку, main size представляет ширину контейнера/элементов, а cross size -- высоту. Когда элементы расположены в столбик, все наоборот.

 

Создаем flex-контейнер

 

    Чтобы создать flex-контейнер, надо присвоить стилевому свойству display одно из 2-х значений: либо flex, либо inline-flex.

Вот как выглядит создание простейшей web-страницы с применением flexbox:

    Обратите внимание, что для контейнера flex-container устанавливается свойство display:flex, в котором располагаются 3 flex-элемента.

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

 

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

 

Свойство flex-direction указывает, как flex-элементы располагаются во flex-контейнере, задавая направление главной оси flex-контейнера. Элементы могут располагаться по двум основным направлениям — как строки по горизонтали или как столбцы по вертикали.

 

Значения:

    1. Со значением row flex-элементы располагаются в ряд слева направо в контексте ltr.

 

.flex-container {

  flex-direction: row;

}

 

    2. При значении row-reverse flex-элементы располагаются в ряд справа налево в контексте ltr.

 
.flex-container {
  flex-direction: row-reverse;
 

    3. Со значением column flex-элементы располагаются в колонку сверху вниз.

 
.flex-container {
  flex-direction: column;
}
 

    4. При значении column-reverse flex-элементы располагаются в колонку снизу вверх.

 
Значение по умолчанию: row.
 
row и row-reverse зависят от режима написания, так что в контексте rtl они будут соответственно перевёрнуты.
 
Например:
 

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

 

    Свойство justify-content применяется к flex-контейнеру, и принимает такие значения:

  1. flex-start (значение по умолчанию) — flex-элементы прижимаются к началу главной оси.
  2. flex-end — flex-элементы прижимаются к концу главной оси.
  3. center — flex-элементы центрируются по главной оси.
  4. space-between — первый flex-элемент находится в начале главной оси, последний flex-элемент — в ее конце, а все остальные flex-элементы равномерно распределяются в пределах оставшегося пространства.
  5. space-around — все flex-элементы равномерно распределяются на главной оси, при этом свободное пространство поровну делится между ними.
 

    Align-items — еще одно свойство, применяемое к flex-контейнеру для выравнивания его дочерних элементов. Только на этот раз выравнивание происходит не по главной оси, а по поперечной. Рассмотрим список значений:

  1. stretch (значение по умолчанию) — flex-элементы растягиваются вдоль поперечной оси (если при этом указаны свойства min-width/max-width, они принимаются во внимание).
  2. flex-start — flex-элементы прижимаются к началу поперечной оси.
  3. flex-end — flex-элементы прижимаются к концу поперечной оси.
  4. center — flex-элементы центрируются по поперечной оси.
  5. baseline — flex-элементы выравниваются по своим базовым линиям.

    

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

    Свойство принимает следующие значения:

  1. nowrap (значение по умолчанию) — flex-элементы размещаются в одной линии, слева направо (либо справа налево для локации RTL).
  2. wrap — flex-элементы выстраиваются горизонтально в несколько рядов (при условии, что они не помещаются в один ряд). Направление элементов — слева направо (или справа налево для RTL).
  3. wrap-reverse — принцип действия идентичен предыдущему свойству, с той лишь разницей, что расположение flex-элементов происходит в реверсном порядке.

    Свойство flex-flow — это, по сути, сокращенная запись свойств flex-direction и flex-wrap. Вы можете одной строкой задать направление главной оси и определить многострочность flex-контейнера. В свойстве указываются два значения через пробел: одно для flex-direction, второе для flex-wrap. 

 

Пример:

 

flex-flow: column wrap-reverse;

 

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

    Доступные значения:

  1. stretch (значение по умолчанию) — ряд flex-элементов растягивается по вертикали, пока не упрется в следующий ряд (если при этом указаны свойства min-width/max-width, они принимаются во внимание).
  2. flex-start — ряды flex-элементов прижимаются к началу flex-контейнера.
  3. flex-end — ряды flex-элементов прижимаются к концу flex-контейнера.
  4. center — ряды flex-элементов вертикально центрируются во flex-контейнере.
  5. space-between — первый ряд flex-элементов находится в начале flex-контейнера, последний ряд flex-элементов — в конце, а все остальные ряды равномерно распределяются в пределах оставшегося пространства.
  6. space-around — все ряды flex-элементов равномерно распределяются в вертикальном пространстве flex-контейнера, при этом свободное пространство поровну делится между ними.

    Свойство flex. Свойство flex является короткой записью и объединяет в себе три свойства: flex-grow, flex-shrink и flex-basis. Второй и третий параметры (flex-shrink и flex-basis) опциональны. 

  1. flex-basis задает базовый размер flex-элемента по главной оси. Значение может быть указано в любых единицах измерения CSS, таких как проценты, пиксели и т. д. В качестве значения также принимается ключевое слово auto — тогда на размеры элемента влияют свойства width/height либо контент, который в нем содержится.
  2. flex-grow можно определить, какое количество свободного пространства может занять flex-элемент по сравнению с другими flex-элементами. В качестве значения указывается число (можно использовать целые и дробные числа), которое обозначает пропорции.
  3. flex-shrink задает коэффициент сужения flex-элементов в контейнере и определяет, насколько сильно flex-элемент будет уменьшаться по отношению к другим flex-элементам, чтобы уместить все элементы в один ряд. В качестве значения указывается число (можно использовать целые и дробные числа), которое обозначает пропорции. По своему действию данное свойство похоже на предыдущее, с той разницей, что здесь пространство не «раздается», а «отбирается», а количество этого отбираемого пространства зависит от указанного значения для flex-shrink, а также от flex-basis.

    По умолчанию установлены следующие параметры:

flex: 0 1 auto;

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

    Свойство align-self позволяет переопределить выравнивание по умолчанию (либо перезаписать значение, заданное свойством align-items) для отдельных flex-элементов.

    Свойство align-self принимает те же значения, что и align-items:

  1. stretch (значение по умолчанию) — flex-элемент растягивается вдоль поперечной оси (если при этом указаны свойства min-width/max-width, они принимаются во внимание).
  2. flex-start — flex-элемент прижимается к началу поперечной оси.
  3. flex-end — flex-элемент прижимается к концу поперечной оси.
  4. center — flex-элемент центрируется по поперечной оси.
  5. baseline — flex-элемент выравнивается по своей базовой линии.

    Flex-элемент легко поддается вертикальному и горизонтальному центрированию через свойство margin: auto (в обычном режиме данная запись дает лишь горизонтальное центрирование). Достаточно применить его к нужному элементу.

 

Макет страницы на Flexbox

 

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

    Для этого определим следующую веб-страницу:

 

<!DOCTYPE html>

<html>

    <head>

        <meta charset="utf-8">

        <meta name="viewport" content="width=device-width" />

        <title>Flexbox в CSS3</title>

        <style>

            *{

                box-sizing: border-box;

            }

            html, body {

                padding: 0;

                margin: 0;

                font-family: verdana, arial, sans-serif;

            }

 

            body {

                color: #fff;

                font-size: 1.1em;

                padding: 1em;

                display: flex;

                flex-direction: column;

            }

 

            main {

                display: flex;

                flex-direction: column;

            }

 

            article {

                background-color: #546e7a;

                flex: 2 2 12em;

                padding: 1em;

            }

 

            nav, aside {

                flex: 1;

                background-color: #455a64;

            }

 

            nav {

                order: -1;

            }

             

            header, footer {

                flex: 0 0 5em;

                background-color: #37474f;

            }

             

            @media screen and (min-width: 600px) {

                 

                body{

                    min-height: 100vh;

                }

                main {

                    flex-direction: row;

                    min-height: 100%;

                    flex: 1 1 auto;

                }

            }

        </style>

    </head>

    <body>

        <header>

            <p>Header</p>

        </header>

        <main>

            <article>

                <h1>Что такое Текст-заполнитель?</h1>

                <p>Текст-заполнитель — это текст, который имеет некоторые характеристики реального письменного текста, но является случайным набором слов или сгенерирован иным образом. Его можно использовать для отображения образца шрифтов, создания текста для тестирования или обхода спам-фильтра.</p>

            </article>

            <nav>

                <p>Navigation</p>

            </nav>

            <aside>

                <p>Sidebar</p>

            </aside>

        </main>

        <footer>

            <p>Footer</p>

        </footer>

    </body>

</html>

 

Это будет выглядеть так:

 

    Итак, flex-контейнером верхнего уровня здесь является элемент body. Его flex-элементами являются header, main и footer. Body располагает все свои элементы сверху вниз в столбик. Здесь также стоит отметить, что при ширине от 600px и выше для заполнения всего пространства браузера у body устанавливается стиль height: 100vh;.

    Элементы header и footer аналогичны. Их свойство flex: 0 0 5em; указывают, что при любом изменении контейнера эти элементы будут иметь размер в 5em. То есть они имеют статический размер.

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

    При ширине от 600px вложенные элементы nav, article и aside располагаются в виде строки. И поскольку при такой ширине браузера родительский элемент body заполняет по высоте все пространство браузера, то для заполнения всей высоты контейнера body при его изменении у элемента main устанавливается свойство flex: 1 1 auto;.

    У вложенных в main flex-элементов стоит отметить, что элемент навигации nav и элемент сайдбара aside будут иметь одинаковые размеры при масштабировании контейнера. А элемент article, содержащий основное содержимое, будет соответственно больше. При этом хотя nav определен после элемента article, но благодаря установке свойства order: -1 блок навигации будет стоять до блока article.