Главная » Статьи » Подробное рассмотрение свойств Flex

Подробное рассмотрение свойств Flex

Подробное рассмотрение свойств Flex

От автора: вы когда-нибудь задумывались о том, как работает свойство CSS flex? Это сокращение от flex-grow, flex-shrink и flex-basis. Наиболее распространенный вариант использования, который я вижу в Интернете — flex: 1. Это возможность flex-элемента расширяться и заполнять все доступное пространство.

В этой статье я подробно рассмотрю сокращенные и полные свойства и объясню, когда и для чего их использовать, с практическими и наглядными примерами.

Свойство flex-grow

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

<div class="wrapper"> <div class="item item-1"></div> <div class="item item-2"></div> <div class="item item-3"></div>
</div>

.wrapper { display: flex; flex-wrap: wrap;
} .item { flex-grow: 1;
}

Примечание: в зависимости от свойства flex-direction flex-grow может влиять на ширину или высоту. В следующих примерах предположим, что для параметра flex-direction установлено значение row (значение по умолчанию), если я не укажу что-то другое.

Обратите внимание, что без использования flex-grow ширина элементов по умолчанию будет равна их начальной ширине. Однако при использовании flex-grow: 1 доступное пространство распределяется между ними.

Подробное рассмотрение свойств Flex

Вам может быть интересно, как пространство распределяется между flex-элементами? Что ж, это хороший вопрос, и я на него скоро отвечу. На рисунке ниже показано, как элементы выглядят без flex-grow. Другими словами, это их естественный размер.

Подробное рассмотрение свойств Flex

Чтобы понять, как рассчитывается ширина flex-элемента, см. уравнение ниже. Я узнал об уравнении из этого поста Саманты Минг (Спасибо!). Рассчитаем размер элемента, содержащего текст «CSS».

Подробное рассмотрение свойств Flex

Ширина элемента = ((flex-grow / total flex-grow) * доступное пространство) + начальная ширина элемента

Flex-grow: коэффициент растяжения для элемента

Total flex-grow: сумма значений flex-grow для всех элементов

Доступное пространство: перед применением flex-grow

Ширина элемента: начальная ширина элемента.

-> Ширина элемента = ((1/3) * 498) + 77 = 241

Несколько факторов flex-grow

В предыдущем примере значение flex-grow одинаково для всех элементов. Попробуем добавить flex-grow: 2 для первого элемента. Как это будет рассчитываться? Имейте в виду, что для нашего примера доступно пространство 498px.

Подробное рассмотрение свойств Flex

Надеюсь, теперь вам стало понятнее.

Можем ли мы использовать ноль в качестве значения flex-grow?

Конечно! Поскольку свойство flex-grow принимает целочисленные значения, можно использовать 0, как способ предотвратить расширения элемента в доступном пространстве.

Подробное рассмотрение свойств Flex

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

Flex-grow не делает flex-элементы одинаковыми

Существует распространенное заблуждение, что использование flex-grow сделает элементы равными по ширине. Это неверно. Идея использования flex-grow — распределить доступное пространство. Как вы видели в уравнении, ширина каждого гибкого элемента рассчитывается на основе его начальной ширины (ширины до применения flex-grow).

Если вы хотите, чтобы элементы были одинаковыми по ширине, это можно сделать, используя flex-basis. Я объясню это в следующих разделах.

Свойство flex-shrink

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

Рассмотрим следующий пример. Средний элемент имеет ширину 300px, и установлено flex-shrink: 1. Это позволит элементу уменьшиться в ширину, если нет места для размещения всех flex-элементов.

Подробное рассмотрение свойств Flex

.item-2 { width: 300px; flex-shrink: 1;
}

Браузер сохранит ширину элемента равной 300px при следующих условиях:

Сумма ширины всех элементов меньше ширины оболочки

Ширина области просмотра равна или меньше ширины элемента

Вот как элемент ведет себя с разными размерами области просмотра.

Подробное рассмотрение свойств Flex

Как вы видите на рисунке, ширина будет 300px до тех пор, пока ширина области просмотра не станет меньше 300px.

Свойство flex-basis

Оно устанавливает начальный размер flex-элемента перед распределением свободного пространства в соответствии с коэффициентами. Размер может относиться к ширине по умолчанию и высоте (в случае flex-direction: column).

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

.item-1 { flex-grow: 0; flex-shrink: 0; flex-basis: 50%;
}

Подробное рассмотрение свойств Flex

В приведенном выше примере ширина первого элемента составляет 50%. Важно сбросить значение flex-grow на 0, чтобы элемент не стал больше, чем 50%.

Что будет, если использовать вместо этого 100%? Элемент займет 100% ширины своего родителя, а остальные элементы будут перенесены в новую строку.

.item-1 { flex-grow: 0; flex-shrink: 0; flex-basis: 100%;
}

Подробное рассмотрение свойств Flex

Сокращенное свойство Flex

Это сокращение для flex-grow, flex-shrink и flex-basis. Значение по умолчанию для flex — auto, которое преобразуется во flex: 0 1 auto. Это означает, что оно позволяет гибким элементам увеличиваться в зависимости от размера их содержимого.

В этом контексте есть кое-что важное, что я хотел бы выделить, а именно абсолютные и относительные flex-элементы. Нет, речь идет не о позиционировании CSS, а о том, что связано с flexbox.

Относительный размер flex-элементов

.item { /* The default value, equivalent to flex: 1 1 auto */ flex: auto;
}

Размер flex-элементов зависит от содержимого. В результате flex-элементы с большим количеством содержимого будут больше.

Подробное рассмотрение свойств Flex

Абсолютный размер flex-элементов

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

.item { /* Equivalent to flex: 1 1 0% */ flex: 1;
}

Подробное рассмотрение свойств Flex

Что мне нравится в свойстве Flex

Судя по названию, это свойство может принимать значения. Возьмем следующие примеры.

Одно значение без единиц измерения

.item { flex: 1;
}

Если он имеет только одно значение без единиц измерения, оно будет рассматриваться как flex-grow, а полные значения будут 1 1 0.

Два значения без единиц измерения

.item { flex: 1 1;
}

Значения — flex-grow и flex-shrink соответственно. По умолчанию flex-basis будет 0.

Одно значение длины

Оно будет использоваться для flex-basis. По умолчанию flex-grow и flex-shrink будут 1.

.item { flex: 100px; /* flex: 1 1 100px */
}

Использование 0 без единиц измерения

В тех случаях, когда вам нужно установить для flex-basis 0, используя сокращение flex.

.item { flex: 0;
}

Это не рекомендуется делать, так как это запутает и разработчика, и браузер. Как вы можете понять, относится 0 к факторам растяжения или сжатия, или к flex-basis? Это сбивает с толку. Согласно спецификации CSS:

Ноль без единиц измерения, которому не предшествуют два коэффициента сжатия/растяжения, следует интерпретировать как коэффициент сжатия/растяжения. Чтобы избежать неправильного толкования или недопустимых объявлений, авторы должны указать нулевой компонент <’flex-base’> с единицей измерения или поставить перед ним два фактора сжатия/растяжения.

Вместо этого вы должны добавить такие единицы, как px или %.

.item { flex: 0%; /* flex: 1 1 0% */
}

Рекомендуется использовать сокращение Flex

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

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

Случаи использования

Аватар пользователя

Подробное рассмотрение свойств Flex

Типичный вариант использования flexbox — пользовательский компонент. Аватар и текстовое содержимое должны находиться в одной строке.

<div class="user"> <img class="user__avatar" src="shadeed.jpg" alt="" /> <div> <h3>Ahmad Shadeed</h3> <p>Author of Debugging CSS</p> </div>
</div>

.user { display: flex; flex-wrap: wrap; align-items: center;
} .user__avatar { flex: 0 0 70px; width: 70px; height: 70px;
}

Обратите внимание, что я добавил для аватара flex: 0 0 70px. Это важно, так как в некоторых старых браузерах изображение может выглядеть сжатым, если flex не установлено. Добавление этого придает flex более высокий приоритет, чем у свойства width (в случае flex-direction: row) или height (в случае flex-direction: column).

Если мы изменим размер аватара, просто настроив свойство flex, width браузер будет игнорировать.

.user__avatar { /* The width is 100px, not 70px */ flex: 0 0 100px; width: 70px; height: 70px;
}

Заголовок раздела

Подробное рассмотрение свойств Flex

У вас есть заголовок раздела, и он должен занимать все доступное пространство. Использование flex: 1идеально подходит для этого случая.

.page-header { display: flex; flex-wrap: wrap; } .page-header__title { flex: 1;
}

Поле для ввода сообщения

Подробное рассмотрение свойств Flex

Это очень распространено в приложениях для обмена сообщениями, таких как Facebook Messenger или Twitter. Входные данные должны заполнять доступное пространство с фиксированной шириной до кнопки отправки.

form { display: flex; flex-wrap: wrap; } input { flex: 1; /* Other styles */
}

Приведенные выше сценарии являются полезными примерами использования flex-grow. Однако некоторые случаи игнорируются или вообще не упоминаются в статьях по flex. Давайте рассмотрим их!

Выравнивание последнего элемента на двух карточках

Подробное рассмотрение свойств Flex

Предположим, что CSS-сетка имеет макет из двух столбцов. Проблема в том, что здесь даты не совпадают. Они должны быть на одной линии (красной). Мы можем сделать это с помощью flexbox.

<div class="card"> <img src="thumb.jpg" alt=""> <h3 class="card__title">Title short</h3> <time class="card__date"></time>
</div>

Установив flex-direction: column, мы можем использовать flex-grow для заголовка, чтобы он заполнял доступное пространство, и, таким образом, дата оставалась в конце, даже если заголовок короткий.

.card { display: flex; flex-direction: column;
} /* First solution */
.card__title { flex-grow: 1;
}

Кроме того, это возможно без использования flex-grow. Благодаря авто полям и flexbox!

/* Second solution */
.card__date { margin-top: auto;
}

Сценарии использования — более одного фактора Flex

Я имею в виду, что здесь используется flex-grow или flex-shrink, но со значением, отличным от 1. В этом разделе я рассмотрю некоторые идеи, где это можно включить.

Действия в футере

Подробное рассмотрение свойств Flex

Вдохновленный Facebook (я украл также значки), этот футер состоит из четырех элементов, и последний имеет меньшую ширину. Мы можем сделать следующее:

.actions { display: flex; flex-wrap: wrap;
} .actions__item { flex: 2;
} .actions__item.user { flex: 1;
}

Анимация раскрытия

Подробное рассмотрение свойств Flex

Мы можем сделать интересную вещь — анимировать элемент при наведении курсора. Это может быть чрезвычайно полезно. Вот простой пример того, что возможно:

.palette { display: flex; flex-wrap: wrap;
} .palette__item { flex: 1; transition: flex 0.3s ease-out;
} .palette__item:hover { flex: 4;
}

Расширение тарифного плана

Мне нравится эта демонстрация на Codepen. После активации карта расширяется с flex-grow 4.

Когда содержимое больше, чем его оболочка

Подробное рассмотрение свойств Flex

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

.wrapper { display: flex;
} .wrapper img { flex: 1;
}

Однако даже при flex: 1 изображения все равно выходят за пределы оболочки. Согласно спецификации CSS:

По умолчанию flex-элементы не сжимаются меньше минимального размера своего содержимого (длины самого длинного слова или элемента фиксированного размера). Чтобы изменить это, установите свойство min-width или min-height.

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

.wrapper img { flex: 1; min-width: 0;
}

Заключение

Вот и все. Я объяснил основы свойств flex и, как их использовать. Надеюсь, вы узнали что-то новое из этой статьи. Спасибо за прочтение.

Автор: Ahmad Shadeed

Источник: https://ishadeed.com

Редакция: Команда webformyself.