1. Гибкая компоновка
Flex — это аббревиатура от Flexible Box, что означает «гибкая компоновка», которая используется для обеспечения максимальной гибкости блочной модели. Свойство flex является сокращением для flex-grow, flex-shrink и flex-basis, значение по умолчанию — 0 1 auto.
Любой контейнер можно выложить с помощью Flex (если гибкий макет не виден, г-н РуанУчебное пособие по гибкому макету), а Flex возникает в отношениях компоновки между родительским контейнером и дочерним контейнером, так какова связь между родительским контейнером и дочерним контейнером, как рассчитать пространство, занимаемое дочерним контейнером, и как выполнить гибкую компоновку? ?
Чтобы решить вышеуказанную проблему, мы должны сначала понять, как рассчитываются flex-grow и flex-shrink? Какова связь и разница между flex-basis и width?
Далее мы сначала предлагаем две концепции:Свободное пространство и пространство переполнения, что именно это означает, мы объясним позже.
2. flex-grow
Определение свойства flex-grow на MDN:
Определяет коэффициент растяжения для flex-элемента, значение по умолчанию — 0.
Традиционный макет заключается в том, что дочерний контейнер выкладывается слева направо в родительском контейнере, а для макета используется flex, тогда родительский контейнер должен быть установленdisplay: flex
, дочерний контейнер должен «занимать» и «разделять» пространство родительского контейнера, и стратегия того, как его занимать и делить, — это стратегия гибкой компоновки. Здесь мы объясняем понятие «оставшееся место»:
Сколько места дочерний контейнер может «разделить» на «шпинделе» родительского контейнера, это пространство, которое может быть «разделено», называется оставшимся пространством.
Текст всегда очень абстрактный, например, можно понять оставшееся пространство, сейчас есть следующий код:
HTML-код:
<div class="container">
<div class="item a">
<p>A</p>
<p> width:100</p>
</div>
<div class="item b">
<p>B</p>
<p> width:150</p>
</div>
<div class="item c">
<p>C</p>
<p> width:100</p>
</div>
</div>
CSS-код:
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
color: #666;
text-align: center;
}
.item {
height: 100px;
}
.item p {
margin: 0;
}
.a{
width: 100px;
background-color:#ff4466;
}
.b{
width: 150px;
background-color:#42b983;
}
.c{
width: 100px;
background-color:#61dafb;
}
Отображаемый эффект выглядит следующим образом (последнее поле — это аннотация скриншота, а не отображаемый эффект):
Картинка стоит тысячи слов, и вы должны понимать, что такое свободное пространство, когда видите эту картинку.
На главной оси родительского контейнера остается так много места, как дочерний контейнер может разделить это оставшееся пространство, чтобы добиться эффекта эластичности?
Это нужно использоватьflex-grow
атрибут,flex-grow
Определите пропорцию оставшегося пространства подконтейнера, по умолчанию0
, то есть если останется место, оно не будет разделено.
flex-grow
пример, измените приведенный выше пример на следующий код:
HTML-код (код добавляет только описание flex-grow, никаких других структурных изменений):
<div class="container">
<div class="item a">
<p>A</p>
<p> width:100</p>
<p>flex-grow:1</p>
</div>
<div class="item b">
<p>B</p>
<p> width:150</p>
<p>flex-grow:2</p>
</div>
<div class="item c">
<p>C</p>
<p> width:100</p>
<p>flex-grow:3</p>
</div>
</div>
Код CSS (добавляет flex-grow к каждому дочернему контейнеру):
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
color: #666;
text-align: center;
}
.item {
height: 100px;
p {
margin: 0;
}
}
.a{
width: 100px;
flex-grow:1;
background-color:#ff4466;
}
.b{
width: 150px;
flex-grow:2;
background-color:#42b983;
}
.c{
width: 100px;
flex-grow:3;
background-color:#61dafb;
}
Результат выглядит следующим образом:
Изначально мы обнаружили, что сумма ширины дочернего контейнера составляет всего 350 пикселей, а ширина родительского контейнера — 500 пикселей, поэтому появляется оставшееся пространство, которое составляет 150 пикселей. когда установленоflex-grow
После этого три подконтейнера A, B и C будут основаны на собственныхflex-grow
Чтобы «поделить» оставшееся пространство.
Здесь мы делаем вывод, что свойство flex-grow определяет, сколько оставшегося места дочерний контейнер будет занимать в родительском контейнере.
Он рассчитывается следующим образом:
- Свободное место: х
- Допустим есть три элемента flex item, значения flex-grow равны a, b, c соответственно
- Оставшееся пространство, которое может быть выделено для каждого элемента: а/(а+b+с) * х, б/(а+b+с) * х, с/(а+b+с) * х
Возьмите A в качестве примера, чтобы проиллюстрировать:Оставшееся пространство приходится на A: 1/(1+2+3) = 1/6, затем A «делится»150*1/6=25
, фактическая ширина100+25=125
.
Подумайте, можно ли установить значение flex-grow меньше 1, а сумма flex-grow тоже меньше 1? Просто установите знаменатель приведенной выше формулы (сумма flex-grow) равным 1, и все готово!
3. flex-shrink
После разговора о flex-grow мы знаем, что подконтейнер может быть растянут, если установлен flex-grow. Итак, при каких обстоятельствах подконтейнер сжимается? Рассмотрим ситуацию: если ширина дочернего контейнера превышает ширину родительского контейнера, даже если установлен flex-grow, оставшееся пространство не может быть выделено, потому что свободного места нет. На данный момент существует два способа: обертывание и сжатие. Поскольку flex не сворачивает по умолчанию, как его сжать и насколько? На этом этапе вам нужно использовать свойство flex-shrink.
Определение свойства flex-shrink на MDN:
Указывает правило сжатия для flex-элементов, значение по умолчанию — 1.
В этот момент понятие оставшегося пространства трансформируется в«Переполненное пространство»
Расчет:
- Ширина трех элементов гибкого элемента: w1, w2, w3.
- flex-shrink трех элементов flex item: a, b, c
- Рассчитайте общий вес сжатия: сумма = а * w1 + b * w2 + c * w3
- Рассчитайте коэффициент сжатия для каждого элемента: S1=a*w1/сумма, S2=b*w2/сумма, S3=c*w3/сумма
- Рассчитайте ширину каждого элемента: ширина - степень сжатия * пространство переполнения
Например:
<div class="container">
<div class="item a">
<p>A</p>
<p> width:300</p>
<p>flex-shrink: 1</p>
</div>
<div class="item b">
<p>B</p>
<p> width:150</p>
<p>flex-shrink: 2</p>
</div>
<div class="item c">
<p>C</p>
<p> width:200</p>
<p>flex-shrink: 3</p>
</div>
</div>
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
color: #666;
text-align:center;
}
.item {
height: 100px;
}
.item p {
margin: 0;
}
.a{
width: 300px;
flex-grow: 1;
flex-shrink: 1;
background-color:#ff4466;
}
.b{
width: 150px;
flex-shrink: 2;
background-color:#42b983;
}
.c{
width: 200px;
flex-shrink: 3;
background-color:#61dafb;
}
Сумма ширин подконтейнеров составляет 650, а пространство переполнения — 150. Общее сжатие: 300*1+150*2+200*3=1200 Степень сжатия А: 300*1/1200 = 0,25 Значение сжатия A: 150 * 0,25 = 37,5 Фактическая ширина A: 300 - 37,5 = 262,5
Результат выглядит следующим образом:
Аналогично, что произойдет, если сумма flex-shrink меньше 1? Тогда результат вычисления пространства переполнения (усадочной суммы) меняется. Например: для сжатия установлено значение 0,1, 0,2, 0,3, исходное пространство переполнения — 200, фактическое пространство переполнения: 200 * (0,1 + 0,2 + 0,3) / 1 = 120.
Примечание. Если дочерний контейнер не превышает родительский контейнер, настройка flex-shrink не имеет никакого эффекта.
4. flex-basis
Определение MDN: указывает начальный размер flex-элемента в направлении главной оси.
Когда гибкий элемент помещается во гибкий контейнер, не гарантируется его отображение в соответствии с размером, установленным flex-basis. Браузер вычислит, есть ли свободное место на главной оси в соответствии с flex-basis. Поскольку это связано с шириной, каков приоритет размера max-width, min-width, width и box.
Например:
<div class="container">
<div class="item a">A</div>
<div class="item b">B</div>
<div class="item c">C</div>
</div>
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
text-align: center;
line-height: 100px;
color: #666;
}
.item {
width: 100px;
height: 100px;
}
.a{
flex-basis: 200px;
background-color:#ff4466;
}
.b{
max-width: 50px;
flex-basis: 150px;
background-color:#42b983;
}
.c{
background-color:#61dafb;
}
Результат выглядит следующим образом:
В приведенном выше примере можно увидеть отношение приоритета нескольких атрибутов через ширину конечного элемента:max-width/min-width > flex-basis > width > box
5. Сценарии применения
- Очень распространенный макет: когда область содержимого недостаточно высока, нижний колонтитул все равно нужно закрепить внизу. На этом этапе мы можем использовать flex-grow: 1 для main, чтобы автоматически заполнить оставшееся пространство.
2. Когда мы разрабатываем общий компонент формы, использование гибкой компоновки может привести к тому, что поле ввода займет оставшееся пространство.
В большинстве сценариев мы не хотим, чтобы элементы сжимались, поэтому flex-shrink обычно устанавливается равным 0.
6. Резюме
Наконец, мы должны обратить внимание на:
- Сумма flex-элементов превышает flex-контейнер и будет сжата в соответствии с настройкой flex-shrink.
- Если есть оставшееся место, если установлен flex-grow, фактическая ширина дочернего контейнера связана с настройкой flex-grow. Если flex-grow не установлен, фактическая ширина отображается в соответствии с flex-basis
использованная литература: