Flexbox (April 2012)

Апрель 04, 2012 ||  css , layout ||  комментарии

Flexible Box Layout Module – новая модель компоновки блоков в CSS3.

Спецификация была изменена поэтому статья устарела

Все тесты я делал на Chrome Canary (20.0.1093.0), поэтому вполне могут быть несоответствия, но все похоже на правду.

HTML во всех примерах:

<section> <div>A</div> <div>B</div> <div>C</div> </section>

display

Flexbox модель начинает работать с того что мы определяем элемент контейнер как flexbox. Дальше флексбокс-элементами считаются элементы которые являются прямыми предками флексбокс контейнера.

section { display: flexbox; }

Значением display может быть flexbox или inline-flexbox.

Поскольку flexbox это новая модель построения блоков некоторые css свойства, которые предполагают поведение блоков по блочной (старой) модели, не будут работать. А именно:

  • column-*
  • float и clear
  • vertical-align

Абсолютно позиционированный элемент-предок не будет вести себя как флексбокс-элемент и не будет влиять компоновку.

flex-direction

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

section { flex-direction: row | row-reverse | column | column-reverse; }

row – означает что блоки будут выстраивается по горизонтальной линии column – по вертикальной, как обычные блоки.

flex-direction

flex-wrap

section { flex-wrap: nowrap | wrap | wrap-reverse; }

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

Примеры будут ниже.

flex-flow

section { flex-flow: <'flex-direction'> || <'flex-wrap'>; }

Cокращенная запись двух свойств, видно из синтаксиса.

flex-order

section div{ flex-order: <number>; }

С этим все прозрачно, применяется к флексбокс элементу.

flex-order

flex

section div{ flex: [ [ <pos-flex> <neg-flex>? ] || <preferred-size> ] | none; }

Свойство которое отвечает за ширину элемента. Применяется к флекбокс элементу. Первые два свойства это положительные числа, действуют как “сила пружины”, или как доля элемента от общей доступной области. pos-flex – максимальное значение, neg-flex – минимальное, дефолтные значения – 1 и 0.preferred-size – предпочитаемый размер, который должен иметь элемент.

Если вы хотите указать предпочитаемый размер – 0 то надо указывать размерность, чтобы не было конфликта с значением “веса”.

На примере видно что значение auto для предпочитаемого размера начинает учитывать количество контента в блоке.

flex

flex-pack

section { flex-pack: start | end | center | justify | distribute; }

Свойство которое выравнивает блоки относительно главной оси, то есть той по которой выстраиваются блоки.

flex-pack

Все примеры здесь для горизонтального потока (flex-flow: row), но все то же самое будет для вертикального. Примеры будут ниже.

section {
    flex-align: start | end | center | justify | distribute | stretch;
}
section div{
    flex-item-align: start | end | center | justify | distribute | stretch;
}

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

Стоит запомнить что дефолтное значение flex-align: stretch , поэтому в случае flex-flow: row блоки будут высотой контейнера, что мне было странно )

flex-align

А вот это полный П. Не могу поверить что такое вообще возможно )

flex-item-align

Многострочный flexbox

Пример для понимания как работает flex-wrap

multi-line flexbox

Интересная деталь – я указал размеры боксов в пикселах, хотя изначально пытался в процентах – 50%. И блоки не хотели выстраиваться по два в строку. Флексбокс-элемент ведет себя подобно инлайн-блоку, то есть блоки не стыкуются без зазора. Хотя это может быть реализацией в Canary.

flex-line-pack

section { flex-line-pack: start | end | center | justify | distribute | stretch; }

Эта штука служит для выравнивания осей флексбокс элементов когда их несколько, то есть это свойство работает только для flex-wrap: wrap

flex-line-pack

Немного едет крыша от количества свойств для выравнивания, но вроде все логично, выравнивать мы можем:

  • боксы по оси “выстраивания”
  • боксы по перпендикуляру к ней же
  • строки боксов по вертикали когда их несколько

По теме:

Где работает:

comments powered by Disqus