Все свойства flexbox. Flexbox: новый принцип CSS верстки макетов

Flexbox это совершенно новый набор CSS свойств, который позволяет верстальщикам создавать гибкие макеты для сайтов. Он отлично подходит для так называемых отзывчивых макетов, потому что резко снижает сложность верстки. Современные браузеры (включая IE10+, мобильные браузеры iOS и Andrioid) уже поддерживают Flexbox, так что если вы еще не слышали о Flexbox, то самое время, чтобы изучить.

Flexbox готов к использованию

Web изначально задумывался как механизм для обмена научными документами. С тех пор технологии сильно шагнули вперёд, но мы до сих пор используем используем CSS, корнями которого являются те цифровые публикации.

Действительно, CSS верстка и позиционирование элементов на странице являются одними из самых сложных понятий для верстальщиков, независимо от их опыта. Для верстки они используют такие свойства как float , clear , display: block , display: inline для верстки макетов своих сайтов. Но теперь, с новым CSS свойством display: flexbox можно задавать направление, расположение, и промежутки между элементами страницы.

Display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */ display: -ms-flexbox; /* TWEENER - IE 10 */ display: -webkit-flex; /* NEW - Chrome */ display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */

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

Использование Flexbox и его свойства

Объединение Flexbox и CSS медиа запросы (media queries) является мощным инструментом. В примере ниже я сделал упрощённую версию главной страницы сайта Treehouse, использую современный подход mobile-first и flexbox. Откройте этот пример и поизменяйте размер окна браузера.

На первый взгляд может показаться что в примере нет ничего особенного, но если взглянуть на код, то можно увидеть, что верстка выполнена без использования свойства float: left или float: right . Не используются также свойства display: block или display: inline .

Свойство DISPLAY: FLEX

display: flex | inline-flex

Свойство display: flex применяется к родительскому контейнеру, который становится "гибким контейнером " (flex-контейнер), а так же все его прямые потомки являются "гибкими элементами" (flex элементы). Гибкий контейнер имеет главную ось , которая задаёт основное направление для своих прямых потомков (гибких элементов). Поперечная ось перпендикулярна главной оси. Обе эти оси имеют набор свойств с помощью которых можно управлять расположением гибких элементов по отношению друг к другу в контейнере.

Так же можно создавать вложенные flex-контейнеры, как я сделал в примере выше, т.к. свойство display: flex не наследуется. Блокам с классами.header и.nav назначено свойство display: flex . Это похоже на реализацию строк и столбцов в CSS фреймворке Foundation.

Примечания:

  • CSS-столбцы columns не работают с flex-контейнером.
  • float , clear и vertical-align не работают с flex-элементами

Свойство FLEX-DIRECTION

flex-direction: row | row-reverse | column | column-reverse
  • row (по умолчанию): слева направо для ltr, справа налево для rtl;
  • row-reverse : справа налево для ltr, слева направо для rtl;
  • column : аналогично row, сверху вниз;
  • column-reverse : аналогично row-reverse, снизу вверх.

Свойство flex-direction задаёт направление главной оси. Главная ось определяет направление и не обязательно горизонтальное, например при просмотре на мобильных браузерах все элементы контейнера (flex item) группируются в 1 колонку друг за другом. Это задаётся с помощью flex-direction: column . Чтобы элементы контейнера располагались в горизонтальном направлении достаточно задать flex-direction: row .

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

Свойство FLEX

flex: none | [ <"flex-grow"> <"flex-shrink">? || <"flex-basis"> ]

Значение по умолчанию: flex: 0 1 auto .

Свойство flex применяется для элементов flex-контейнера. Это короткая запись, с помощью которой можно задать сразу несколько отдельных свойств: flex-grow , flex-shrink и flex-basis .

Свойства flex-grow и flex-shrink определяют сколько места будет занимать каждый элемент flex-контейнера по отношению друг к другу. По умолчанию flex-grow: 0 , а flex-shrink: 1 . Это означает, что все элементы будут пропорциональны друг к другу.

Свойство flex-basis определяет размеры элементов, чтобы заполнить всё пространство flex-контейнера. Значение этого свойства - auto .

Последние 2 свойства flex-shrink и flex-basis не обязательны. В примере выше, я установил значение flex: 1 для блока с классом.nav , что одно и тоже если прописать ему flex-grow: 1 . Другим flex-элементом в контейнере.header является элемент h1 с классом.logo , для которого установлено flex-grow: 0 , поэтому элемент.nav будет всегда занимать больше места чем элемент.logo .

Свойство JUSTIFY-CONTENT

justify-content: flex-start | flex-end | center | space-between | space-around

Одно из моих любимых свойств, свойство justify-content определяет выравнивание относительно главной оси, помогая распределить оставшееся свободное место внутри flex-контейнера, например, когда его элементы уже не «тянутся», либо тянутся, но уже достигли своего максимального размера. Также позволяет в некотором роде управлять выравниванием элементов при выходе за границы строки.

  • flex-start (по умолчанию): элементы сдвигаются к началу строки;
  • flex-end : элементы сдвигаются к концу строки;
  • center : элементы выравниваются по центру строки;
  • space-between : элементы распределяются равномерно (первый элемент в начале строки, последний - в конце);
  • space-around : элементы распределяются равномерно с равным расстоянием между собой и границами строки.

Иллюстрация работы свойства justyfy-content:

В моём примере, блоку с классом.header я прописал значение justify-content: space-between . Это означает, что первый элемент flex-контейнера будет располагаться в начале main start (см. изображение в главе Свойство DISPLAY: FLEX), а последний элемент будет располагаться в конце main end. Все элементы flex контейнера которые находятся между первым и последним будут распределены равномерно.

Для элемента с классом.nav я применил свойство justify-content: space-around для распределения всего пространства равномерно с отступами вокруг каждого элемента flex-контейнера.

В заключении

Я перечислил только некоторые свойства, которые есть у модуля flexbox . Это достаточно новая технология верстки, и по мере её внедрения в проекты я буду дополнять статью новыми полезными свойствами, которые сильно упростят создание качественных отзывчивых макетов для сайтов.

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

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

Если раньше, миллион лет назад, верстали на таблицах, а потом перелезли на дивы, то сейчас уже без применения flexbox в сочетании с сетками или же готовым css-фреймворком, чувствую, что даже простая верстка на дивах скоро будет считаться «моветоном». Пока это еще не так, но насколько я наблюдаю (точнее, даже не успеваю наблюдать) за развитием в данной области различных методик и best practices, то скорее всего, такой вариант имеет место быть.

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

Верстаем адаптивно

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

Как известно, любой блочный элемент display: block по умолчанию занимает всю доступную ширину экрана, только если мы не определим его ширину явно (либо в px, либо в %) . Но даже если ему будет задана определенная таким образом ширина, то следующий после него блочный элемент будет идти после него с новой строки (этим, кстати и отличается block от inline, который будет следовать друг за другом). Это важный момент, его нужно просто понять, а для того чтобы понять, это дело легко просмотреть в инспекторе любого браузера.

Если же нам надо, чтобы блочные элементы соседствовали друг с другом, то необходимо обтеакание элементов (float), причем нужно задавать ширину блоков в %, чтобы браузер автоматически вычислял ширину в пикселях. Как распространенный пример, это блок контента, а рядом сайдбар. После обтекания элементов, незабываем использовать clearfix, сброс обтекания, чтобы не сломать верстку в дальнейшем.

Самым первым делом мы должны "уведомить" браузер, что хотим использовать адаптивное представление, в соответствии с которым любой браузер будет открывать страницу в этом режиме, делается это вот таким объявлением между тегами head документа:

Meta name="viewport" content="width=device-width, initial-scale=1"

Иными словами, ширина-устройства в масштабе 1:1. И если у вас верстка сделана не адаптивно, то скорее всего будут проблемы при таком отображении в мобильном представлении (скорее всего весь контент сожмется в "гармошку", если логически представить, что может произойти:). Вот с этих пор можно уже говорить о следующем шаге, который есть в любой grid системе или адаптивном фреймворке.

В любой grid системе есть брейкпоинты, точки перехода. Посмотрим на Bootstrap, когда при изменении ширины экрана (мобильный, планшетный вид, и т.д.), происходит проверка элемента, имеющего текущий колоночный класс (к примеру класс десктопа для колонки, в популярном фреймворке Bootstrap, это col-md-{x}, md - десктоп). Классы в свою очередь задают различную ширину в %, равную (100/12) · x, где x - коэффициент ширины, от 1 до 12.

Колоночные классы описывают поведение обтекания элементов: есть класс (в тоже время класс может быть для различных устройств) - обтекание задано, нет - ширина 100% (типично для представления контента на мобильных устройствах). А реализовано это поведение с помощью медиа-запросов, которые понимают все браузеры. Медиа-запрос - в css это понятие означает правило, при выполнении условия которого, подключаются соответствующие стили, например, ширина стала меньше 600px - подключаем новый блок стилей, переопределяющий старый. Например, колоночный класс col-md-{x} подключается по умолчанию от 992px и выше, и отключается до 992px. Но все брейкпоинты бутстраповские по умолчанию можно переопределить своими при компиляции сетки.

Вот и вся простая механика с дивами, которым нужно задать ширину в %, float:left; и очистить обтекание после колонок (в бутстрап колонки оборачиваются во враппер c классом row в этом случае), которые мы выстраиваем в ряд. Все это с легкостью можно реализовать самому и без всякой сетки, когда есть понятие, как это работает, просто в любой сетке прописаны классы и много кода уже написано, вашей задачей остается прописывать классы элементам, вот и все.

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

Тут хочется отметить, что ширина, заданная в %, как в случае с зоной контента и сайдбаром (шапка и подвал по умолчанию занимают всю ширину, 100%), при резайзинге (или открытии страницы на малом экране) сразу же автоматически пересчитывается. Это, пожалуй главное правило, задавать все в %, все остальное браузер сделает сам.

Простой адаптив

header (logo etc)
content
footer (copyright etc)

В дивах у нас пускай будет просто текст пока что, потренируемся выравнивать текст (по горизонтали/вертикали). Еще хорошая практика футер исключать из общего враппера, задавать html и body, height:100%, врапперу: min-height:100%, чтобы футер всегда был прижат к низу страницы.

Я привык использовать scss, приведу листинг кода на нем:

$grey: #808080; $h: 50px; html, body { margin: 0; height: 100%; } body { font-family: monospace, sans-serif; text-transform: uppercase; } .row { display: flex; } .vertical-center { align-items: center; justify-content: center; } .wrap { min-height: 100%; header, .content, .sidebar { border: 1px solid $grey; } header { height: $h; } .content { height: 100px; padding: 15px 15px 0 15px; border-top-width: 0; margin-right: 1%; width: 75%; } .sidebar { height: 120px; padding: 15px 15px 0 15px; border-top-width: 0; width: 25%; } } footer { height: $h; border: 1px solid $grey; }

display: flex; - вкл. flex-контекст; свойство flex-direction: row; - по умолчанию, если не укажем column явно. Это то что нам позволяет делать многие потрясающие вещи. Нe совсем уверен, но вроде пока что это свойство не везде поддерживается caniuse, но пора бы уже выкинуть все эти старые браузеры и установить современные, не так ли? :)

Еще задаем соотношение для ширины контент - сайдбар, 75% : 25%. Тот же самый эффект получился бы, если бы использовали бутстрап. Только с класами col-md-9 для контента ((100/12 · 9)% - ширина в процентах, 75) и col-md-3 для сайдбара ((100/12 · 3)% - ширина в процентах, 25)

Итак, давайте разберемся, что происходит и как работает флексбокс. Самое первое, это нужно задать display:flex тому контейнеру, в котором нам нужно производить центрирование, к примеру. В разметке у меня это шапка, подвал и контейнер, внутри которого контент и сайдбар. Самое простейшее, что эффетивно делает флексбокс здесь, так это просто берет и выравнивает текст, который в шапке и подвале, при помощи класса.vertical-center:


.vertical-center { align-items: center; // выравниваем по центру, по вертикали justify-content: center; // выравниваем по центру, по горизонтали }

В результате, текст выравнен в двух направлениях, в шапке и подвале. Осталась средняя часть, здесь, если бы мы не задали display:flex, то по умолчанию остался бы display:block, что в итоге с блоками контента и сайдбара, получилось вот так:

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

Но перед тем, как перейти к этому главному вопросу, для которого и создавалась эта заметка, давайте немного улучшим наш простой макет в плане адаптивности. Сейчас при ресайзе, контент и сайдбар не складываются друг под друга. Необходимо исправить это, так как, представьте себе, что весь текст при малых разрешениях будет некрасиво «спрессован» в области контента и сайдбара. Я не говорю уже про картинки. Кстати, изображениям, которые будут адаптивными обязательно надо задавать:


img{ display:block; max-width:100%; height:auto; }

Воспользуемся медиа-запросами. Улучшаем наш css, я его переписывать весь не буду, просто оставлю // ... * там где код тот же остался:


// .. $mobileBreak: 479px; html, body { // ... } body { // ... } .row { // ... } .middle { @media (max-width: $mobileBreak) { display: block; } } .vertical-center { // ... } .wrap { // ... header, .content, .sidebar { // ... } header { // ... } .content { // ... @media (max-width: $mobileBreak) { width: auto; margin-right: 0; } } .sidebar { // ... @media (max-width: $mobileBreak) { width: auto; } } } footer { // ... }

Теперь сайдбар сложится под контент на телефонах (<480px):


Работа с выравниваниями

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



// ... $mobileBreak: 479px; @mixin wh($w, $h) { width: $w; height: $h; } // ... .content { // ... padding-top: 0; .content-inner { height: 100%; justify-content: space-between; align-items: center; .bounce { -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; } .red { background: #D9534F; } .green { background: #6AB181; } .blue { background: #2D8CD3; } .wh50 { @include wh(50px, 50px); } .wh60 { @include wh(60px, 60px); } .wh35 { @include wh(35px, 35px); } } @media (max-width: $mobileBreak) { // ... } } // ...

Опять таки, там где знаки, // ... , код остается тот же самый.

Результат:



Как видим, шарики выровнены идеально. При добавлении новых шариков, выравнивание будет происходит также без всяких проблем. Свойство align-items: center; отвечает за выравнивание по вертикали, а justify-content: space-between; равномерно выравнивает по горизонтали.

align-items: flex-start; делает вот так:


По аналогии, после применения align-items: flex-end; шарики оказываются внизу контейнера, а align-items: baseline; делает вот так:


Есть еще свойство align-items: stretch;, оно вроде как вытягивает каждый элемент в высоту, но у меня по быстрому не получилось реализовать, поэтому скрин не покажу.

Это все относится к расположению по горизонтальной оси (по умолчанию). Но если мы сделаем явно column:


.content-inner { flex-direction: column; }

То шарики станут по вертикали! И опять таки, применяя различные свойства align-items, мы будем добиваться всего того, что и при горизонтальном построении шариков, но только уже по вертикали! Еще есть свойство align-self, оно переопределяет свойство align-items для одного какого нибудь шарика, или группы. Вот таким вот способом можно гибко управлять всеми выравниваниями.

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

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



О том, как просто работать с Flexbox на примере верстки шаблона новостного сайта.

Поверьте, нет никакой необходимости в детальном разборе всех аспектов работы с Flexbox, если вы хотите начать им пользоваться уже сейчас. В этом руководстве автор собирается познакомить вас с некоторыми свойствами Flexbox и сделать «новостной лейаут» наподобие того, который вы могли видеть на сайте The Guardian .

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

Ну, поехали!

1. Начинаем с создания двух столбцов

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

В свою очередь, Flexbox упрощает этот процесс, обладая рядом таких преимуществ, как:

Написание более «чистого» кода: от нас лишь требуется создать контейнер с правилом display: flex;
- гибкость: мы можем изменять размер, растягивать и выравнивать столбцы путем изменения пары строк CSS;
- семантическая разметка;
- кроме того, с использованием Flexbox отпадает необходимость отменять обтекание во избежание непредсказуемого поведения лейаута.

Давайте начнем работу с создания двух столбцов, один из которых будет занимать 2/3 ширины нашего контейнера, а еще один - 1/3 его часть.

2/3 column
1/3 column

Здесь присутствуют два элемента:

Контейнер columns;
- два дочерних элемента column , один из которых имеет дополнительный класс main-column , который мы используем позже для того, чтобы сделать столбец шире.

Columns { display: flex; } .column { flex: 1; } .main-column { flex: 2; }
Поскольку main-column имеет значение flex равное 2 , то этот столбец займет в два раза больше места, чем второй.

Добавим немного визуального оформления и, в итоге, получим:

Кликните для просмотра в действии

2. Делаем каждый столбец flexbox-контейнером

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

Итак, нам необходимо, чтобы статьи:

Располагались вертикально внутри столбца-контейнера;
- занимали все доступное место.

Правило flex-direction: column , указанное для контейнера, вместе с правилом flex: 1 , указанным для дочернего элемента, позволяет статье заполнить все свободное место по вертикали, при этом высота первых двух столбцов останется неизменной.


Кликните для просмотра в действии

3. Делаем контейнер из статьи

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

Заголовок;
- параграф;
- информационную панель с именем автора и количеством комментариев;
- какую-нибудь адаптивную картинку.

Здесь мы используем Flexbox для того, чтобы «прижать» информационную панель к низу элемента. Вот, посмотрите, какой результат мы ожидаем получить.

А вот и сам код:


.article { display: flex; flex-direction: column; flex-basis: auto; /* Устанавливает начальный размер элемента в зависимости от его содержимого */ } .article-body { display: flex; flex: 1; flex-direction: column; } .article-content { flex: 1; /* Содержимое заполняет все оставшееся место, тем самым прижимая информационную панель к нижней части */ }
Элементы внутри статьи расположены вертикально благодаря использованию правила flex-direction: column .

Также мы применили свойство flex: 1 к элементу article-content , тем самым растянув его на все свободное место и прижав article-info к низу. Высота столбцов в этом случае не имеет значения.


Кликните для просмотра в действии

4. Добавляем несколько вложенных столбцов

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


Поскольку мы хотим, чтобы первый вложенный столбец был шире, добавим к элементу класс nested-column , а в CSS укажем:

Nested-column { flex: 2; }
Теперь этот столбец будет вдвое шире второго.


Кликните для просмотра в действии

5. Делаем первую статью с горизонтальным лейаутом

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

First-article { flex-direction: row; } .first-article .article-body { flex: 1; } .first-article .article-image { height: 300px; order: 2; padding-top: 0; width: 400px; }
Свойство order в данном случае играет большую роль, поскольку оно позволяет изменять очередность HTML-элементов без изменения HTML-разметки. В действительности, article-image в коде идет перед элементом article-body , но ведет себя так, будто стоит после него.


Кликните для просмотра в действии

6. Делаем адаптивный лейаут

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

Одной из замечательных вещей в Flexbox является то, что достаточно удалить правило display: flex в контейнере для того, чтобы полостью отключить его (Flexbox), в то время, как остальные его свойства (такие, как align-items или flex ) останутся рабочими.

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

Итак, мы собираемся удалить display: flex из селекторов .columns и .column , вместо этого «запаковав» их в медиа-запрос:

@media screen and (min-width: 800px) { .columns, .column { display: flex; } }
Вот и все! На экранах с маленьким разрешением все статьи будут располагаться друг над другом, а на экранах с разрешением свыше 800 пикселей - в два столбца.

7. Добавляем завершающие штрихи

Для того, чтобы лейаут выглядел более привлекательно на больших экранах, давайте добавим кое-какие CSS-твики:

@media screen and (min-width: 1000px) { .first-article { flex-direction: row; } .first-article .article-body { flex: 1; } .first-article .article-image { height: 300px; order: 2; padding-top: 0; width: 400px; } .main-column { flex: 3; } .nested-column { flex: 2; } }
Содержимое первой статьи выровнено по горизонтали: текст расположен по левой стороне, а картинка - по правой. Также, главный столбец теперь стал шире (75%). То же самое касается и вложенного столбца (66%).

А вот и финальный результат!


Кликните для просмотра в действии

Вывод

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

Содержание:

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

UPD от 02.02.2017: сделала удобную шпаргалку по флексбоксам, с живыми демками и описаниями из спеки: Flexbox cheatsheet .

В примерах используется только новый синтаксис. На момент написания статьи правильней всего они отображаются в Chrome . В Firefox работают частично, в Safari - вообще не работают.

Согласно сайту caniuse.com , Flexbox не поддерживается 8 и 9-м IE и Opera Mini, а в других браузерах поддерживаются не все свойства и/или требуются префиксы.

Это означает, что технологию нельзя широко использовать прямо сейчас, но уже самое время познакомиться с ней поближе.

Для начала надо знать, что flex-элементы располагаются по осям. По умолчанию элементы располагаются по горизонтали - вдоль main axis - главной оси.

Так же следует иметь в виду, что при использовании Flexbox для внутренних блоков не работают float , clear и vertical-align , а так же свойства, задающие колонки в тексте.

Приготовим полигон для экспериментов:

Один родительский блок (желтый) и 5 дочерних.

Display: flex

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

display: flex; делает все дочерние элементы резиновыми - flex , а не инлайновыми или блочными, как было изначально.

Если родительский блок содержит картинки или текст без оберток, они становятся анонимными flex-элементами.

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

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

inline-flex - ведёт себя как инлайн-блочный. Приоритет у содержимого (контент растопыривает блоки до необходимой ширины, чтобы строчки, по возможности, поместились).

Flex-direction

Направление раскладки блоков управляется свойством flex-direction .

Возможные значения:

row - строка (значение по умолчанию); row-reverse - строка с элементами в обратном порядке; column - колонка; column-reverse - колонка с элементами в обратном порядке.

row и row-reverse

column и column-reverse

Flex-wrap

В одной строке может быть много блоков. Переносятся они или нет определяет свойство flex-wrap .

Возможные значения:

nowrap - блоки не переносятся (значение по умолчанию); wrap - блоки переносятся; wrap-reverse - блоки переносятся и располагаются в обратном порядке.

Для короткой записи свойств flex-direction и flex-wrap существует свойство: flex-flow .

Возможные значения: можно задавать оба свойства или только какое-то одно. Например:

flex-flow: column; flex-flow: wrap-reverse; flex-flow: column-reverse wrap;

Демо для row-reverse wrap-reverse:

Order

Для управления порядком блоков служит свойство order .

Возможные значения: числа. Чтобы поставить блок самым первым, задайте ему order: -1:

Justify-content

Для выравнивания элементов есть несколько свойств: justify-content , align-items и align-self .

justify-content и align-items применяются к родительскому контейнеру, align-self - к дочерним.

justify-content отвечает за выравнивание по главной оси.

Возможные значения justify-content:

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

flex-start и flex-end

space-between , space-around

Align-items

align-items отвечает за выравнивание по перпендикулярной оси.

Возможные значения align-items:

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

flex-start , flex-end

baseline , stretch

Align-self

align-self также отвечает за выравнивание по перпендикулярной оси, но задается отдельным flex-элементам.

Возможные значения align-self:

auto - значение по умолчанию. Означает, что элемент использует align-items родительского элемента; flex-start - элемент выравнивается от начала перпендикулярной оси; flex-end - элемент выравнивается от конца перпендикулярной оси; center - элемент выравнивается по центру; baseline - элемент выравнивается по базовой линии; stretch - элемент растягивается, занимая все пространство по высоте.

Align-content

Для управления выравниванием внутри многострочного flex-контейнера есть свойство align-content .

Возможные значения:

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

flex-start , flex-end

center , stretch

space-between , space-around

Ps: Некоторые штуки мне так и не удалось увидеть в действии, например, строчку flex-flow: column wrap или полную запись того же flex-direction: column; flex-wrap: wrap; .

Элементы стоят столбиком, но не переносятся:

Не срабатывает wrap при flex-direction: column; , хотя в спеке это выглядит вот так:

Думаю, со временем заработает.

UPD от 21.06.2014: всё работает, если задать блоку высоту. За подсказку спасибо

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

Поддержка браузерами технологии CSS Flexbox

Технология Flexbox поддерживается уже почти всеми используемые на сегодняшний момент браузерами (с использованием префиксов: IE10+, Edge12+, Firefox 2+, Chrome 4+, Safari 3.1+, Opera 12.1+, iOS Safari 3.2, Opera mini, Android 2.1+, Blackberry 7+).

Основы Flexbox (сетка)

В основу Flexbox положена сетка. Она состоит всего из 2 элементов. Первый элемент – это flex-контейнер . Создание flex-контейнера осуществляется посредством добавления к необходимому HTML элементу CSS-свойства display со значением flex или flex-inline .

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

HTML разметка:

1
2
3
4

Flex-container { display: flex; /* flex || inline-flex */ } Структура flexbox сетки

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

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

Направление выстраивания flex-элементов

Указание направления выстраивания flex-элементов внутри flex-контейнера осуществляется посредством осей .


Во flexbox выделяют 2 оси . Первая ось называется основной или главной (по умолчанию направлена вправо). Вторая - поперечная (по умолчанию направлена вниз).

Элементы во flex-контейнере располагаются в одну линию (по умолчанию) даже тогда, когда им не хватает места. Выстраиваются flex-элементы в flex-контейнере по направлению основной оси.

Расположение элементов в контейнере по умолчанию (flex-элементы, которым не хватает места во flex-контейнере, вылезают за его пределы)

В CSS Flexbox разрешить перенос flex-элементов на новые линии (если им не хватает места в текущей линии) осуществляется с помощью установки flex-контейнеру CSS свойства flex-wrap со значением wrap или wrap-reverse .

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

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

Установка направления главной оси flexbox осуществляется с помощью CSS-свойства flex-direction .

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

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


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

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

Выравнивание flex-элементов

Во Flexbox выравнивание элементов внутри контейнера осуществляется по двум направлениям (осям).

Выравнивание flex-элементов по направлению главной оси

Выравнивание элементов вдоль основной оси осуществляется с помощью CSS свойства justify-content:

Justify-content: flex-start; /* flex-start (flex-элементы выравниваются относительно начала оси) – по умолчанию flex-end (flex-элементы выравниваются относительно конца оси) center (по центру flex-контейнера) space-between (равномерно, т.е. с одинаковым расстоянием между flex-элементами) space-around (равномерно, но с добавлением половины пространства перед первым flex-элементом и после последнего) */ Варианты выравнивания flex-элементов вдоль главной оси

Выравнивание flex-элементов вдоль поперечной оси

Выравнивание flex-элементов во flex-контейнере по направлению поперечной оси осуществляется с помощью CSS-свойства align-items:

Align-items: stretch; /* stretch (растягиваются по всей длине поперечной оси) – по умолчанию flex-start (относительно начала поперечной оси) flex-end (относительно конца поперечной оси) baseline (относительно базовой линии) center (по центру) */ Варианты выравнивания flex-элементов вдоль поперечной оси

Выравнивание линий flex-контейнера

CSS Flexbox позволяет выравнивать не только сами flex-элементы, но и линии на которых они расположены.

Align-content: stretch /* stretch (растягиваются по всей длине поперечной оси) – по умолчанию flex-start (относительно начала поперечной оси) flex-end (относительно конца поперечной оси) center (по центру) space-between (равномерно, т.е. с одинаковым расстоянием между линиями) space-around (равномерно, но с добавлением половины пространства перед первой линией и после последней) */ Варианты выравнивания линий flex-контейнера

Свойство align-content имеет смысл использовать только тогда, когда flex-элементы во flex-контейнере располагаются на нескольких линиях. Чтобы это произошло, необходимо, во-первых, чтобы ширина всех flex-элементов была больше ширины flex-контейнера, а во-вторых flex-контейнер должен иметь в качестве CSS-свойства flex-wrap значение wrap или wrap-reverse .

CSS-свойство align-self

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

Align-items: stretch; /* auto (по умолчанию) || stretch || flex-start || flex-end || baseline || center */

1
2
3
4

Flex-container { display: flex; width: 300px; height: 150px; align-items: center; padding: 10px; background-color: #efefef; } .flex-container_element-1, .flex-container_element-2, .flex-container_element-3, .flex-container_element-4 { flex-basis: 70px; text-align: center; padding: 15px; font-size: 30px; } .flex-container_element-1 { align-self: flex-start; background: #fe4; } .flex-container_element-2 { align-self: flex-end; background: pink; } .flex-container_element-3 { align-self: stretch; background: lime; } .flex-container_element-4 { align-self: auto; background: cyan; } Как работает CSS свойство align-self

Изменение порядка следования flex-элементов

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

Order: 0; /* 0 (по умолчанию) целое положительное или отрицательное число */

Например:

...
...
...
...
CSS: .flex-container { display: flex; } /* переместим 2 flex-элемент в конец */ .flex-container_element-2 { order: 2; } /* передвинем 3 элемент до 2 */ .flex-container_element-3 { order: 1; } /* расположим 4 flex-элемент до 1 */ .flex-container_element-4 { order: -1; } Как работает CSS свойство order

Управление шириной flex-элемента

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

CSS-свойство flex-basis

Данное свойство предназначено для установления начальной ширины flex-элементу . Задавать значение ширины можно посредством различных единиц измерения, таких как px, %, em и др. По умолчанию данное свойство имеет значение auto (в этом случае ширина элемента будет рассчитываться автоматически на основании его содержимого).

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

CSS-свойство flex-grow

Это свойство определяет, может ли начальная ширина flex-элемента увеличиваться (расти) . Увеличение ширины flex-элемента осуществляется за счёт свободного пространства линии . В качестве значения CSS-свойства flex-grow указывается целое число . Именно это значение и определяет (если оно больше или равно 1) какую часть свободного пространства flex-элемент заберёт себе.

Например:

...
...
CSS: .flex-container { display: flex; width: 600px; } .flex-container_element-1 { flex-basis: 40%; flex-grow: 1; } .flex-container_element-2 { flex-basis: 40%; flex-grow: 4; } Как работает CSS свойство flex-grow

В этом примере, если flex-элементы расположены на одной линии и в ней есть свободное пространство (600×(1-0,8)=120px):

  • к ширине элемента.flex-container_element-1 добавится 1/5 часть этого пространства (120×1/5=24px);
  • к ширине элемента.flex-container_element-2 добавится 4/5 части этого пространства (120×4/5=96px).

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

По умолчанию CSS свойство flex-grow имеет значение 0. Это означает, что flex-элемент не может расти (увеличивать свою ширину).

CSS-свойство flex-shrink

Данное свойство определяет, может ли ширина flex-элемента уменьшиться. Уменьшение ширины flex-элемента будет осуществляться только в том случае, если ширины линии будет не достаточно для отображения всех flex-элементов , расположенных в ней. Необходимая ширина рассчитывается на основании начальной ширины , который имеет каждый flex-элемент в ней.

Например:

...
...
CSS: .flex-container { display: flex; width: 500px; } .flex-container_element-1 { flex-basis: 300px; flex-shrink: 1; } .flex-container_element-2 { flex-basis: 300px; flex-shrink: 3; } Как работает CSS свойство flex-shrink

Ширина flex-контейнера 500px. Для отображения flex-элементов необходимо 600px. В итоге не хватает 100px. В этом примере уменьшаться могут 2 flex-элемента (.flex-container_element-1 и.flex-container_element-2). Ширина первого flex-элемента.flex-container_element-1 в данном случае составит 300 – 1/4*100= 275px. Ширина второго flex-элемента.flex-container_element-2 в данном случае составит 300 – 3/4*100= 225px.

Значение по умолчанию:

Flex-shrink: 1;

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

CSS-свойство flex

Для удобной установки flex-grow , flex-shrink и flex-basis можно использовать CSS свойство flex .

Значение по умолчанию:

Flex: 0 1 auto; /* 0 - flex-grow (1 значение) 1 - flex-shrink (2 значение) auto - flex-basis (3 значение) */

Верстка макета страницы на CSS Flexbox

В этом разделе создадим простой адаптивный макет на Flexbox.

Структура макета будет состоять из 3 секций:

  • header (для вывода заголовка и основного меню);
  • main (для отображения основной части);
  • footer (для футера).

Основную часть (main) в свою очередь разделим ещё на 2 раздела (их позиционирование будем осуществлять с помощью CSS Flexbox). На больших экранах (>=992px) эти разделы выстроим горизонтально, а на остальных - вертикально (<992px).

[Шапка страницы...]
[Основная часть...]
[Футер...]
CSS: /* контейнер (устанавливает ширину блока в зависимости от ширины viewport) */ .container { position: relative; margin-left: auto; margin-right: auto; padding-right: 15px; padding-left: 15px; } @media (min-width: 576px) { .container { width: 540px; max-width: 100%; } } @media (min-width: 768px) { .container { width: 720px; max-width: 100%; } } @media (min-width: 992px) { .container { width: 960px; max-width: 100%; } } @media (min-width: 1200px) { .container { width: 1140px; max-width: 100%; } } /* flex-контейнер */ .row-flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; } /* CSS настройки flex-элементов */ .col-flex { position: relative; width: 100%; min-height: 1px; padding-right: 15px; padding-left: 15px; } /* ширина блоков article и aside по умолчанию */ .main_article, .main_aside { -webkit-box-flex: 0; -webkit-flex: 0 0 100%; -ms-flex: 0 0 100%; flex: 0 0 100%; max-width: 100%; } /* ширина блоков article и aside для больших экранов */ @media (min-width: 992px) { /* 2/3 от ширины контейнера */ .main_article { -webkit-box-flex: 0; -webkit-flex: 0 0 66.666667%; -ms-flex: 0 0 66.666667%; flex: 0 0 66.666667%; max-width: 66.666667%; } /* 1/3 от ширины контейнера */ .main_aside { -webkit-box-flex: 0; -webkit-flex: 0 0 33.333333%; -ms-flex: 0 0 33.333333%; flex: 0 0 33.333333%; max-width: 33.333333%; } }

Для поддержки макета большинством браузеров добавим в CSS необходимые префиксы и max-width .

Для «превращения» блока во flex-контейнер будем использовать класс row-flex . Установку ширины каждому flex-элементу (main_article и main_aside) внутри flex-контейнера будем осуществлять с помощью CSS-свойства flex .


В качестве примера разметим посредством Flexbox ещё блок «Футер» и секцию раздела main-article «Интересненькое на сайте».

Секцию «Футер» разделим на 4 равные части (минимальная ширина одной части - 200px), а «Интересненькое на сайте» на 3 части (минимальная ширина одной части - 300px).

[Шапка страницы...]
[Основная часть...]
[Ещё 1...]
[Ещё 2...]
[Ещё 3...]

Дополнительный CSS:

Footer_block, .main_other_article { -webkit-flex-basis: 0; -ms-flex-preferred-size: 0; flex-basis: 0; -webkit-box-flex: 1; -webkit-flex-grow: 1; -ms-flex-positive: 1; flex-grow: 1; max-width: 100%; }