MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Используем CSS Flexible Boxes

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

CSS3 Flexible Box, или просто flexbox — это режим разметки, созданный для упорядочения элементов на странице таким образом, чтобы они вели себя предсказуемо в случаях, когда разметка страницы адаптирована под различные размеры экрана и устройства. Во многих случаях флексбоксы лучше блочной модели разметки, поскольку не использует обтекания (floats) и не выполняет схлопывание отступлений flex-контейнера и его содержимого (margin collapse).

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

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

Концепция Flexbox

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

Алгоритм разметки флексбоксами агностичено направлен в противовес блочной разметке, которая ориентирована строго вертикально, или горизонтально-ориентированной инлайн-разметке. Несмотря на то что разметка блоками хорошо подходит для страницы, ей не хватает объективного механизма для поддержки компонентов, которые должны менять ориентацию, размеры а также растягиваться или сжиматься при изменениях размера экрана, изменении ориентации с вертикальной на горизонтальную и так далее. Разметка флексбоксами наиболее желательна для компонентов приложения и шаблонов, которые мало масштабируются, тогда как grid-разметка создана для больших шаблонов. Обе технологии являются частью разработки CSS Working Group которая должна способствовать совместимости web-приложений с различными браузерами, режимами а также большей гибкости.

Терминология

Поскольку описание флексбоксов не включает таких словосочетаний, как горизонтальная / inline и вертикальная / block оси, объяснение модели предусматривает новую терминологию. Используйте следующую диаграмму при просмотре словаря терминов. Она изображает flex-контейнер, имеющий flex-направление ряда, что означает, что каждый flex item расположен горизонтально, друг за другом по главной оси (main axis) в соответствии с установленного режима написания, направления текста элемента. Слева направо в данном случае.

flex_terms.png

Flex-контейнер
Родительский элемент, в котором содержатся flex-элементы. Flex-контейнер определяется установкой свойства display в flex или inline-flex.
Flex-элемент, flex item

Каждый дочерний элемент flex-контейнера становится flex-элементом. Текст, который напрямую содержится в flex-контейнере, оборачивается анонимным flex-элементом.

Оси

Каждый flexible-бокс шаблон строится по двум осям. Главная ось (main axis) — это ось, вдоль которой flex-элементы следуют один за другим, а перекрёстная ось (cross axis) перпендикулярна ей.

  • Свойство flex-direction устанавливает главную ось.
  • Свойство justify-content определяет расположение элементов вдоль главной оси в текущем ряду.
  • Свойство align-items расположение элементов вдоль перекрёстной оси в текущем ряду.
  • Свойство align-self устанавливает, как отдельный flex-элемент выровнен по перекрёстной оси, переопределяя значения, установленные с помощью align-items.
Направления

Главное начало и конец (main) и перекрёстное начало и конец (cross start/end) — это стороны контейнера, определяющие начало и окончание потока flex-элемментов. Они следуют по главной и перекрестной осями flex-контейнера в векторе, установленном режимом написания (writing-mode) (слева направо, справа налево и т. д.).

  • Свойство order присваивает элементы порядковым группам и определяет, в каком порядке их показывать.
  • Свойство flex-flow — это короткая форма, состоящая из свойств flex-direction и flex-wrap, определяющих расплолжение элементов.
Линии

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

Размеры

Флекс элементы агностически эквивалентны высоте и ширине главного размера и поперечного размера, которые равны, соответственно,  главной оси (main axis) и поперечной оси (cross axis) флекс-контейнера.

Делаем элемент флексбоксом

Чтобы сделать элемент flexible-боксом, укажите значение display следующим образом:

display: flex

или

display: inline-flex

Таким образом мы определяем элемент как флексбокс, а его дочерниие элементы — как flex-элементы. Значение flex делает контейнер блочным элементом, а inline-flex значение превращает его в инлайн-элемент.

Внимание: для указания префикса вендора, добавьте строку в значение атрибута, а не к самому атрибуту. Например, display: -webkit-flex.

Рассмотрим flex-элементы

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

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

Отступы (margin) соседних flex-контейнеров не схлопываются. Установка значений margin: auto поглощает дополнительное место в вертикальном или горизонтальном направлении и может быть использовано для выравнивания или для разделения соседних flex-элементов. См. Выравнивание при помощи 'автоматических' отступов в разделе "Модель расположения при помощи flex-контейнеров" спецификации W3C.

Свойства выравнивания flexbox выполняют "истинное" центрирование в отличие от других способов центрирования в CSS. Это означает, что flex-элементы будут оставаться отцентрированными даже если они переполняют flex-контейнер. Впрочем, это может иногда быть проблематичным, если они вылезают за верхний или левый край страницы (в языках с написанием слева направо; в языках с написанием справа налево, таких как арабский, возникает проблема с правой границей), так как вы не можете прокрутить страницу в данную область даже если там есть содержимое! В будущем релизе свойства выравнивания будут также дополнены "безопасной" опцией. На данный момент, если это проблема, вы можете использовать отступы (margin) для достижения центрирования, так как они сработают "безопасно" и центрирование будет прекращено при переполнении. Вместо использования свойства align- просто установите автоматические отступы (margin: auto) для flex-элементов, которые вы хотите отцентрировать. Вместо свойств justify- установите margin: auto на внешние края первого и последнего элемента в flex-контейнере. Автоматические отступы будут "подстраиваться" и занимать оставшееся место, центрируя flex-элементы при наличии свободного места и используя стандартное выравнивание при его отсутствии. Тем не менее, если вы пытаетесь заменить justify-content центрированием, основанным на отступах (margin-based) в многострочном flexbox, вам, видимо, не повезло, так как вам необходимо установить отступы для первого и последнего элемента на каждой строке. Если вы не можете предугадать заранее на какой строке окажется каждый элемент, вы не сможете надежно использовать центрирование, основанное на отступах, на основной оси для замены свойства justify-content.

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

Свойства Flexbox

Свойства, не влияющие на Flexbox

Так как flexbox используют другой алгоритм расположения, некоторые свойства не имеют смысла для flex-контейнера:

Пример

Типичный пример flex

Типичный пример показывает как применять "flex-эффект" к элементам и как соседние элементы ведут себя в состоянии flex.

​<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
    .flex {
        /* basic styling */
        width: 350px;
        height: 200px;
        border: 1px solid #555;
        font: 14px Arial;

        /* flexbox setup */
        display: flex;
        flex-direction: row;
    }

    .flex > div {
        flex: 1 1 auto;
        width: 30px; /* To make the transition work nicely. (Transitions to/from
                        "width:auto" are buggy in Gecko and Webkit, at least.
                        See http://bugzil.la/731886 for more info.) */
        transition: width 0.7s ease-out;
    }

    /* colors */
    .flex > div:nth-child(1){ background: #009246; }
    .flex > div:nth-child(2){ background: #F1F2F1; }
    .flex > div:nth-child(3){ background: #CE2B37; }

    .flex > div:hover {
        width: 200px;
    }
   
    </style> 
  </head>
  <body>
    <p>Flexbox nuovo</p>
    <div class="flex">
      <div>uno</div>
      <div>due</div>
      <div>tre</div>
    </div>
  </body>
</html>

Пример расположения "Священный Грааль"

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

HolyGrailLayout.png

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

​<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
    body {
        font: 24px Helvetica;
        background: #999999;
    }

    #main {
        min-height: 800px;
        margin: 0px;
        padding: 0px;
        display: flex;
        flex-flow: row;
    }
 
    #main > article {
        margin: 4px;
        padding: 5px;
        border: 1px solid #cccc33;
        border-radius: 7pt;
        background: #dddd88;
        flex: 3 1 60%;
        order: 2;
    }

    #main > nav {
        margin: 4px;
        padding: 5px;
        border: 1px solid #8888bb;
        border-radius: 7pt;
        background: #ccccff;
        flex: 1 6 20%;
        order: 1;
    }
  
    #main > aside {
        margin: 4px;
        padding: 5px;
        border: 1px solid #8888bb;
        border-radius: 7pt;
        background: #ccccff;
        flex: 1 6 20%;
        order: 3;
    }
 
    header, footer {
        display: block;
        margin: 4px;
        padding: 5px;
        min-height: 100px;
        border: 1px solid #eebb55;
        border-radius: 7pt;
        background: #ffeebb;
    }
 
    /* Too narrow to support three columns */
    @media all and (max-width: 640px) {
        #main, #page {
            flex-direction: column;
        }

        #main > article, #main > nav, #main > aside {
        /* Return them to document order */
            order: 0;
        }
  
        #main > nav, #main > aside, header, footer {
            min-height: 50px;
            max-height: 50px;
        }
    }
    </style>
  </head>
  <body>
    <header>header</header>
    <div id='main'>
      <article>article</article>
      <nav>nav</nav>
      <aside>aside</aside>
    </div>
    <footer>footer</footer>
  </body>
</html>

Песочница

Существует несколько песочниц с flexbox, доступных онлайн для экспериментов:

О чем нужно помнить

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

Flexbox располагаются в соответствие с направлением письма, что означает, что главное начало и главный конец располагаются в зависимости от положения начала и конца (строки - прим.).

Перекрестное начало и перекрестный конец полагаются на определение позиции начала и конца, которое зависит от значения свойства direction.

Разрывы страницы допустимы в расположении flex-контейнеров, когда это позволяет свойство break-. Свойства CSS3 break-after, break-before и break-inside, а также свойства CSS 2.1 page-break-before, page-break-after и page-break-inside работают на flex-контейнере, flex-элементах, а также внутри flex-элементов.

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

Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
Basic support (single-line flexbox) 18.0 (18.0)[6]-moz[2]
22.0 (22.0)
21.0-webkit
29.0
11[3] 12.10-webkit[5] 6.1-webkit[1]
Multi-line flexbox 28.0 (28.0) 21.0-webkit
29.0
11[3] 12.10[5]
15 -webkit
6.1-webkit[1]
Feature Firefox Mobile (Gecko) Firefox OS Android IE Phone Opera Mobile Safari Mobile
Basic support (single-line flexbox) 18.0 (18.0)-moz[2]
22.0 (22.0)

1.0-moz[2]
1.1

2.1-webkit[4]
4.4
11 12.10[5]
15-webkit
7-webkit[1]
Multi-line flexbox 28.0 (28.0) 1.3 2.1-webkit[4]
4.4
11 12.10[5]
15-webkit
7-webkit[1]

[1] Safari до версии 6.0 (iOS.1) поддерживал старую несовместимую черновую версию спецификации. Safari 6.1 (и Safari на iOS 7) был обновлен для поддержки финальной версии.

[2] До Firefox 22, чтобы активировать поддержку flexbox, пользователь должен установить параметр about:config layout.css.flexbox.enabled в значение true. Начиная с Firefox 22 по Firefox 27, параметр установлен в true по умолчанию, и полностью исключен в Firefox 28.

[3] Internet Explorer 10 поддерживает старую несовместимую черновую версию спецификации; Internet Explorer 11 был обновлен для поддержки финальной версии.

[4] Android browser до версии 4.3 поддерживал старую несовместимую черновую версию спецификации. Android 4.4 был обновлен для поддержки финальной версии.

[5] Хотя изначальная реализация в Opera 12.10 flexbox была без приставки, она получила приставку -webkit в версиях с 15 по 16 Opera и с 15 по 19 Opera Mobile. Приставка была снова убрана в Opera 17 и Opera Mobile 24.

[6] До Firefox 29, установка visibility: collapse для flex-элемента заставляет его обрабатываться как display: none вместо предполагаемого поведения, обрабатывающего его как visibility: hidden. Предложенное решение - использовать visibility:hidden для flex-элементов, которые должны вести себя как при установленном visibility:collapse. Для большей информации, см баг 783470.

См. также

  • Проект Flexbugs для информации о багах в браузерных реализациях flexbox.

Метки документа и участники

 Внесли вклад в эту страницу: DmitriyPoltavskiy, MrDaedra, antenko, dixiony, SKaznadei, iamale
 Обновлялась последний раз: DmitriyPoltavskiy,