Статьи

Создание гибких макетов с помощью Flexbox

Следующее введение в 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 будет иметь ту же высоту, что и его самый высокий элемент (как определяется содержимым). Он также будет складываться горизонтально (или вертикально, когда документ имеет режим вертикальной записи) без переноса и без пробелов между краями каждого блока. Гибкие элементы могут переполнить контейнер.

Список с отображением: flex применяется к элементу, содержащему ul Список с 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 увеличивается, чтобы заполнить оставшееся пространство.

Эффект сгибания: 0 0 150px Эффект 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 Распределение гибких предметов с помощью 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 используется для вашего меню навигации или поля поиска, а плавающие для размещения таблиц или изображений.