Следующее введение в Flexbox — это отрывок из новой книги Тиффани, CSS Master, 2nd Edition .
До появления CSS Grid существовал Flexbox (официально известный как модуль CSS Flexible Box Layout ). Flexbox был разработан для управления макетом в одном направлении — строка ( flex-direction: row
или row-reverse
) или столбец ( flex-direction: column
column-reverse
flex-direction: column
или column-reverse
). Это в отличие от сетки, которая учитывает строки и столбцы.
Базовая гибкая компоновка коробки проста в создании: добавьте display: flex
или display: inline-flex
к содержащему элементу. Эти значения для display
вызовут контекст гибкого форматирования для того, который содержит дочерние элементы. Как и в случае с Grid, как flex
и inline-flex
находятся в режимах отображения. Мы устанавливаем эти значения для контейнера, который ведет себя как блок уровня блока или встроенного уровня соответственно. Затем дочерние элементы этого контейнера располагаются в соответствии с правилами гибкого размещения.
Примечание. В старых версиях браузеров на основе Blink, таких как Chrome (≤ 28), и браузеров на основе WebKit, таких как Safari (≤ 8), требуется префикс поставщика. Если ваш проект все еще поддерживает эти браузеры, вам необходимо использовать display: -webkit-flex
или display: -webkit-inline-flex
. Более старые версии Firefox (≤ 21) также требуют префикса. Используйте -moz-flex
и -moz-inline-flex
для поддержки этих браузеров.
Добавляя display: flex
или display: inline-flex
к содержащему элементу, его непосредственные дочерние элементы становятся элементами flex, как показано на рисунке ниже. Элементы Flex могут быть дочерними элементами или непустыми текстовыми узлами. Например, приведенная ниже разметка создает три блока Flex-элемента, каждый из которых ведет себя в соответствии с правилами Flex-макета:
<div style="display: flex"> <span>This text is contained by a SPAN element.</span> <b>This text is contained by a B element.</b> This text node is still a flex item. </div>
Если никакие другие свойства не установлены, каждый элемент flex будет иметь ту же высоту, что и его самый высокий элемент (как определяется содержимым). Он также будет складываться горизонтально (или вертикально, когда документ имеет режим вертикальной записи) без переноса и без пробелов между краями каждого блока. Гибкие элементы могут переполнить контейнер.
display: flex
применяется к элементу, содержащему ul
Это может показаться не таким уж большим делом, но оно упрощает код, необходимый для ряда шаблонов пользовательского интерфейса. Давайте посмотрим на пару примеров.
Новый компонент медиа-объекта
Возьмите следующий код медиа-объекта:
<div class="media__object"> <img src="video-thumb1.jpg"> <div class="media__object__text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div> </div>
До Flexbox мы могли бы связать предыдущую разметку со следующим CSS:
.media__object img { float: left; height: auto; width: 150px; } .media__object__text { padding-left: 170px; } /* Let's use the clearfix hack! */ .media__object::after{ content: ' '; display: block; clear: both; }
Этот макет работает, но у него есть один существенный недостаток: он требует от нас ограничения ширины наших изображений, чтобы мы знали, какой отступ использовать. Это ограничивает нашу способность использовать один и тот же компонент в нескольких контекстах. Возможно, вам понадобится изображение шириной 150 пикселей, когда этот компонент используется для виджета «Похожие истории», а для комментариев — всего 75 пикселей.
Давайте попробуем это с помощью Flexbox. Вот наш обновленный CSS:
.media__object { display: flex; } .media_object img { margin-right: 20px; }
Это намного меньше CSS. Дополнительным бонусом является то, что нам не нужно беспокоиться о том, насколько широким или высоким будет наше изображение. Мы также не должны заниматься очисткой поплавков. Независимо от того, является ли изображение шириной .media__object__text
или шириной 20 .media__object__text
, .media__object__text
упирается в поле поля нашего элемента img
.
Создание гибких компонентов формы с помощью flex
Еще один вариант использования Flexbox — создание гибких вертикально выровненных компонентов формы. Рассмотрим шаблон интерфейса, показанный на рисунке ниже.
Здесь у нас есть элемент управления вводом формы и смежная кнопка. Оба выровнены по вертикали, а наша кнопка имеет ширину 150 пикселей.
Что если мы хотим, чтобы наш элемент input
расширялся, чтобы заполнить доступное пространство в его контейнере? Без Flexbox нам потребовалось бы немного JavaScript и ручной разметки, чтобы обновить ширину input
в ответ на изменения ширины его родителя. Однако с Flexbox мы можем просто использовать flex
.
Свойство flex
самом деле является сокращением для трех других свойств.
-
flex-grow
указывает, что элемент должен расти при необходимости и должен быть положительным целым числом. Его начальное значение0
. -
flex-shrink
указывает, что элемент должен сжиматься при необходимости и должен быть положительным целым числом. Его начальное значение равно1
. -
flex-basis:
указывает начальную или минимальную ширину (когда ось flex горизонтальна) или высоту элемента (если она вертикальная). Это может быть длина или процент илиauto
, и его начальное значение —auto
.
Хотя можно установить каждый из них по отдельности, в спецификации настоятельно рекомендуется использовать сокращенное обозначение flex
. Вот пример:
div { display: flex; } input[type="text"], button { border: 0; font: inherit; } input[type="text"] { flex: 1 0 auto; } button { background: #003; color: whitesmoke; display: block; text-align: center; flex: 0 0 150px; }
Здесь мы использовали flex: 1 0 auto
для нашего элемента input
. Поскольку его значение flex-grow
равно 1
, оно будет увеличиваться, чтобы заполнить доступное пространство своего родителя. Однако для элемента button
мы использовали flex: 0 0 150px
. Значения 0
для flex-grow
и flex-shrink
предотвращают увеличение или уменьшение ширины кнопки, в то время как значение flex-basis
150px
устанавливает ее ширину.
Как вы можете видеть на изображении ниже, наша кнопка остается того же размера, но ширина input
увеличивается, чтобы заполнить оставшееся пространство.
flex: 0 0 150px
Хитрость в значениях flex-grow
и flex-shrink
заключается в том, что они пропорциональны. Да, flex: 1 0 auto
означает, что наш элемент input
будет шире, чем наша кнопка. Но изменение значения свойства flex: 1 0 auto
нашей кнопки на flex: 1 0 auto
не обязательно означает, что оба элемента будут иметь одинаковый размер, как показано на следующем рисунке.
Вместо этого размеры изгибаемых элементов будут изменены, чтобы заполнить контейнер, принимая во внимание их используемые значения min-width
и max-width
(которые могут быть их начальными значениями).
К сожалению, мы не можем использовать модули fr
со свойствами flex
или flex-basis
based. Вместо этого используйте значения длины или процента.
Вертикальное центрирование с Flexbox
Наконец, давайте посмотрим, как центрировать содержимое по вертикали с помощью Flexbox. Вертикальное центрирование элементов является одной из наиболее сложных задач, которые можно решить с помощью CSS, особенно если высота вашего контента неизвестна. Но с Flexbox нам требуется всего одна дополнительная строка CSS — align-items: center
:
.flex-container { display: flex; align-items: center; }
Теперь наши flex-элементы и их содержимое вертикально центрированы внутри flex-контейнера, как показано на рисунке ниже.
align-items: center
Создание Grid-подобных макетов с помощью Flexbox
В большинстве случаев вы захотите использовать Grid для создания сеточных макетов. Тем не менее, вы можете захотеть коробки, которые выровнены, когда есть четное количество элементов, но расширить, чтобы заполнить доступное пространство, когда есть нечетное число.
Вот разметка, которую мы будем использовать:
<ul class="flex-aligned"> <li>A</li> <li>B</li> <li>C</li> <li>D</li> <li>E</li> <li>F</li> <li>G</li> </li>
По умолчанию гибкие элементы не переносятся. Чтобы получить макет выше, нам нужно будет обернуть их, используя свойство flex-wrap
. Он принимает три значения: nowrap
(начальное значение), wrap
и wrap-reverse
. Мы будем использовать wrap
здесь:
.flex-aligned { display: flex; flex-wrap: wrap; }
Теперь нам просто нужно указать, как должны вести себя наши гибкие элементы и какова их максимальная ширина. Поскольку нам нужно максимум четыре столбца, мы установим наше значение flex-basis
based на 25%
. И поскольку мы хотим, чтобы наши flex-элементы расширялись, чтобы заполнить доступное пространство, мы установим flex-grow
на 1. Мы будем держать flex-shrink
на 0, чтобы наши блоки никогда не занимали менее 25% их контейнера:
.flex-aligned li { flex: 1 0 25%; }
Узнать больше о Flexbox
Flexbox — это намного больше, чем мы рассмотрели здесь. « Полное руководство по Flexbox » от CSS-Tricks рассматривает все свойства и значения. Вы также можете ознакомиться с « Решением Flexbox » Филиппа Уолтона, в котором демонстрируются шаблоны пользовательского интерфейса, упрощающие работу с Flexbox.
Выбор flex
или grid
Разрабатывая макеты страниц или компонентов, вы можете задаться вопросом, когда лучше использовать Flexbox, а когда использовать Grid.
- Используйте Grid, если вы хотите расположить элементы в строки и столбцы, которые выровнены как по горизонтали, так и по вертикали.
- Используйте Flexbox, когда вы хотите расположить элементы в строке или столбце, когда вы хотите выровнять элементы по вертикали или по горизонтали, но не одновременно.
Видео Джен Симмонс « Flexbox vs. CSS Grid — что лучше? ”Проведет вас через некоторые вещи, которые следует учитывать при выборе между Grid и Flexbox. Рейчел Эндрю: « Должен ли я использовать Grid или Flexbox? Это еще один отличный ресурс для понимания того и другого.
На практике ваши проекты, вероятно, будут сочетать оба этих метода, а также плавающие. Например, вы можете использовать Grid для определения общего макета страницы, в то время как Flexbox используется для вашего меню навигации или поля поиска, а плавающие для размещения таблиц или изображений.