Работаем с Flexbox: flex-basis

Работаем с Flexbox: flex-basis

Больше вкусностей найдешь на моем канале - https://t.me/emotional_robot


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

Напоминаю, что все примеры я складываю в личном репозитории на GitHub. Спуливайте последние изменения и заходите в папку "src/flexbox-layout-examples/flex-basis". Сейчас потихоньку пройдемся по всем файлам. Как обычно, результат работы можно посмотреть, открыв в браузере файл "index.html".

Как определяется размер flex-элемента


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

Когда вы задаете свойство "display: flex" контейнеру, его элементы даже без явного указания свойства "flex" (напоминаю, что это сокращение для "flex-grow", "flex-shrink" и "flex-basis") будут вести себя как flex-элементы. Это из-за значения по умолчанию для flex. Оно выглядит так:

flex: 0 1 auto

Это означает, что flex-элементы не должны растягиваться на все свободное пространство (flex-grow: 0), должны сжиматься равномерно (flex-shrink: 1), иметь автоматический flex-basis. Выделяют четыре варианта установки начального размера:

  1. Явное указание flex-basis: 100px, 20em, calc(100% - 30em) и так далее.
  2. Явное указание width. Если flex-basis не указан (что означает "auto"), размер flex-элемента смотрит на свойство width.
  3. Если не указаны ни flex-basis, ни width, тогда размер flex-элемента устанавливается по его содержимому (контенту).
  4. Если элементу указать min-width (минимальная ширина) и max-width (максимальная ширина), то его размер будет ограничен этими величинами.

Это можно представить такой формулой:

content → width → flex-basis (ограниченный max|min-width)

Откройте в браузере файл "index.html". Вы увидите два flex-контейнера с 4 элементами в каждом. Выглядит все одинаково. Однако, у элементов первого контейнера указано свойство "width", у элементов второго - "flex-basis". Откройте файл "style.css" и убедитесь в этом.

Давайте проверим нашу формулу. Сначала внутри селектора ".flex-width" укажите "flex-basis: 250px" сразу под свойством "width" и проверьте результат в браузере. Как видите, наличие "flex-basis" убивает необходимость указывать "width". Теперь удалите все стили из этого селектора и еще раз проверьте результат. Ширина элементов теперь стала по контенту.

Чтобы проверить работу "min-width" и "max-width", сначала уберите "width: 1000px" в селекторе ".flex-container", затем в селекторе ".flex-width" добавьте следующее:

Теперь откройте браузер и посмотрите внимательно на поведение элементов в первом контейнере. Во-первых, несмотря на указание "flex-grow: 1", элементы не заняли все свободное пространство, потому что их размер ограничен "max-width". Во-вторых, если вы будете уменьшать размер окна браузера, элементы будут сжиматься (помним про значение "flex-shrink: 1" по умолчанию), пока не достигнут размера в 200 пикселей (min-width). Меньше этого числа размер элемента не станет.

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

В чем смысл flex-basis?


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

Flexbox - это про контейнеры и их элементы. Есть отдельно контейнер, отдельно элемент, и есть их симбиоз - помещение элементов в контейнер. Так вот, flex-basis - это размер flex-элементов перед тем, как они разместятся в контейнере. Это идеальный или предположительный размер элементов.

Но flex-basis - это не гарантированный размер. Как только браузер поместит элементы в контейнер, всё поменяется. Если сумма flex-basis всех элементов равна размеру контейнера, то все будет четко работать (попробуйте вставить пятый элемент во второй контейнер в файле "index.html").

Но если сумма flex-basis элементов больше или меньше размера flex-контейнера, то для грамотного их размещения в игру вступают "flex-grow" и "flex-shrink". Теперь вы понимаете, почему именно эти три свойства объединены в одно под названием "flex"? Потому что они практически всегда указываются вместе. Вы сначала выбираете изначальный размер элемента (flex-basis), а затем решаете, как элемент будет расти при наличии свободного пространства в контейнере (flex-grow), и как будет сжиматься при нехватке этого места (flex-shrink).

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

Но есть еще одна существенная разница, и она кроется в свойстве контейнера "flex-direction". Если она указана "row" или "row-reverse", то "width" и "flex-basis" взаимозаменяемы. Но стоит вам направление изменить на вертикальное ("column" и "column-reverse"), как все переворачивается: теперь "flex-basis" - это одно и то же со свойством "height".

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

В общем, использование width (или height) не запрещается, главное помнить о нюансах.

Итого

Мы закончили знакомиться с таким замечательным инструментом, как Flexbox. Это мощная штука для верстки, позволяющая размещать красиво элементы в строку или столбец при различных экранах устройств. Мы можем позиционировать ("align-items", "justify-content", "align-content"), направлять ("flex-direction") и переносить на новую строку/столбец ("flex-wrap") элементы, описывая свойства во flex-контейнере, и управлять изначальным размером ("flex-basis"), расширением ("flex-grow"), сжатием ("flex-shrink"), порядком ("order") и позицией ("align-self") конкретного flex-элемента.

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



Report Page