Довелось мне недавно побывать на собеседовании по специальности HTML-верстальщик/фронтенд-разработчик. Я и мой будущий работодатель встретились, пожали друг-другу руки и... понеслось))
Первым вопросом, в которым меня выстрелили, был "Какие вы знаете значения свойства display?" Ну что же, давайте вспоминать вместе: block
, inline
, inline-block
, inline-table
, list-item
, none
, run-in
, table
, table-caption
, table-cell
, table-column-group
, table-column
, table-footer-group
, table-header-group
, table-row
, table-row-group
. Вот и все, или не все? Да! Мы забыли еще парочку значений. И звать их flex и inline-flex. Тут мой интервьютер оживился и я начал свой рассказ.
Любой дизайнер знает как заставить попотеть верстальщика: для этого нужно попросить его выровнять что-то по вертикали, раскидать блоки затейливым образом, а при изменении размера экрана поменять их местами. И, хотя способов для решения этих задачи существует немало, все они, по сути своей костыли и не всегда работают. Каковы же преимущества Flexible Box Layout Module (или Flexbox чтобы язык не сломать)? А они весьма впечатляют:
- Выравнивание по вертикали и горизонтали, базовой линии текста работает безотказно.
- Расположение элементов в html не имеет решающего значения. Его можно поменять прямо в CSS!!! Это особенно важно для адаптивной верстки.
- Элементы могут автоматически выстраиваться в несколько строк/столбцов, сжиматься и растягиваться по заданным правилам, занимая все предоставленное место. Это еще одно полезное свойство, которое применяется в адаптивной верстве
Итак, пусть у нас имеется следующий HTML код:
<ul class="flex-container">
<li class="flex-block">item1</li>
<li class="flex-block">item2</li>
<li class="flex-block">item3</li>
</ul>
Все, что нам теперь нужно - это написать следующие CSS строки:
.flex-container {
display: -ms-flexbox; /* для IE 10 */
display: -webkit-flex; /* для Chrome */
display: -moz-flex; /* для Firefox */
display: -ms-flex; /* для IE 11 */
display: flex; /* согласно спецификации */
}
Давайте усложним задачу. Хотим 3х колоночную верстку, причем первая и последняя колонка тянется, а средняя фиксированная. И пусть они имеют одинаковую высоту чтобы не случилось) Для этго, нам нужно определить направление, в котором будут располагаться дочерние элементы нашего контейнера. Т.е. направление главной оси и поможет нам в этом css свойство flex-direction. Далее, мы с помощью свойства flex-wrap подскажем браузеру будет ли наш контейнер однострочным или многострочным. А еще лучше, воспользоваться свойством flex-flow, которое представляет собой объединение предыдущих свойств. Но, поскольку в нашем примере мы воспользуемся дефолтными свойствами, то этот шаг можно пропустить. Давайте добавим классы к нашим html тегам чтобы сократить css код:
<section class="flex-container">
<article class="flex-block fluid">какой-то текст</article>
<article class="flex-block fixed">какой-то текст</article>
<article class="flex-block fluid">какой-то текст</article>
</section>
Напишем css, в нем вам должно быть все знакомо:
.flex-block {
background: #ccc;
padding: 30px
}
.fixed {
background: red;
width: 400px;
}
Мы сказали браузеру, что все колонки, кроме той, которая имеет класс fixed
, должны быть с серым фоном. Все колонки должны иметь отступы в 30px, а колонка с классом fixed
должна иметь красный фон и ее длина (без учетов отступов) должна равняться 400px. Теперь нам нужно сказать браузеру, что у нас остальные 2 колонки тянущиеся и имеют одинаковую длину. Для этого достаточно воспользоваться свойством flex и написать:
.fluid {
flex: 1;
}
Строкой flex: 1
мы сказали браузеру, что наши колонки должны занять все доступное пространсnво внутри родительского блока и ширина их должна быть одинаковой. Все это вы наглядно можете увидеть на примере Трехколоночный макет. А как вы думаете, что нужно написать чтобы первая колонка была в 2 раза больше последней? Тот, кто написал нижеприведенный код, может смело взять с полки пирожок.
.fluid:first-child {
flex: 2;
}
Обратите внимание, что высота колонок одинакова, а nеперь вспомните, сколько вам пришлось бы возиться чтобы создать нечто подобное с помощью блоков. Или таблиц... Кстати, чем еще хороши таблицы, так это тем, что их содержимое можно выровнять по вертикали. С этим во Flexbox тоже нет проблем. Каких только свойств для выравнивания не понапридумывали. Это и align-self, и align-content, и justify-content. Нам понадобится align-content: center;
, но, если вы думаете, что можете его просто так взять и добавить к перечню свойств нашего flex-контейнера, то вы сильно недооценили разработчиков. Как всегда все через одно место. Нам придется обернуть наш текст тегом (например, div), обозначить его как flex-контейнер, максимально возможно растянуть по высоте и выравнивать содержимое уже в нем. Наш css-код будет выглядеть так:
.flex-container div {
display: -webkit-flex;
display: flex;
flex-flow: wrap;
align-content: center;
height:100%;
}
Работает? Ха-ха. Как бы не так! Нам опять потребуются костыли. Перепишем наш код:
.fluid:first-child {
flex:2;
position:relative;
}
.flex-container div {
display: -webkit-flex;
display: flex;
flex-flow: row wrap;
-webkit-flex-flow: row wrap;
align-content: center;
position:absolute;
/* 30px - так как у нас отступы в 30px */
top:30px;
left:30px;
bottom:30px;
right:30px;
}
Мы только что осуществили выравнивание текста по высоте. Попробуйте сделать тоже самое с помощью таблиц или блоков. Вы под впечатлением? То ли еще будет! Сделаем полноценную web страцу: хидер, футер и 3 колонки: справа, слева и в центре. Наш HTML код:
<section class="wrapper">
<header class="header">Трехколоночный макет</header>
<article class="main">
<p>Текст</p>
</article>
<aside class="aside aside-1">Меню</aside>
<aside class="aside aside-2">Реклама</aside>
<footer class="footer">Копирайтr</footer>
</section>
Теперь CSS. Пока ничего нового, веселье будет после:
.wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
/* Задаем всем элементам ширину в 100% */
flex: 1 100%;
}
.header {
background: tomato;
}
.footer {
background: lightgreen;
}
.main {
text-align: left;
background: deepskyblue;
}
.aside-1 {
background: gold;
}
.aside-2 {
background: hotpink;
}
html,body {
padding: 0;
margin: 0;
}
Вот, что у нас получилось:
Теперь обещанное веселье: пусть начиная с экранов шириной в 600px меню и реклама будут рядом друг с другом и занимают половину окна браузера, а, начиная с 800px, у нас будет классический 3 колоночный макет: Шапка вверху, подвал внизу. Контент располагается между ними, слева от него меню, справа - рекламный блок.
@media all and (min-width: 600px) {
.aside-1,
.aside-2{ flex: 1 auto; }
}
@media all and (min-width: 800px) {
/* .main должен быть в 2 раза длинее соседних колонок */
.main { flex: 2; }
/* задаем порядок следования */
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
Полюбуйтесь на наш новый Трехколоночный макет с помощью flexbox. На сколько все стало проще!
Уверен, что воодушивившись примерами, вы стали копать дальше и впитывать новую информацию. Хочу сразу дать вам пояснения, чтобы вам бело проще отделять зерна от плевел: Итак, если вы читаете статью о Flexbox и видите display: box; или свойство с именем box-{*}, значит, там обсуждается старая версия Flexbox 2009 года. Если вы видите видите display: flexbox; или функцию flex(), значит, перед вами неуклюжий промежуточный вариант 2011 года. И, наконец, если вы видите надписи display: flex; и свойства flex-{*}, то перед вами текущая спецификация:
-
Современный синтаксис
- display: flex
- flex-direction: row
- justify-content: flex-start
- align-items: flex-start
- flex: 1
Гибридный синтаксис 2011
- display: flexbox
- box-orient: horizontal
- box-pack: start
- box-align: start
- flex: 1
Синтаксис 2009
- display: box
- box-orient: horizontal
- box-pack: start
- box-align: start
- box-flex: 1
И, в заключении, добавлю пару слов о поддержке браузерами:
- IE 10, IE mobile 10
- Синтаксис 2011 г.
- IE11
- С префиксом -ms- поддерживает современный синтаксис
- Firefox 2+
- Синтаксис 2009 г.
- Firefox 22
- современный синтаксис
- Chrome 4+
- Синтаксис 2009 г.
- Chrome 21
- современный синтаксис с префиксом -webkit-
- Chrome 29+
- современный синтаксис без префикса
- Chrome Mobile (Android 4+)
- Синтаксис 2009 г., префикс -webkit-
- Opera 12.1+
- современный синтаксис
- Opera Mobile 16+
- современный синтаксис с префиксом -webkit-
- Safari 3.1+,Safari Mobile (iOS 3.2+)
- Синтаксис 2009 г. с префиксом -webkit-
- Safari 7
- современный синтаксис с префиксом -webkit-
- Android Browser 2.1+
- Синтаксис 2009 г. с префиксом -webkit-