МУДРЕНЫЙ HTML&CSS

УРОК Nº 8.

Самый понятный учебник современной CSS-верстки

МУДРЕНЫЙ HTML&CSS

FLEXBOX

УРОК Nº 8.

Самый понятный учебник современной CSS-верстки

Режим макета Flexbox ["Гибкий блок"] предлагает альтернативу плавающим элементам Floats для создания общего вида веб-страницы. В то время как плавающие элементы позволяют нам только горизонтально располагать наши блоки, flexbox дает нам полный контроль над выравниванием, направлением, порядком и размером наших блоков.

Interneting is hard HTML+CSS
Скриншот 1: сравнение свойств выравнивания (alignment), направления (direction), порядка (order) и размера (size) flexbox

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

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

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

Interneting is hard HTML+CSS
Скриншот 2: плавающие элементы Floats для обтекания текста вокруг блока ("журнальная" структура) и Flexbox для остальной части макета (основная структура страницы)

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

подготовка
setup

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

Interneting is hard HTML+CSS
Скриншот 3: веб-страница с макетом на основе flexbox

Для начала нам нужен пустой HTML-документ, в котором нет ничего, кроме строки меню. Создайте новый Atom-проект под названием flexbox, в котором будут храниться все файлы примеров для этого урока. Затем создайте файл flexbox.html и добавьте в него следующую разметку:

<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Some Web Page</title>
<link rel='stylesheet' href='styles.css'/>
</head>
<body>
<div class='menu-container'>
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='signup'>Sign Up</div>
<div class='login'>Login</div>
</div>
</div>
</body>
</html>

Далее нужно создать таблицу стилей styles.css. Выглядеть это будет не очень презентабельно: просто синяя полоса меню во всю ширину с белым блоком в ней. Обратите внимание, что для центрирования меню мы будем использовать flexbox вместо уже привычной техники auto-margin.

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.menu-container {
color: #fff;
background-color: #5995DA; /* синий */
padding: 20px 0;
}

.menu {
border: 1px solid #fff; /* для отладки */
width: 900px;
}

Напоследок скачайте несколько изображений для нашего примера веб-страницы. Распакуйте их в проект flexbox, сохранив родительский каталог images. Ваш проект должен выглядеть примерно так:

Interneting is hard HTML+CSS
Скриншот 4: скриншот файлов проекта
обзор
flexbox overview

Flexbox использует два типа блоков, которые мы никогда не видели раньше: "flex контейнеры" [flex containers] и "flex элементы" [flex items]. Задача flex контейнера - сгруппировать несколько flex элементов и определить, как они будут располагаться.

Interneting is hard HTML+CSS
Скриншот 5: flex-контейнер в виде выделенного контейнера, обертывающего серые элементы, и flex-элементы в виде выделенных блоков внутри контейнера

Каждый HTML-элемент, являющийся прямым дочерним элементом flex контейнера, представляет собой "элемент" [flex item]. Flex элементами можно манипулировать по отдельности, но в основном их расположение определяет контейнер. Основная задача flex элементов - сообщить контейнеру, сколько элементов ему нужно расположить.

Как и в случае с макетами на основе плавающих элементов [floats], создание сложных веб-страниц с помощью flexbox сводится к созданию вложенных блоков. Вы выравниваете кучу flex элементов внутри контейнера, и, в свою очередь, эти элементы могут служить flex контейнерами для своих собственных элементов. Работая с примерами этого урока, помните, что основная задача компоновки страницы не изменилась: мы по-прежнему просто перемещаем группу вложенных блоков.

флекс-контейнеры
flex containers

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

Добавьте следующую строку в наше правило .menu-container, чтобы превратить его в flex контейнер:

.menu-container {
/* ... */
display: flex;
}

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

Interneting is hard HTML+CSS
Скриншот 6: смешивание и сочетание макета flexbox с блочными блоками и плавающими элементами

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

Выравнивание элемента
aligning a flex item

После того как вы создали flex-контейнер, нужно задать горизонтальное выравнивание его элементов. Для этого предназначено свойство justify-content. Мы можем использовать его, чтобы выровнять по центру наше .menu, как показано ниже:

.menu-container {
/* ... */
display: flex;
justify-content: center; /* добавьте это */
}

Это имеет тот же эффект, что и добавление объявления margin: 0 auto к элементу .menu. Но обратите внимание, что мы добавили свойство к родительскому элементу (flex-контейнеру), а не непосредственно к элементу, который мы хотим выровнять по центру (flex-элементу). Управление элементами через их контейнеры является общей темой в flexbox, и это немного отличается от того, как мы позиционировали блоки до сих пор.

Interneting is hard HTML+CSS
Скриншот 7: flex-start (3 блока с выравниванием по левому краю), center (3 блока с выравниванием по центру), flex-end (3 блока с выравниванием по правому краю)

Другие значения для justify-content показаны ниже:

Попробуйте изменить justify-content на flex-start и flex-end. Это позволит выровнять меню по левой и правой стороне окна браузера соответственно. Не забудьте изменить его обратно на center, прежде чем двигаться дальше. Последние две опции полезны только когда в контейнере находятся несколько flex-элементов.

Распределение нескольких элементов
distributing multiple flex items

"Подумаешь! Мы уже умеем выравнивать влево/вправо с помощью плавающих элементов и центрировать с помощью auto-margins" - скажете вы. Верно. Но Flexbox не проявляет себя по-настоящему, пока в контейнере всего один элемент. Свойство justify-content также позволяет равномерно распределить элементы внутри контейнера.

Interneting is hard HTML+CSS
Скриншот 8: space-around (3 блока с одинаковым пространством между ними и их контейнером), space-between (3 блока с пробелами между ними, но не между их контейнером)

Измените наше правило .menu следующим образом:

.menu {
border: 1px solid #fff;
width: 900px;
display: flex;
justify-content: space-around;
}

Это превращает наше .menu во вложенный flex контейнер, а значение space-around распределяет его элементы по всей ширине. Вы должны увидеть что-то вроде этого:

Interneting is hard HTML+CSS
Скриншот 9: веб-страница, на которой элементы <li> строки меню размещены с использованием пространства между ними

Flex-контейнер автоматически распределяет дополнительное горизонтальное пространство по обе стороны от каждого элемента. Значение space-between аналогично, но оно только добавляет дополнительное пространство между элементами. Это именно то, что требуется для нашей страницы. Поэтому обновите строку justify-content:

justify-content: space-between;

Конечно, вы также можете использовать здесь center, flex-start, flex-end, если хотите сдвинуть все элементы в ту или иную сторону. Но давайте оставим значение space-between.

группировка элементов
grouping flex items

Flex контейнеры умеют позиционировать только элементы, находящиеся уровнем ниже (то есть свои дочерние элементы). Их нисколько не волнует, что находится внутри тех flex элементов. Это означает, что группировка flex элементов - еще одно оружие в вашем арсенале для создания HTML-макета. Если обернуть множество элементов в дополнительный <div>, получится совершенно другая веб-страница.

Interneting is hard HTML+CSS
Скриншот 10: обертывание двух flex-элементов в <div> для устранения одного из flex-элементов

Предположим, вы хотите, поместить ссылки Sign Up и Login в правую часть страницы (см. скриншот ниже). Для этого достаточно поместить их в другой <div>:

<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='links'>
<div class='signup'>Sign Up</div> <!-- это вложено -->
<div class='login'>Login</div> <!-- и это вложено -->
</div>
</div>

Вместо трех элементов в нашем flex-контейнере .menu теперь только два (.date и .links). В соответствии с существующим поведением пространства между ними, они будут привязаны к левой и правой стороне страницы.

Interneting is hard HTML+CSS
Скриншот 11: веб-страница, c двумя полями меню, внутри контейнеров <div>

Но теперь нам нужно разместить элемент .links, поскольку он использует стандартный режим блокового размещения. Решение: больше вложенных flex-контейнеров! Добавьте новое правило в наш файл styles.css, которое превратит элемент .links в flex-контейнер:

.links {
border: 1px solid #fff; /* для отладки */
display: flex;
justify-content: flex-end;
}

.login {
margin-left: 20px;
}

Это позволит разместить наши ссылки именно там, где мы хотим. Обратите внимание, что поля по-прежнему работают так же, как и в блоковой модели CSS. Как и в обычной блоковой модели, в flexbox особое значение имеют auto отступы (подробнее об этом в конце урока).

Interneting is hard HTML+CSS
Скриншот 12: поля меню, размещенные с помощью вложенных контейнеров flexbox

Белые рамки нам больше не понадобятся. Можно их смело удалить.

выравнивание по оси (вертикальное)
cross-axis (vertical) alignment

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

Interneting is hard HTML+CSS
Скриншот 13: justify-content (слева и справа), align-items (сверху и снизу)

Чтобы изучить это, нам нужно добавить заголовок под нашим меню. Добавьте следующую разметку в файл flexbox.html после элемента .menu-container:

<div class='header-container'>
<div class='header'>
<div class='subscribe'>Subscribe ▾</div>
<div class='logo'><img src='images/awesome-logo.svg'/></div>
<div class='social'><img src='images/social-icons.svg'/></div>
</div>
</div>

Затем добавьте несколько базовых стилей, чтобы выровнять его по элементу .menu:

.header-container {
color: #5995DA;
background-color: #D6E9FE;
display: flex;
justify-content: center;
}

.header {
width: 900px;
height: 300px;
display: flex;
justify-content: space-between;
}

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

Interneting is hard HTML+CSS
Скриншот 14: вертикальное выравниванием в контейнере заголовка с помощью свойства align-items

Вертикальное выравнивание определяется добавлением свойства align-items к flex-контейнеру. Чтобы наша страница-пример соответствовала приведенному выше скриншоту, добавьте следующую строку:

.header {
/* ... */
align-items: center; /* добавьте это */
}

Варианты свойства align-items аналогичны justify-content:

Interneting is hard HTML+CSS
Скриншот 15: flex-start (блоки в верху контейнера), center (блоки в центре контейнера), flex-end (блоки в низу контейнера, stretch (блоки, заполняющие высоту контейнера)

Большинство из вышеназванных вариантов довольно просты. С вариантом stretch стоит немного поэкспериментировать, потому что stretch позволяет отобразить фон каждого элемента. Давайте рассмотрим это ближе, добавив в файл styles.css следующее:

.header {
/* ... */
align-items: stretch; /* Измените это */
}

.social,
.logo,
.subscribe {
border: 1px solid #5995DA;
}

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

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

обертывание элементов
wrapping flex items

Flexbox - это более мощная альтернатива grid-сеткам на основе плавающих элементов. Он может не только отображать элементы в виде сетки, но и изменять их выравнивание, направление, порядок и размер. Для создания сетки нам понадобится свойство flex-wrap.

Interneting is hard HTML+CSS
Скриншот 16: без обертывания (блоки выходят за пределы контейнера), с обертыванием (блоки переходят на следующую строку в контейнере)

Добавьте ряд фотографий в файл flexbox.html, чтобы нам было с чем работать. Поместите их внутрь <body>, под элементом .header-container:

<div class='photo-grid-container'>
<div class='photo-grid'>
<div class='photo-grid-item first-item'>
<img src='images/one.svg'/>
</div>
<div class='photo-grid-item'>
<img src='images/two.svg'/>
</div>
<div class='photo-grid-item'>
<img src='images/three.svg'/>
</div>
</div>
</div>

Опять же, соответствующие CSS должны быть вам знакомы по предыдущим секциям:

.photo-grid-container {
display: flex;
justify-content: center;
}

.photo-grid {
width: 900px;
display: flex;
justify-content: flex-start;
}

.photo-grid-item {
border: 1px solid #fff;
width: 300px;
height: 300px;
}

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

<div class='photo-grid-item'>
<img src='images/four.svg'/>
</div>
<div class='photo-grid-item last-item'>
<img src='images/five.svg'/>
</div>

По умолчанию они вытекают за край страницы:

Interneting is hard HTML+CSS
Скриншот 17: веб-страница с неправильной версткой из-за отсутствия обертывания flexbox

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

.photo-grid {
/* ... */
flex-wrap: wrap;
}

Теперь наши flex-элементы ведут себя так же, как плавающие элементы, только flexbox дает нам больше контроля над тем, как "лишние" элементы выравниваются в последней строке с помощью свойства justify-content. Например, последняя строка сейчас выровнена по левому краю. Попробуйте выровнять ее по центру, обновив наше правило .photo-grid, например, так:

.photo-grid {
width: 900px;
display: flex;
justify-content: center; /* Измените это */
flex-wrap: wrap;
}

Добиться этого с макетами на основе плавающих элементов невероятно сложно.

Interneting is hard HTML+CSS
Скриншот 18: веб-страница, с корректной grid-сеткой, созданной с помощью правильного обертывания flexbox
направление контейнера
flex container direction

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

Interneting is hard HTML+CSS
Скриншот 19: ряд (ROW - 3 горизонтальных блока), столбец (COLUMN - 3 вертикальных блока)

Одна из самых удивительных вещей в flexbox - его способность преобразовывать ряды в столбцы с помощью всего одной строки CSS. Попробуйте добавить следующее объявление flex-direction в наше правило .photo-grid:

.photo-grid {
/* ... */
flex-direction: column;
}

Это изменит направление контейнера по сравнению со стандартным значением ряда [row value]. Вместо сетки наша страница теперь имеет одну вертикальную колонку:

Interneting is hard HTML+CSS
Скриншот 20: веб-страница с сеткой, превращенная в вертикальный столбец ячеек

Ключевым условием адаптивного дизайна является одна HTML-разметка как для мобильных, так и ноутбуков/ПК. Небольшая проблема состоит в том, что большинство мобильных макетов имеют одну колонку, в то время как большинство макетов для ноутбуков/ПК располагают элементы горизонтально. Только представьте, насколько полезным станет flex-direction, когда мы начнем создавать адаптивные макеты.

АСПЕКТЫ ВЫРАВНИВАНИЯ
alignment considerations

Обратите внимание, что колонка прижимается к левой стороне своего flex-контейнера, несмотря на наше объявление justify-content: center;. Когда вы меняете направление контейнера, вы также меняете направление свойства justify-content. Теперь оно относится к вертикальному выравниванию контейнера, а не к горизонтальному.

Interneting is hard HTML+CSS
Скриншот 21: оси перевернуты, когда flex-direction равно column

Чтобы горизонтально выровнять колонку, нам нужно задать свойство align-items для нашей .photo-grid:

.photo-grid {
/* ... */
flex-direction: column;
align-items: center; /* Добавьте это */
}

порядок контейнеров
flex container order

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

Interneting is hard HTML+CSS
Скриншот 22: ряд (ROW - слева направо), обратный ряд (ROW-REVERSE - справа налево), столбец (COLUMN - сверху вниз), обратный столбец (COLUMN-REVERSE - снизу вверх)

Свойство flex-direction тоже позволяет контролировать порядок отображения элементов с помощью свойств row-reverse и column-reverse. Чтобы увидеть это в действии, преобразуем наш столбец обратно в сетку, но на этот раз мы изменим порядок отображения:

.photo-grid {
width: 900px;
display: flex;
justify-content: center;
flex-wrap: wrap;
flex-direction: row-reverse; /* <--- Реально офигенно круто! */
align-items: center;
}

Теперь оба ряда отображаются справа налево, а не слева направо. Но обратите внимание, что порядок меняется только для каждой строки: первый ряд начинается не с 5, а с 3. Это полезное поведение для многих распространенных паттернов дизайна (в частности, обратный порядок колонок открывает много возможностей для мобильных макетов). В следующем разделе вы научитесь еще большей детализации.

Interneting is hard HTML+CSS
Скриншот 23: веб-страница, на которой строки сетки отображаются в обратном порядке (3, 2, 1 в первом ряду и 5, 4 во втором)

Переупорядочивание элементов внутри таблицы стилей - это серьезное дело. До появления flexbox для этого приходилось прибегать к хакам JavaScript. Однако не стоит злоупотреблять своими новыми возможностями. Как уже говорилось в начале учебника, всегда следует отделять структуру от презентации. Изменение порядка является чисто визуальным - ваш HTML должен быть понятен и без применения этих стилей.

порядок элементов
flex item order

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

Interneting is hard HTML+CSS
Скриншот 24: настройка порядка отдельных flex элементов через свойство order

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

Это можно использовать, например, чтобы поменять местами порядок элементов .first-item и .last-item в нашей сетке. Мы также должны изменить значение row-reverse из предыдущего раздела обратно на row, потому что так будет немного легче распознать наши исправления:

.photo-grid {
/* ... */
flex-direction: row; /* Обновите это */
align-items: center;
}

.first-item {
order: 1;
}

.last-item {
order: -1;
}

В отличие от настроек row-reverse и column-reverse в flex контейнере, порядок действует вне границ рядов/колонок. Приведенный выше фрагмент поменяет местами первый и последний элементы, даже если они находятся в разных рядах.

выравнивание элементов
flex item alignment

То же самое мы можем сделать с вертикальным выравниванием. Что если мы хотим, чтобы ссылка "Подписаться" [Subscribe] и иконки соцсетей находились внизу заголовка, а не в центре? Выровняйте их по отдельности! Здесь на помощь приходит свойство align-self. Добавление этого свойства к элементу flex отменяет значение align-items из его контейнера:

.social
.subscribe {
align-self: flex-end;
margin-bottom: 20px;
}

Это должно отправить их в нижнюю часть .header. Обратите внимание, что и margin и padding действуют так, как от них ожидается.

Interneting is hard HTML+CSS
Скриншот 25: веб-страница, показывающая иконки, с помощью свойства align-self выровненные по нижнему краю [bottom-aligned]

Элементы можно выравнивать и другими способами, используя те же значения, что и свойство align-items, перечисленные ниже для удобства.

гибкие элементы
flexible items

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

Свойство flex определяет ширину отдельных элементов в flex контейнере. Точнее, оно позволяет им иметь гибкую ширину. Оно работает как некий коэффициент веса [weight], указывающий flex контейнеру, как распределить дополнительное пространство между элементами. Например, элемент со значением flex, равным 2, будет увеличиваться в два раза быстрее, чем элементы с стандартным значением, равным 1.

Interneting is hard HTML+CSS
Скриншот 26: отсутствие flex (3 квадратных блока), равный flex (3 прямоугольных блока), неравный flex (2 меньших блока, один вытянутый)

Для дальнейших экспериментов нам нужен футер. Вставьте его после элемента .photo-grid-container:

<div class='footer'>
<div class='footer-item footer-one'></div>
<div class='footer-item footer-two'></div>
<div class='footer-item footer-three'></div>
</div>

Затем, немного CSS:

.footer {
display: flex;
justify-content: space-between;
}

.footer-item {
border: 1px solid #fff;
background-color: #D6E9FE;
height: 200px;
flex: 1;
}

Этот flex: 1; велит элементам растягиваться в соответствии с шириной .footer. Поскольку все они имеют одинаковый вес [weight], они будут растягиваться одинаково:

Interneting is hard HTML+CSS
Скриншот 27: три одинаковых голубых блока, растянутые по всей ширине футера

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

.footer-three {
flex: 2;
}

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

ЭЛЕМЕНТЫ ФИКСИРОВАННОЙ ШИРИНЫ
static item widths

Мы даже можем сочетать гибкие блоки с блоками фиксированной ширины. В flex: initial происходит возврат к конкретному свойству ширины элемента. Это позволяет нам по-разному комбинировать статические и гибкие блоки.

Interneting is hard HTML+CSS
Скриншот 28: блок фиксированной ширины (flex: initial), гибкий блок (flex: 1)

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

.footer-one
.footer-three {
background-color: #5995DA;
flex: initial;
width: 300px;
}

Без этого flex: initial; объявление flex: 1; было бы унаследовано от правила .footer-item, в результате чего свойства ширины игнорировались бы. initial исправляет это, и мы получаем гибкий макет, который также содержит элементы фиксированной ширины. Измененяя размер окна браузера, мы увидим, что в футере изменяется только размер среднего блока.

Interneting is hard HTML+CSS
Скриншот 29: два блока фиксированной ширины по обе стороны от гибкого блока. Все три полностью заполняют весь футер.

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

элементы и отступы
flex items and auto-margins

Auto отступы [auto-margins] в flexbox - это нечто особенное. Они могут использоваться как альтернатива дополнительному <div> при попытке выровнять группу элементов по левому/правому краю контейнера. Воспринимайте auto-margin как "разделитель" для flex элементов в одном контейнере.

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

<div class='menu-container'>
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='signup'>Sign Up</div>
<div class='login'>Login</div>
</div>
</div>

При перезагрузке страницы пункты должны равномерно распределиться по нашему меню, как в начале главы. Мы можем воспроизвести желаемый макет, вставив auto-margin между пунктами, которые мы хотим отделить, как показано ниже:

.signup {
margin-left: auto;
}

auto-margin съедает все лишнее пространство в flex-контейнере, поэтому вместо равномерного распределения элементов, мы перемещаем .signup и все следующие элементы (.login) в правую часть контейнера. Получится точно такой же макет, как и раньше, но без лишнего вложенного <div> для группировки. Иногда приятнее оставить HTML более простым.

резюме

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

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

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

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

СЛЕДУЮЩИЙ УРОК >