Spec-Zone.ru › CSS

Управление пропорциями элементов flex по главной оси

В этом руководстве мы рассмотрим три свойства, которые управляют размером и гибкостью элементов flex по главной оси: flex-grow, flex-shrink и flex-basis. Полное понимание работы этих свойств с растущими и ужимающимися элементами является ключом к освоению CSS гибкой компоновки.

Первый взгляд

Наши три свойства контролируют следующие аспекты гибкости элемента flex:

  • flex-grow: Сколько положительного свободного места получит этот элемент?
  • flex-shrink: Сколько отрицательного свободного места можно удалить из этого элемента?
  • flex-basis: Каков размер элемента до начала роста и уменьшения?

Свойства обычно выражаются с помощью сокращенного свойства flex. Следующий код установит свойство flex-grow в значение 2, flex-shrink в 1 и flex-basis в auto.

.item {
  flex: 2 1 auto;
}

Важные понятия при работе с главной осью

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

Размеры элементов flex

Чтобы определить, сколько места доступно для вывода элементов flex, браузеру необходимо знать, каким будет начальный размер элемента. Как это рассчитывается для элементов, у которых не задана ширина или высота с использованием абсолютной единицы длины?

В CSS ключевые слова min-content и max-content могут использоваться вместо единицы <length>. В общем случае min-content — это наименьший размер, который может иметь элемент, при этом помещая самую длинную лексему, а max-content — размер, который нужен элементу для размещения всего содержимого без переноса на следующую строку.

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

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

<p class="min-content">
  I am sized with min-content and so I will take all of the soft-wrapping
  opportunities.
</p>
<p class="max-content">
  I am sized with max-content and so I will take none of the soft-wrapping
  opportunities.
</p>
.min-content {
  width: min-content;
  border: 2px dotted rgb(96 139 168);
}
.max-content {
  width: max-content;
  border: 2px dotted rgb(96 139 168);
}

Помните это поведение и влияние min-content и max-content, когда мы будем изучать flex-grow и flex-shrink позже в этой статье.

Положительное и отрицательное свободное место

Нам также необходимо понять понятие положительного и отрицательного свободного места. Когда у контейнера flex есть положительное свободное место, у него больше места, чем необходимо для отображения элементов flex внутри контейнера. Например, контейнер шириной 500px, с flex-direction, установленным на row, и содержащим три элемента flex шириной 100px, имеет 200px положительного свободного места. Это положительное свободное место может распределяться между элементами, если необходимо заполнить контейнер.

Image showing space left over after items have been displayed.

Контейнер flex имеет отрицательное свободное место, когда совокупное значение естественных размеров элементов flex больше, чем доступное пространство в контейнере flex. Если три элемента flex в примере контейнера шириной 500px имеют ширину 200px вместо 100px, их совокупная ширина составит 600px, что приведет к 100px отрицательного свободного места. Это пространство может быть удалено из элементов, чтобы они поместились в контейнер, иначе элементы будут выходить за пределы.

The items overflow the container

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

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

Свойство flex-basis

Свойство flex-basis определяет начальный размер элемента flex до распределения положительного или отрицательного свободного места. Начальное значение этого свойства — auto. Это свойство принимает те же значения, что и свойства width и height, а также ключевое слово content.

Если flex-basis установлено в значение auto, начальный размер элемента — это размер <length-percentage> по главной оси, если он был задан. Например, если для элемента задано свойство width: 200px, тогда 200px будет flex-basis для этого элемента. Процентные значения относительны к внутренней ширине контейнера flex по главной оси. Если width: 50% было установлено, то flex-basis для этого элемента составило бы половину ширины области содержимого контейнера. Если такой размер не задан, то есть размер элемента задан автоматически, то auto определяется размером его содержимого (см. обсуждение размеров min- и max-content выше), то есть flex-basis — это размер элемента max-content.

Этот пример содержит три неизменяемых элемента flex, для которых flex-grow и flex-shrink установлены в значение 0. Первый элемент, у которого задана явная ширина 150px, занимает flex-basis 150px, в то время как у других двух элементов ширина не задана, и поэтому их размер определяется шириной содержимого или max-content.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  flex: 0 0 auto;
}

.box {
  width: 500px;
  border: 2px dotted rgb(96 139 168);
  display: flex;
}

.box :first-child {
  width: 150px;
}

В дополнение к ключевому слову auto и любому другому допустимому значению width можно использовать ключевое слово content в качестве flex-basis. Это приводит к тому, что flex-basis основывается на размере содержимого, даже если для элемента задана width. Это создает тот же эффект, что и удаление любой заданной ширины и использование auto в качестве flex-basis. Хотя это похоже на установку max-content, значение content позволяет рассчитывать любое aspect-ratio на основе размера оси поперек.

Чтобы полностью игнорировать размер элемента flex во время распределения места, установите flex-basis в значение 0 и задайте ненулевое значение flex-grow. Давайте изучим flex-grow перед тем, как рассмотреть это значение в действии.

Свойство flex-grow

Свойство flex-grow определяет коэффициент роста flex, который определяет, насколько элемент flex увеличится относительно других элементов flex в контейнере flex при распределении положительного свободного места.

Если у всех элементов одинаковый коэффициент flex-grow, положительное свободное место будет распределено равномерно между ними. Для этого случая обычной практикой является установка flex-grow: 1, но вы можете задать любое значение, например 88, 100 или 1.2; это отношение. Если коэффициент одинаков для всех элементов flex в контейнере и имеется положительное свободное место, то это место будет распределено поровну.

END_OF_DOCUMENT_MARKER ```

Комбинирование flex-grow и flex-basis

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

.class {
  flex: 1 1 auto;
}

В этом случае значение flex-basis равно auto, и элементы не имеют установленной ширины, поэтому они имеют автоматический размер. Это означает, что используемая flex-basis — это max-content размер каждого элемента. После размещения элементов есть некоторое положительное свободное место в контейнере flex, которое показано на изображении ниже в виде штриховки; штрихованная область — это положительное свободное место, которое будет распределено между тремя элементами на основе их flex-grow коэффициентов:

Three items taking a bit more than half the width, with the rest of the width being hatched

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

The hatched area was divided into thirds, with each item getting a single portion appended.

Чтобы создать три элемента одинакового размера, даже если исходные элементы имеют разные размеры, установите компонент flex-basis в 0:

.class {
  flex: 1 1 0;
}

Здесь, для расчета распределения пространства, мы устанавливаем размер каждого элемента в 0. Это означает, что все пространство доступно для распределения. Поскольку у всех элементов одинаковый коэффициент flex-grow, каждый из них получает равное количество места. В результате получаются три элемента flex одинаковой ширины.

Попробуйте изменить коэффициент flex-grow с 1 на 0 в этом интерактивном примере, чтобы увидеть разное поведение:

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three has more content</div>
</div>
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  flex: 1 1 0;
}

.box {
  width: 400px;
  border: 2px dotted rgb(96 139 168);
  display: flex;
}

Назначение элементам различных коэффициентов flex-grow

Использование flex-grow и flex-basis вместе позволяет управлять размерами отдельных элементов, задавая разные коэффициенты flex-grow. Если мы сохраним flex-basis на уровне 0, чтобы все пространство можно было распределить, мы можем создать элементы flex разных размеров, присвоив каждому элементу различный коэффициент flex-grow.

В примере ниже мы используем 1 в качестве коэффициента flex-grow для первых двух элементов и удваиваем его до 2 для третьего элемента. При flex-basis: 0 , установленных для всех элементов, доступное пространство распределяется следующим образом:

  1. Значения коэффициента flex-grow всех элементов flex-потомков складываются (в данном случае итог 4).
  2. Положительное свободное пространство в контейнере flex делится на это суммарное значение.
  3. Свободное пространство распределяется в соответствии с индивидуальными значениями. В данном случае первый элемент получает одну часть, второй — одну, а третий — две. Это означает, что третий элемент вдвое больше первого и второго элементов.
<div class="box">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  flex: 1 1 0;
}

.box {
  border: 2px dotted rgb(96 139 168);
  display: flex;
}

.one {
  flex: 1 1 0;
}

.two {
  flex: 1 1 0;
}

.three {
  flex: 2 1 0;
}

Помните, что вы можете использовать здесь любое положительное значение. Важно соотношение между элементами. Вы можете использовать большие числа или десятичные дроби; это зависит от вас. Чтобы проверить это, измените значения flex-grow в приведенном выше примере на .25, .25, и .50. Вы должны увидеть тот же результат.

Свойство flex-shrink

Свойство flex-shrink задает коэффициент сжатия flex, который определяет, насколько элемент flex будет сжиматься относительно других элементов flex в контейнере flex при распределении отрицательного свободного пространства.

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

Если flex-grow используется для добавления доступного пространства к элементам, которые могут расти, то flex-shrink используется для удаления пространства, чтобы гарантировать, что элементы помещаются в контейнер без переполнения.

В этом примере есть три элемента flex шириной 200px в контейнере шириной 500px. При flex-shrink , установленном на 0, элементы не могут сжиматься, что приводит к переполнению контейнера.

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three has more content</div>
</div>
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  flex: 0 0 auto;
  width: 200px;
}

.box {
  width: 500px;
  border: 2px dotted rgb(96 139 168);
  display: flex;
}

Измените значение flex-shrink на 1; каждый элемент будет сжиматься на одинаковое количество, помещая все элементы в контейнер. Отрицательное свободное пространство было пропорционально удалено из каждого элемента, сделав каждый элемент flex меньше его начальной ширины.

Комбинирование flex-shrink и flex-basis

Может показаться, что flex-shrink работает так же, как flex-grow, сжимая, а не увеличивая элементы. Однако есть некоторые важные различия.

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

Небольшие элементы не будут сжиматься до размера меньше их min-content размера, который является минимальным размером элемента, если он использовал все доступные возможности перевода.

Этот пример демонстрирует min-content ограничение, с flex-basis , определяющимся размером содержимого. Если изменить ширину контейнера flex, например, увеличив ее до 700px, а затем уменьшить ширину элемента flex, вы увидите, что первые два элемента будут переносить. Однако они никогда не станут меньше своего min-content размера. Когда контейнер становится меньше, пространство удаляется только из третьего элемента, когда он сжимается еще дальше.

<div class="box">
  <div>Item One</div>
  <div>Item Two</div>
  <div>Item Three has more content and so has a larger size</div>
</div>
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  flex: 1 1 auto;
}

.box {
  border: 2px dotted rgb(96 139 168);
  width: 500px;
  display: flex;
}

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

Назначение элементам различных коэффициентов flex-shrink

Так же, как и flex-grow, вы можете назначить элементам flex различные коэффициенты flex-shrink. Это может помочь изменить поведение по умолчанию, если, например, вы хотите, чтобы элемент сжимался быстрее или медленнее своих собратьев или не сжимался совсем.

В этом примере первый элемент имеет коэффициент flex-shrink равный 1, второй элемент 0 (поэтому он вообще не будет сжиматься), а третий элемент 4, что в сумме дает коэффициенты сжатия 5. Таким образом, третий элемент сжимается примерно в четыре раза быстрее, чем первый, но ни один из них не сжимается ниже их min-content ширины. Поэкспериментируйте с разными значениями: как и с flex-grow, вы также можете использовать десятичные дроби или большие числа.

<div class="box">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  width: 200px;
}

.box {
  display: flex;
  width: 500px;
  border: 2px dotted rgb(96 139 168);
}

.one {
  flex: 1 1 auto;
}

.two {
  flex: 1 0 auto;
}

.three {
  flex: 2 4 auto;
}

Освоение размеров элементов flex

Чтобы понять, как работает размер элементов flex, вам необходимо учесть следующие факторы, которые мы обсуждали в этих руководствах:

Что определяет базовый размер элемента?

  • Установлено ли flex-basis в значение auto, и есть ли у элемента заданная ширина? Если да, размер будет основан на этой ширине.
  • Установлено ли flex-basis в значение auto, но у элемента нет заданной ширины? Если да, размер будет основан на размере содержимого элемента.
  • Является ли flex-basis длиной или процентом, но не нулем? Если да, это будет размер элемента (округлённый до min-content).
  • Установлено ли flex-basis в значение 0? Если да, размер элемента не будет учтён при расчете распределения пространства.

Есть ли свободное место?

Элементы могут расти только если есть положительное свободное место, и они не уменьшатся, если свободное место отрицательное.

  • Если сложить ширины всех элементов (или высоту, если работаем в столбце), это общее значение меньше общей ширины (или высоты) контейнера? Если да, то будет положительное свободное место, и flex-grow вступит в силу.
  • Если сложить ширины всех элементов (или высоту, если работаем в столбце), это общее значение больше общей ширины (или высоты) контейнера? Если да, то будет отрицательное свободное место, и flex-shrink вступит в силу.

Какие существуют другие способы распределения места?

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

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

© 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/Controlling_ratios_of_flex_items_along_the_main_axis

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API