Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Вольный перевод статьи http://gedd.ski/post/the-difference-between-width-and-flex-basis/

Отличия между свойствами width и flex-basis

Безусловно, это самый распространенный вопрос о flexbox, который мне задают. Помню как сам прибегал к поиску ответа на этот вопрос, когда еще только изучал flexbox. Проверяя свою историю поиска в Google, я обнаружил, что за последний год делал запросы по фразе "flex-basis vs width vs min-width" 4 раза. Talk about slacking! Сегодня я дам ответ на этот вопрос, и надеюсь, сэкономлю кому-то время на поиск этого ответа.

Формула flex элементов

Это формула, которую необходимо запомнить:

content –> width –> flex-basis (ограничено помощью max|min-width)

Для опеределения размера flex элемента самым важным является итоговое значение flex-basis, которое связано со свойствами max-width и min-width.

Спецификация flexbox называет это "гипотетическим основным размером", но его проще представить как итоговое значение flex-basis.

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

Давайте проиллюстрируем данную формулу. Создадим flex контейнер с шириной в 1000px: Flex контейнер

container {
  display: flex;
  width: 1000px;
}

Добавление свойства width

Создадим элементы, размером 200x200px: Flex элементы

item {
  width: 200px;
  height: 200px;
}

И добавим данные элементы в ранее созданный flex контйенер: Flex элементы внутри flex контейнера

Во flex контейнере много места, и его элементы хорошо в него вписались.

В этом примере у flex элементов не выставлено значение свойства flex-basis, а значением по умолчанию является - auto, которое берет значение свойства width.

В данном случае, установка свойства width равнозначна установке свойства flex-basis.

Добавление свойства flex-basis

Давайте посмотрим, что произойдет, если мы добавим нашим flex элементам опеределенное значение для flex-basis, если у них уже есть свойство width:

Flex элементы с flex-basis свойством

item {
  width: 30px;
  flex-basis: 250px;
}

Как видите, когда свойство flex-basis имеет конкретное значение, то свойство width просто игнорируется, поэтому мы можем его не указывать.

item {
  flex-basis: 250px;
}

Окончательное значение свойства flex-basis для каждого элемента равняется 250px. На данный момент, у нас хватает места в контейнере, поэтому элементы в него прекрасно вписываются.

Вспомните формулу, по которой высчитывается значение flex-basis:

content –> width –> flex-basis (ограничено помощью max|min-width)

Важно только конечное свойство flex-basis. Лучше всего указывать именно его, вместо свойства width.

Свойство flex-basis ограниченное свойством max-width

Окончательное значение свойства flex-basis ограничивается двумя свойствами: max-width и min-width. Посмотрим, что произойдет, если мы добавим определенное значение свойству max-width у наших flex элементов. max-width у flex элементов

item {
  flex-basis: 250px;
  max-width: 100px;
}

Несмотря на то, что у наших элементов установлено свойство flex-basis со значением 250px, каждый из них достиг макисмально возможной ширины, установленной в свойстве max-width, и равной 100px. В итоге, окончательное значение flex-basis в этом случае равняется 100px, и элементы вписываются в контейнер следующим образм: Расположение во flex контейнере flex элементов с установленным свойством max-width

А теперь, давайте уставновим значение для свойства min-width и посмотрим, как это повлияет на окончательное значение свойства flex-basis: min-width у flex элементов

item {
  flex-basis: 100px;
  min-width: 250px;
}

Несмотря на то, что у наших элементов установлено свойство flex-basis со значением 100px, их ширина не может быть меньше 250px, так как это значение указано у свойства min-width. Поэтому, окончательное значение flex-basis в этом случае равняется 250px, и элементы прекрасно вписываются в контейнер: Расположение во flex контейнере flex элементов с установленным свойством min-width

Так что же означает свойство flex-basis?

Сейчас мы понимаем, что свойство width является так называемым "фолбэком" (значение из этого свойства берется в том случае, если свойство flex-basis не уставновлено, или имеет значение по умолчанию - auto), а свойства max-width и min-width ограничивают окончательное значение для свойства flex-basis. Так что же означает свойство flex-basis?

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

Когда в контейнере не хватает места

Скажем, мы хотим вставить еще больше элементов со значением flex-basis: 200px в наш flex контейнер: Элементы, у которых сумма значений flex-basis превышает ширину flex контейнер

Перед тем как перейти во flex контейнер, каждый из этих элементов получит ширину равную 200px, а в сумме это будет 1600px. Но у нашего контейнера доступно только 1000px. Когда места не хватает для всех элементов с определенным значением flex-basis, то элементы будут сжиматься, чтобы уместиться во flex контейнере

Сжатие элементов для вписывания в размер flex контейнера

Все элементы изначально имели ширину в 200px, но так как во flex контейнере не хватало места, то они одинакого уменьшились до 125px, чтобы полностью уместиться в нем. За коэффициент сжатия отвечает свойство flex-shrink. Вы можете переопределять это свойство, делая некоторые элементы больше (с большими коэффцициентами) или меньше (с меньшими коэффициентами). Можно также запретить элементу сжиматься, установив свойство flex-shrink в значение 0.

Когда в контейнере остается место

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

item {
  flex-basis: 100px;
}

Мы можем поручить нашим flex элементам растягиваться, чтобы заполнить все доступное пространство flex контейнера. За это отвечает свойство flex-grow. По умолчанию оно имеет значение 0, т.е. запрещает расширяться нашим flex элементам. Давайте установим каждому элементу это свойство в значение 1, чтобы они одинакого расширились, заполнив свободное пространство своего flex контейнера: Расширение элементов для заполнения flex контейнера

item {
  flex-basis: 100px;
  flex-grow: 1;
}

Управление расширением и сжатием - огрномная часть спецификации flexbox, именно это делает flexbox великолепным инструментом в отзывчивом UI дизайне.

Width vs flex-basis

Надеюсь, теперь вы видите разницу между свойствами width и flex-basis, а также то, как свойства max-width и min-width влияют на окончательное значение flex-basis. Все вышеперечисленное также относится и к свойству height, когда у flex контейнера изменена основная ось направления flex элементов с помощью свойства flex-direction и его значений column и column-reverse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment