CSS Flexible Box Layout
Способ CSS раскладки Flexible Box (CSS Flexible Box Layout или Flexbox) — это способ CSS раскладки, означающий блочную модель CSS, оптимизированную для построения пользовательских интерфейсов. Во флекс-модели потомки флекс-контейнера могут выстраиваться в любом направлении (право/лево, верх/низ), растягиваться, заполняя свободное пространство, или сжиматься во избежание переполнения родительского контейнера. Доступно различное выравнивание потомков по горизонтали и вертикали. Комбинация из родительского и вложенных блоков позволяют создавать такой layout, при котором элементы автоматически выстраиваются в столбы или строки.
Базовый пример
В следующем примере контейнер объявлен как display: flex , таким образом его три потомка становятся флекс-элементами. Свойству justify-content присвоено значение space-between для того, чтобы, во-первых, задать между элементами равные интервалы по основной оси, и, во-вторых, «примагнитить» первый и последний элементы к левому и правому краям контейнера соответственно. Также можно заметить, что флекс-элементы растянуты перпендикулярно оси; это происходит из-за того, что дефолтным значением align-items является stretch . Так как высота родительского контейнера не задана, элементы растягиваются по высоте и принимают значение высоты самого высокого из них.
Reference
CSS Properties
Guides
Step-by-step tutorial about how to build layouts using this feature.
Tutorial explaining how to use flexbox in the specific context of Web applications.
Спецификации
Found a content problem with this page?
This page was last modified on 26 мая 2023 г. by MDN contributors.
Your blueprint for a better internet.
Примеры использования Flexbox
Мы подошли к заключительной части моей серии о Flexbox здесь, в Smashing Magazine. В этом посте я собираюсь потратить некоторое время на размышления о том, каковы на самом деле варианты использования Flexbox, учитывая, что теперь у нас есть CSS Grid Layout, дам некоторые предложения о том, что вы можете использовать, когда и как.
Ранее в этой серии
Если вы еще не выбрали другие статьи, это, по сути, заключительный пост, поэтому сначала посмотрите их. Я начала с описания того, что происходит при создании контейнера flex. Во второй статье серии я взглянула на выравнивание и на то, как мы выравниваем элементы по главной и поперечной осям во flexbox. В третьей статье я распаковываю, как работает изменение размера в Flexbox, и как браузер определяет, насколько большим должен быть flex-элемент. Теперь, когда мы точно знаем, как работает Flexbox, мы можем обернуться, чтобы подумать о примерах использования, для которых это лучше всего.
Я должна использовать Grid или Flexbox?
Это по-прежнему главный вопрос, который мне задают при обучении компоновке, и в целом я считаю, что по мере того, как люди все больше привыкают к работе с новыми методами, это становится вопросом, который вам нужно задавать себе реже. По мере роста опыта вы будете понимать, какой метод компоновки использовать.
Однако, если вы только начинаете ухватывать эту мысль, следует помнить, что CSS Grid Layout и Flexbox оба являются CSS. Если вы указали display: grid или display: flex , вы часто используете больше общего, чем различий. И Grid, и Flexbox используют свойства, которые являются частью спецификации Box Alignment; оба опираются на концепции, детализированные в спецификации CSS Intrinsic and Extrinsic Sizing..
Спрашивать, должен ли ваш дизайн использовать Grid или Flexbox подобно вопросу должен ли ваш дизайн использовать размер шрифта или цвет. Вероятно, вы должны использовать оба, если требуется. И никто не будет преследовать вас, если вы воспользуетесь не тем.
Итак, мы не выбираем между Vue.js и React, Bootstrap или Foundation. Мы используем CSS, чтобы выполнить компоновку, и нам нужно использовать частицы CSS, которые имеют наибольший смысл для конкретной части нашего дизайна, над которым мы работаем. Рассмотрите каждый компонент и решите, что лучше для него, или какая комбинация элементов лучше для него.
Это может быть Grid, или это может быть Flexbox. Это может быть внешний контейнер Grid, в котором некоторые элементы сетки становятся гибкими или реверсивными. Нет проблем с вложением сетки в элемент flex, если это требуется для вашего проекта.
Что такое Flexbox на самом деле?
Спецификация Flexbox описывает метод компоновки так:
«Flex layout внешне похож на block layout. В нем отсутствуют многие более сложные текстовые или документо-ориентированные свойства, которые можно использовать в компоновке блоков, такие как floats и columns. Взамен он получил простые и мощные инструменты для распределения пространства и выравнивания контента способом, в котором давно нуждались веб-приложения и сложные веб-страницы.”
Я думаю, что ключевая фраза здесь “распределение пространства и выравнивание контента”. Flexbox — это все о том, чтобы взять кучу элементов (которые имеют разные размеры) и поместить их в контейнер (который сам может быть переменного размера). Flexbox — это мягкость. Он пытается создать наилучший макет для наших элементов, давая большим элементам больше пространства, а меньшим элементам меньше пространства, тем самым сохраняя читаемость контента.
Если люди находят Flexbox сложным и загадочным, это часто потому, что они пытаются использовать Flexbox как grid-систему, пытаясь вернуть контроль над размером и распределением пространства. Когда вы это делаете, Flexbox может показаться странным и сложным, поскольку вы боретесь с тем, что и делает его Flexbox‘ом, т.е. с присущей ему гибкостью.
Поэтому шаблоны, которые очень хорошо подходят для гибкой компоновки, это те, в которых нас не так интересует наличие идеального размера каждого элемента. Мы просто хотим, чтобы эти элементы отображались рядом друг с другом.
Существуют также шаблоны, в которых вы хотите иметь строки с переносом, однако вам не нужна строгая сетка. Если мы возьмем оригинальный пример Grid против Flexbox, где мы используем в сетке синтаксис repeat auto-fill, а затем flex-контейнер с переносом строк, то сразу увидим разницу между этими двумя методами.
В примере Grid элементы сетки выстраиваются в строки и столбцы. Когда число столбцов трека изменяется (в зависимости от пространства), элементы всегда переходят в следующую доступную ячейку сетки. На самом деле, нет никакого способа запросить элемент сетки окружить трек, чтобы заполнить по auto-flow сценарию, если есть другие пустые ячейки.
В примере flex итоговые элементы разделяют пространство, оставшееся между ними, таким образом, мы не используем выравнивание по горизонтали и вертикали.
Если у нас flex-basis установлен в auto, и любой из flex-элементов увеличивается, то остальным также будет предоставлено дополнительное пространство, чтобы выравнивание могло быть различным от строки к строке.
Это очень яркий пример того, где мы хотели бы использовать Flexbox над Grid Layout. Если мы хотим, чтобы элементы были обернуты, но занимали пространство, в котором они нуждались, по строкам. Это очень отличается от сетки. Шаблоны, подобные этому, могут представлять собой набор тегов (один или два слова, которые вы хотите хорошо отображать в виде набора элементов), занимающих необходимое пространство, а не жестко вставленных в строгую сетку.
В настоящее время Flexbox также является лучшим способом выполнения вертикального и горизонтального центрирования элемента внутри контейнера.
В будущем (если будет поддержка браузерами свойств Box Alignment вне гибкого макета), мы можем сделать это, не добавляя display: flex в контейнер. На данный момент, однако, все, что вам нужно сделать, это дополнительная строка CSS, что не является проблемой.
Flexbox очень хорошо справляется с небольшими одномерными компонентами. Наборы полей формы, иконок или другой информации можно легко расположить и позволить им быть гибкими без необходимости тщательно устанавливать размеры каждого элемента.
Вы также можете выбрать Flexbox в сценарии, где контент нужно привести к низу контейнера, не давая ему всплывать. В примере, расположенном ниже, я делаю контейнер flex-контейнером, отображая содержимое в виде столбца, а затем позволяю середине расти, выталкивая footer вниз компонента.
При разработке я нахожу, что Flexbox полезен для множества небольших заданий, выполняя правильно выравнивание, распределяя пространство между элементами. Вы безусловно можете использовать одномерный контейнер сетки для некоторых из этих задач, и не беспокоится о том, что вы решили сделать.
Однако я думаю, что Flexbox будет лучшим в ситуации, когда потребуется добавлять дополнительные элементы, которые я не ожидала в своем дизайне. Например, если у меня есть компонент навигации, использующий Grid, я бы создала достаточно треков для всех элементов, так как я не хотела бы, чтобы создавалась новая строка, если бы у меня было “слишком много” элементов. С flexbox, достаточно длинным, я бы разрешил элементам быть гибкими с flex-basis 0 (или auto), тогда бы элементы сами пускали нового компаньона в строку, освобождая ему место.
Когда не следует использовать Flexbox?
Мы рассмотрели некоторые соображения, по которым, я думаю, вы должны предпочесть Flexbox перед Grid компоновкой, поэтому теперь мы можем осмотреть некоторые из мест, где Flexbox может быть не лучшим выбором. Мы уже рассматривали наш пример Flexbox против сетки с элементами, выровненными по горизонтали и вертикали против элементов, которые занимают пространство построчно. И это различие — первое, что нужно учитывать.
Пример сетки имеет двумерную компоновку. Компоновка по строкам и столбцам одновременно.
Пример Flexbox это одномерная компоновка. Мы упаковали flex-строки, но размещение в пространстве происходит построчно. Каждая строка, по сути, выступает в качестве нового flex-контейнера во Flex-направлении.
Поэтому, если ваш компонент нуждается в двумерной компоновке, вам будет лучше использовать Grid, а не Flexbox. Не имеет значения, большой или маленький компонент. Если вы возьмете одну вещь из этой статьи, то это удалите идею из вашей головы, что Grid почему-то предназначена только для макета главной страницы, а Flexbox для компонентов. Вы можете иметь крошечный компонент, который требует двумерного макета, и структуру главной страницы, которой лучше подходит одномерный макет.
Еще одно хорошее место, где Grid может считаться лучшим решением, это применение ширины или установка flex-basis в качестве единицы длины ваших flex-элементов, чтобы выровнять их с другой строкой flex-элементов или просто ограничить гибкость в некотором роде. Довольно часто это указывает либо на то, что вам действительно нужен метод двумерного макета, либо на то, что элемент управления из grid-контейнера лучше подходит для вашего макета.
Например, мы могли бы сделать наш гибкий макет более похожим на Grid, ограничив гибкость наших элементов. Установка flex-grow в 0 и расчет размеров элементов в процентах, аналогично тому, как мы определяли размер элементов в плавающей «сетке». Если вы обнаружите, что делаете это, я бы предположила, что макет сетки — лучший подход, поскольку он предназначен для этого типа макетов.
При всем сказанном помните, что очень часто нет четкого правильного или неправильного ответа. Иногда единственное, что вы можете сделать, это попробовать разные способы и посмотреть, что лучше всего подходит для компонента. Помните, что вы также можете переключать методы макета, используя Flexbox в одной точке останова, а Grid в другой.
И так, сворачиваемся!
Я надеюсь, что эта серия по Flexbox была полезной и продемонстрировала как понимание некоторых алгоритмов выравнивания и калибровки flex-элементов облегчает жизнь при работе с ними.
Если у вас остались какие-либо нерешенные вопросы или у вас есть шаблон, который, похоже, не имеет очевидного ответа с точки зрения используемого метода компоновки, оставьте комментарий.