Типичные варианты использования Flexbox
В этом руководстве мы рассмотрим некоторые распространённые варианты использования Flexbox — те случаи, где Flexbox более уместен, чем другой метод макета.
Почему стоит выбрать Flexbox?
Flexbox, как правило, является правильным решением для макета CSS, когда требуется выложить набор элементов в одном измерении или управлять интервалами между ними. В этом руководстве мы рассмотрим некоторые типичные варианты использования Flexbox.
Навигация
Распространённый шаблон для навигации — это список элементов, отображаемых в виде горизонтальной полосы. Это, пожалуй, самый распространённый пример использования Flexbox, и его можно считать идеальным случаем для Flexbox.
Когда у нас есть набор элементов, которые мы хотим отобразить горизонтально, может возникнуть дополнительное пространство. Нам нужно решить, что с ним делать, и у нас есть несколько вариантов. Либо мы отображаем это пространство вне элементов — тем самым разделяя их пробелами между ними — или поглощаем дополнительное пространство внутри элементов и, следовательно, нам нужен метод, позволяющий элементам расти и занимать это пространство.
Распределение пространства за пределами элементов
Для распределения пространства между элементами мы используем свойства выравнивания в Flexbox и свойство justify-content. Подробнее об этом свойстве вы можете прочитать в разделе Выравнивание элементов в контейнере Flex, в котором рассматривается выравнивание элементов по основной оси.
В этом примере мы отображаем элементы в их естественном размере и используем justify-content: space-between для равномерного распределения пространства между элементами. Вы можете изменить способ распределения пространства, используя значения space-around или space-evenly. Вы также можете использовать start для размещения пространства в конце элементов, end для размещения перед ними или center для центрирования элементов навигации.
<nav>
<ul>
<li><a href="#">Page 1</a></li>
<li><a href="#">Page 2</a></li>
<li><a href="#">Page 3 is longer</a></li>
<li><a href="#">Page 4</a></li>
</ul>
</nav>
nav {
border: 2px solid #eeeeee;
}
nav a {
text-decoration: none;
color: #000;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
display: block;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: space-between;
}
Распределение пространства внутри элементов
Другим шаблоном для навигации будет распределение доступного пространства внутри самих элементов, а не создание пространства между ними. Свойства flex позволяют элементам увеличиваться и уменьшаться пропорционально друг другу, как описано в Управление пропорциями элементов Flex по основной оси.
Если вы хотите учитывать размер элементов навигации, но при этом распределить доступное пространство равномерно между ними, вы можете использовать flex: auto, что является сокращённой записью flex: 1 1 auto — все элементы увеличиваются и уменьшаются от flex-basis auto. Это означает, что более длинный элемент получит больше места, так как он начинался с большего размера, даже если ему присвоено такое же количество доступного пространства, как и другим.
В примере ниже попробуйте изменить flex: auto на flex: 1. Эта сокращённая запись для flex: 1 1 0 приводит к тому, что все элементы становятся одинаковой ширины, так как они исходят из flex-basis flex-basis 0, что позволяет равномерно распределить всё пространство.
<nav>
<ul>
<li><a href="#">Page 1</a></li>
<li><a href="#">Page 2</a></li>
<li><a href="#">Page 3 is longer</a></li>
<li><a href="#">Page 4</a></li>
</ul>
</nav>
nav {
border: 2px solid #eeeeee;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
nav a {
text-decoration: none;
color: #000;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
display: block;
}
nav li {
flex: auto;
}
Разделение навигации
Другой способ выравнивания элементов по основной оси — использование автоматических отступов. Это позволяет использовать шаблон навигационной панели, где одна группа элементов выравнивается слева, а другая — справа. Здесь мы используем технику автоматических отступов, описанную в Использование автоматических отступов для выравнивания по основной оси.
Элементы выравниваются по основной оси с помощью normal, что эквивалентно start, поскольку это начальное поведение Flexbox. Свойство gap создаёт интервалы между элементами. И мы выравниваем последний элемент справа, присвоив ему значение margin-left auto. Вы можете переместить класс с одного элемента на другой, чтобы изменить место разделения.
<nav>
<ul>
<li><a href="#">Page 1</a></li>
<li><a href="#">Page 2</a></li>
<li><a href="#">Page 3 is longer</a></li>
<li class="push-right"><a href="#">Page 4</a></li>
</ul>
</nav>
nav {
border: 2px solid #eeeeee;
}
nav a {
text-decoration: none;
color: #000;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
display: block;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: 20px;
}
.push-right {
margin-left: auto;
}
Центрирование элемента
Длительное время среди разработчиков ходит шутка, что самой сложной проблемой в веб-дизайне является вертикальное центрирование. Вертикальное центрирование содержимого очень просто реализовать с помощью свойств выравнивания Flexbox, как показывает следующий пример.
Нажмите «Запустить» и попробуйте изменить выравнивание, например, выровнять элемент в начале с помощью start или в конце с помощью end.
<div class="box"> <div></div> </div>
.box {
height: 300px;
border: 2px dotted rgb(96 139 168);
display: flex;
align-items: center;
justify-content: center;
}
.box div {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
width: 100px;
height: 100px;
}
С помощью свойств выравнивания CSS-блоков можно центрировать элемент внутри другого без Flexbox. В примере выше попробуйте удалить свойства Flex из блока и добавить align-content: center. Затем добавьте margin: auto к элементу, который вы хотите центрировать по горизонтали.
Макет карточек с нижним подвалом
Используете ли вы Flexbox или сетку для макета списка карточек, эти методы макета работают только с непосредственными дочерними элементами Flex или Grid. Это означает, что при наличии переменного количества содержимого карточка будет растягиваться до высоты области сетки или контейнера Flex. Любое содержимое внутри использует обычный макет блоков, что означает, что на карточке с меньшим содержимым подвал будет подниматься до нижней части содержимого, а не прилипать к низу карточки.
Flexbox решает эту проблему. Мы делаем карточку контейнером Flex с flex-direction: column. Затем мы устанавливаем для области содержимого flex: 1, что является сокращённой записью flex: 1 1 0 — элемент может увеличиваться и уменьшаться от базового значения 0. Поскольку это единственный элемент, который может увеличиваться, он занимает всё доступное пространство в контейнере Flex и опускает подвал вниз. Если вы удалите свойство flex из примера, вы увидите, как подвал перемещается вверх, чтобы расположиться непосредственно под содержимым.
<div class="cards">
<div class="card">
<div class="content">
<p>This card doesn't have much content.</p>
</div>
<footer>Card footer</footer>
</div>
<div class="card">
<div class="content">
<p>
This card has a lot more content which means that it defines the height
of the container the cards are in. I've laid the cards out using grid
layout, so the cards themselves will stretch to the same height.
</p>
</div>
<footer>Card footer</footer>
</div>
</div>
body {
font-family: sans-serif;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 10px;
}
.card {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
display: flex;
flex-direction: column;
}
.card .content {
padding: 10px;
flex: 1 1 auto;
}
.card footer {
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
}
Средства отображения медиа
Объект медиа — изображение или другой элемент медиа с некоторым описательным текстом рядом — распространённый шаблон в веб-дизайне. Объекты медиа должны быть способны к переворачиванию — перемещению изображения с одной стороны на другую.
Этот шаблон используется для комментариев и других мест, где изображения размещаются рядом с их описаниями. Мы можем использовать гибкую компоновку, чтобы позволить части объекта медиа, содержащей изображение, принимать свои размеры из изображения, а контент объекта медиа будет расширяться, занимая оставшееся пространство.
В этом примере объект медиа выровнен по flex-start и .content установлен для роста, причём коэффициент роста установлен на 1. Эти свойства такие же, как и те, которые используются для нашего шаблона карточек компоновки колонок выше.
<div class="media">
<div class="image">
<img
alt="A colorful balloon against a blue sky"
src="https://mdn.github.io/shared-assets/images/examples/balloon.jpg" />
</div>
<div class="content">
This is the content of my media object. Items directly inside the flex
container will be aligned to flex-start.
</div>
</div>
img {
max-width: 100%;
display: block;
}
.media {
border: 2px dotted rgb(96 139 168);
display: flex;
align-items: flex-start;
}
.media .content {
flex: 1;
padding: 10px;
}
Некоторые вещи, которые вы можете попробовать в этом интерактивном примере, связаны с различными способами ограничения объекта медиа в вашем дизайне.
Чтобы предотвратить чрезмерное увеличение изображения, вы должны добавить max-width к изображению. Поскольку эта сторона объекта медиа использует начальные значения гибкой компоновки, она может уменьшаться, но не увеличиваться, и использует значение flex-basis auto. Любой width или max-width применённый к изображению, станет flex-basis.
.image img {
max-width: 100px;
}
Вы также можете позволить обеим сторонам расти и уменьшаться пропорционально. Если вы установите обе стороны на flex: 1, они будут расти и уменьшаться от flex-basis 0, так что вы получите две колонки одинакового размера. Вы можете либо использовать контент как руководство и установить обе на flex: auto, в этом случае они будут расти и уменьшаться в размерах контента или любого размера, применённого непосредственно к элементам гибкой компоновки, например, width к изображению.
.media .content {
flex: 1;
padding: 10px;
}
.image {
flex: 1;
}
Вы также можете присвоить каждой стороне разные коэффициенты flex-grow, например, установить значение стороны с изображением на flex: 1 и сторону с текстом на flex: 3. Это означает, что они используют значение flex-basis 0, но распределяют это пространство с разными скоростями в соответствии с коэффициентом flex-grow , который вы присвоили. Свойства гибкой компоновки, которые мы используем для этого, подробно описаны в руководстве Управление пропорциями элементов гибкой компоновки вдоль основной оси.
.media .content {
flex: 3;
padding: 10px;
}
.image {
flex: 1;
}
Переворачивание объекта медиа
Чтобы переключить отображение объекта медиа и расположить изображение справа, а контент слева, мы устанавливаем свойство flex-direction на row-reverse.
В этом примере мы добавили класс flipped рядом с классом media. Удалите класс из HTML, чтобы увидеть, как изменяется отображение.
<div class="media flipped">
<div class="image">
<img
alt="A colorful balloon against a blue sky"
src="https://mdn.github.io/shared-assets/images/examples/balloon.jpg" />
</div>
<div class="content">
This is the content of my media object. Items directly inside the flex
container will be aligned to flex-start.
</div>
</div>
img {
max-width: 100%;
display: block;
}
.media {
border: 2px dotted rgb(96 139 168);
display: flex;
align-items: flex-start;
}
.flipped {
flex-direction: row-reverse;
}
.media .content {
flex: 1;
padding: 10px;
}
Элементы управления формами
Гибкая компоновка особенно полезна при стилизации элементов управления формами. Формы имеют несколько мелких элементов, которые мы обычно хотим выровнять друг с другом. Распространённый шаблон — это пара <label> и <input>, объединённая с <button>, возможно, для поисковой формы или формы подписки на новостную рассылку, где вы хотите, чтобы посетитель ввёл свой адрес электронной почты.
Гибкая компоновка упрощает реализацию такого рода макета. <label>, <input> и <button> находятся в контейнере, установленном на display: flex. Свойства гибкой компоновки позволяют полю <input> увеличиваться, в то время как кнопка и метка не растут. Поле ввода текста будет увеличиваться и уменьшаться в зависимости от доступного пространства.
<form class="example">
<div class="wrapper">
<label for="text">Label</label>
<input id="text" type="text" />
<input type="submit" value="Send" />
</div>
</form>
* {
font: 1.1em sans-serif;
}
.wrapper {
display: flex;
border: 1px solid rgb(96 139 168);
}
.wrapper > * {
padding: 10px;
border: none;
color: #fff;
}
.wrapper > input[type="text"] {
background-color: rgb(96 139 168 / 0.5);
border-right: 1px solid rgb(96 139 168);
flex: 1 1 auto;
}
.wrapper input[type="submit"] {
background-color: rgb(96 139 168);
color: #fff;
}
.wrapper label {
background-color: #666;
}
Такие шаблоны могут значительно упростить создание библиотеки элементов форм для вашего дизайна, которая легко адаптируется к добавлению дополнительных элементов. Вы используете гибкость гибкой компоновки, комбинируя элементы, которые не растут, с теми, которые растут.
Заключение
Изучая вышеперечисленные шаблоны, вы, надеюсь, начали понимать, как можно продумать наилучший способ использования гибкой компоновки для достижения желаемого результата. Часто у вас есть несколько вариантов. Объединяйте элементы, которые не могут растягиваться, с элементами, которые могут, используйте содержимое для определения размера или позвольте гибкой компоновке распределять пространство пропорционально. Решение за вами.
Подумайте о наилучшем способе отображения вашего содержимого, а затем посмотрите, как гибкая компоновка или другие методы компоновки могут вам в этом помочь.
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Typical_use_cases_of_flexbox