Как работает CSS Flexbox: наглядное введение в систему компоновки элементов на веб-странице
Авторизуйтесь
Как работает CSS Flexbox: наглядное введение в систему компоновки элементов на веб-странице
CSS Flexbox — это технология для создания сложных гибких макетов за счёт правильного размещения элементов на странице. О самой технологии пишут здесь. Мы же решили объяснить возможности CSS Flexbox с использованием гифок.
Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.
display: flex
Так у блоков появилось свойство flex-контекст, которое в дальнейшем позволит ими управлять гораздо проще, чем с использованием стандартного CSS.
flex-direction
У flex-контейнера есть две оси: главная и перпендикулярная ей.
Обратите внимание, что flex-direction: column не выравнивает блоки по оси, перпендикулярной главной. Главная ось сама меняет своё расположение, и теперь направлена сверху вниз.
justify-content
Отвечает за выравнивание элементов по главной оси:
Justify-content может принимать 5 значений:
Space-between задаёт одинаковое расстояние между блоками, но не между контейнером и блоками. Space-around также задаёт одинаковое расстояние между блоками, но теперь расстояние между контейнером и блоками равно половине расстояния между блоками.
align-items
Если justify-content работает с главной осью, то align-items работает с осью, перпендикулярной главной оси. Вернёмся к flex-direction: row и пройдёмся по командам align-items :
Чтобы получше разобраться в том, как работают оси, объединим justify-content с align-items и посмотрим, как работает выравнивание по центру для двух свойств flex-direction :
align-self
Позволяет выравнивать элементы по отдельности:
flex-basis
Отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами CSS Flexbox:
flex-basis влияет на размер элементов вдоль главной оси. Давайте посмотрим, что случится, если мы изменим направление главной оси:
Заметьте, что нам пришлось изменить и высоту элементов: flex-basis может определять как высоту элементов, так и их ширину в зависимости от направления оси.
flex-grow
Это свойство немного сложнее. Для начала зададим блокам одинаковую ширину в 120px:
По умолчанию значение flex-grow равно 0. Это значит, что блокам запрещено увеличиваться в размерах. Зададим flex-grow равным 1 для каждого блока:
Вначале flex-grow каждого блока равен 1, в сумме получится 6. Значит, наш контейнер разделён на 6 частей. Каждый блок будет занимать 1/6 часть доступного пространства в контейнере. Когда flex-grow третьего блока становится равным 2, контейнер делится на 7 частей: 1 + 1 + 2 + 1 + 1 + 1. Теперь третий блок занимает 2/7 пространства, остальные — по 1/7. И так далее.
flex-grow работает только для главной оси, пока мы не изменим её направление.
flex-shrink
Зададим flex-grow и flex-shrink равными 1:
Теперь поменяем значение flex-shrink для третьего блока на 0. Ему запретили сжиматься, поэтому его ширина останется равной 120px:
flex-shrink основывается на пропорциях. То есть, если у первого блока flex-shrink равен 6, а у остальных он равен 2, то, это значит, что первый блок будет сжиматься в три раза быстрее, чем остальные.
Создадим два блока:
Ещё больше возможностей свойства вы можете найти в анимированном руководстве по CSS flex.
Дополнительно
Как с CSS Flexbox меняется размер?
Когда увеличивается первый блок, он не становится в два раза больше второго, и когда уменьшается второй, он также не становится в два раза меньше первого. Это происходит из-за того, что flex-grow и flex-shrink отвечают за темп роста и сокращения.
Немного математики
Если вы также интересуетесь CSS Grid, можете ознакомиться с нашей статьёй, где мы рассматриваем Flexbox и Grid.
Flexbox в CSS
Модель верстки известная как Flexbox (флексы), становится все популярнее. В первую очередь за счет удобного использования при создании каркасов и верстки отдельных элементов HTML страницы. Во вторую, за счет совершенно новых возможностей. В этой статье я попробую разобраться во всех тонкостях Flexbox, сделать своего рода документацию (шпаргалку) по флексам и доступно поделиться знаниями с вами.
Если говорить коротко про документацию флексов, то верстка с Flexbox дает нам простые решения некогда непростых задач. Например, когда нужно выровнять элемент по вертикали, или прижать подвал к низу экрана, или просто вставить несколько блоков в один ряд, так чтобы они занимали все свободно пространство. Подобные задачи решаются и без flex. Но как правило, эти решения больше похожи на «костыли», и это еще больше усложняется когда нужно сверстать адаптивный под мобильные устройства макет. Тогда как с flexbox такие задачи решаются элегантно и именно так, как задумывает flex-модель (без добавления вспомогательных стилей и прочего).
Flexbox позволяет элегантно контролировать самые разные параметры элементов внутри контейнера: направление, порядок, ширину, высоту, выравнивание вдоль и поперек, распределение свободного места, растяжение и сжатие элементов.
Базовые знания
FlexBox состоит из Контейнера и его Дочерних элементов (items) (гибких элементов).
После включения flex свойства, внутри контейнера создаются две оси: главная и поперечная (перпендикулярная (⊥), кросс ось). Все вложенные элементы (первого уровня) выстраиваются по главной оси. По умолчанию главная ось горизонтальная и имеет направление слева направо (→), а кросс ось соответственно вертикальная и направлена сверху вниз (↓).
Еще одной важной особенностью Флекс-бокс является наличие рядов в поперечном направлении. Чтобы понять о чем речь, давайте представим что есть главная горизонтальная ось, много элементов и они не «лезут» в контейнер, поэтому переходят на другой ряд. Т.е. контейнер выглядит так: контейнер, внутри него два ряда, в каждом ряду по несколько элементов. Представили? А теперь запомните, что выравнивать по вертикали мы можем не только элементы, но и ряды! Как это работает хорошо видно в примере к свойству align-content. А вот так это выглядит схематически:
CSS свойства Flexbox
Flexbox содержит разные css правила для управления всей flex конструкцией. Одни нужно применять к основному контейнеру, а другие к элементам этого контейнера.
Для контейнера
Изменяет направление главной оси контейнера. Поперечная ось меняется соответственно.
Управляет переносом непомещающихся в контейнер элементов.
flex-flow принимает значения двух этих свойств, разделенные пробелом. Или можно указать одно значение любого свойства.
Выравнивает элементы по основной оси: если direction=row, то по горизонтали, а если direction=column, то по вертикали.
Выравнивает ряды, в которых находятся элементы по поперечной оси. То же что justify-content только для противоположной оси.
Заметка: Работает только когда высота контейнера фиксированная (выше чем ряды внутри него).
Это свойство мало где нужно и вместо него чаще используется align-items (см.ниже).
Задает размер промежутка между элементами контейнера. Соответственно:
Поддержка gap
Для элементов контейнера
Задает коэффициент увеличения элемента при наличии свободного места в контейнере. По умолчанию flex-grow: 0 т.е. никакой из элементов не должен увеличиваться и заполнять свободное место в контейнере.
По умолчанию flex-grow: 0
Задает коэффициент уменьшения элемента. Свойство противоположное flex-grow и определяет как элемент должен сжиматься, если в контейнере не остается свободного места. Т.е. свойство начинает работать, когда сумма размеров всех элементов больше чем размер контейнера.
По умолчанию flex-shrink:1
По умолчанию: auto
По умолчанию: flex: 0 1 auto
Однако можно указать и одно, и два значения:
По умолчанию: от align-items контейнера
Позволяет менять порядок (позицию, положение) элемента в общем ряду.
По умолчанию: order: 0
Так можно, например, первый элемент перекинуть в конец, при этом не меняя направление движения остальных элементов или HTML код.
Заметки
Чем отличается flex-basis от width?
Ниже важные различия между flex-basis и width / height:
flex-basis работает только для главной оси. Это значит что при flex-direction:row flex-basis контролирует ширину (width), а при flex-direction:column контролирует высоту (height). Смотрите пример.
flex-basis применяется только к flex элементам. А значит если отключить flex у контейнера это свойство не будет иметь эффекта.
Примеры Flex верстки
В примерах нигде не используются префиксы для кроссбраузерности. Сделал я так для удобного чтения css. Поэтому примеры смотрите в последних версиях Chrome или Firefox.
#1 Простой пример с выравниванием по вертикали и горизонтали
Или так, без блока внутри:
#1.2 Разделение (разрыв) между элементами флекс блока
#2 Адаптивное меню на flex
Сделаем меню в самом верху страницы. На широком экране оно должно быть справа. На среднем выравниваться по середине. А на маленьком каждый элемент должен быть на новой строке.
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#3 Адаптивные 3 колонки
Этот пример показывает как быстро и удобно сделать 3 колонки, которые при сужении будут превращаться в 2 и затем в 1.
Обратите внимание, что сделать это можно без использования media правил, все на flex.
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#4 Адаптивные блоки на flex
Допустим нам нужно вывести 3 блока, один большой и два маленьких. При этом нужно чтобы блоки подстраивались под маленькие экраны. Делаем:
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#5 Галерея на flex и transition
Этот пример показывает как быстро можно сделать симпатичный аккордеон с картинками на flex. Обратите внимание на свойство transition для flex.
#6 Флекс во флекс (просто пример)
Задача сделать гибкий блок. Так чтобы начало текста в каждом блоке находилось на одной линии по горизонтали. Т.е. при сужении ширины, блоки растут в высоту. Нужно, чтобы картинка была вверху, кнопка всегда внизу, а текст по середине начинался по одной горизонтальной линии.
Еще примеры
Полной поддержки разумеется нет, однако все современные браузеры поддерживают flexbox конструкции. Для некоторых все еще нужно указывать префиксы.
Чтобы знать какие префиксы актуальны на сегодня (июнь. 2019), приведу пример всех flex правил с нужными префиксами:
Лучше если свойства с префиксами будут идти до оригинального свойства.
В этом списке нет ненужных на сегодня (по caniuse) префиксов, но вообще префиксов больше.
Видео
Ну и не забывайте про видео, там порой тоже интересно и понятно. Вот парочка популярных:
Полезные ссылки по Flex
Flexbox
Это новая технология, которая уже имеет достаточно широкую поддержку браузеров. Flexbox предоставляет инструменты для быстрого создания сложных, гибких макетов, и функции, которые были сложны в традиционных методах CSS. В этой статье объясняются все основы данной технологии.
| Необходимые навыки: | HTML основы (изучите Введение в HTML), знание того, как работает CSS (изучите Вступление в CSS). |
|---|---|
| Цель: | Узнать, как использовать систему адаптируемых блоков Flexbox для создания веб-макетов. |
Почему Flexbox?
Долгое время единственными надёжными инструментами CSS вёрстки были такие способы как Float (обтекание) и позиционирование.
С их помощью сложно или невозможно достичь следующих простых требований к макету:
Как вы увидите в последующих разделах, flexbox значительно облегчает работу с макетами. Погружаемся!
Разберём простой пример
В этой статье вы проработаете серию упражнений, которые помогут понять, как работает flexbox. Чтобы начать, скачайте на компьютер стартовый файл — flexbox0.html с нашего Github репозитория — загрузите его в современном браузере (Firefox или Chrome), а также в любимом редакторе кода. Также вы можете посмотреть его вживую.
Определяем, какие элементы разместить в виде flex блоков
В результате у нас получится вот так:
Так, всего одно объявление делает всё, что нам нужно — здорово, правда? Мы получили 3-х колоночный макет с колонками равных размеров по ширине и высоте. Это связано с тем, что значения по умолчанию, заданные для flex элементов (дочерние элементы flex контейнера), настроены для решения основных задач. Подробнее об этом позже.
Примечание: вы также можете установить значение display inline-flex, если хотите расставить inline элементы как flex блоки.
Внутри flex модели
Когда элементы выложены как flex блоки, они располагаются вдоль двух осей:
Запомните эти термины, они пригодятся вам в последующих разделах.
Столбцы или строки?
Попробуйте добавить следующую строчку в ваш файл:
Вы увидите, что элементы расположились в виде столбцов, также как было до того, как мы добавили CSS код. Прежде чем продолжать, удалите эту строчку из примера.
Перенос строк
Проблема может быть в том, что, если у вас фиксированная ширина или высота макета, ваши flexbox элементы переполнят контейнер и нарушат макет. Посмотрите на этот пример: flexbox-wrap0.html и посмотрите его вживую (сохраните его себе на компьютер, если хотите изучить этот пример):
Попробуйте, и вы увидите, что так макет стал выглядеть гораздо лучше:
Но мы можем пойти дальше. Прежде всего, попробуйте изменить значение свойства flex-direction на row-reverse — теперь у вас также макет в несколько строк, но он начинается из противоположного угла окна браузера и теперь выстраивается в обратном порядке.
flex-flow сокращение
Гибкое изменение размеров flex элементов
Теперь давайте вернёмся к нашему первому примеру и посмотрим, как мы можем контролировать, в каких пропорциях flex элементы будут занимать место. Включите свою копию файла flexbox0.html, или скачайте flexbox1.html (просмотр).
Прежде всего, добавим следующее правило в конец вашего CSS кода:
Это безразмерное значение пропорции, которое указывает, сколько свободного пространства на главной оси (main axis) каждый flex элемент сможет занять. В этом случае, мы даём каждому элементу значение 1, а это значит, что они будут занимать равное количество свободного места в макете, которое осталось после установки свойств padding и margin.
Теперь добавьте следующее правило в строку после предыдущего:
Вы также можете указать минимальный размер внутри значения flex. Попробуйте изменить существующие правила, добавив размеры:
Это просто означает, что каждому flex элементу сначала будет дано 200px от свободного места. Потом оставшееся место будет поделено в соответствии с частями пропорций. Обновите страницу, и вы увидите разницу, как пространство поделено теперь.
flex: краткий код против развёрнутого
flex это сокращённое свойство, в которым можно задать до трёх разных свойств:
Мы не советуем использовать развёрнутые свойства flex, если вам в действительности это не нужно (например, переопределить ранее установленное). Они приводят к написанию большого количества дополнительного кода и могут запутать кого угодно.
Горизонтальное и вертикальное выравнивание
Flexbox также имеет функции для выравнивания flex элементов вдоль основной (main) или поперечной (cross) осей. Рассмотрим их на новом примере — flex-align0.html (просмотр) — который мы превратим в аккуратную, гибкую кнопочную панель инструментов. На данный момент вы видите горизонтальную панель меню, кнопки которой застряли в верхнем левом углу.
Сначала сделайте себе копию этого примера.
Теперь добавьте следующую строку в низ кода CSS:
Обновите страницу, и вы увидите, что кнопки теперь хорошо центрированы, горизонтально и вертикально. Мы сделали это с помощью двух новых свойств.
align-items контролирует, где на поперечной оси находятся flex элементы.
Вы можете переопределить align-items поведение для отдельных flex элементов, применив свойство align-self к ним. Например, попробуйте добавить эти строки в код:
Посмотрите, что произошло и удалите эти строки.
justify-content контролирует, где flex элементы располагаются на главной оси.
Попробуйте немного поиграть с этими значениями прежде чем продолжить
Порядок элементов flex
В Flexbox также есть возможность менять порядок расположения flex элементов, не влияя на исходный порядок. Это ещё одна вещь, которую невозможно сделать традиционными методами CSS.
Код здесь простой: попробуйте добавить следующий CSS вниз вашего кода примера:
и теперь вы увидите, что кнопка «Smile» переместилась в конец главной оси. Давайте теперь поговорим подробнее о том, как это работает:
Вложенные flex блоки
Можно создать несколько довольно сложных макетов с помощью flexbox. Совершенно нормально сделать flex элемент flex контейнером, чтобы его потомки также были flex блоками. Посмотрите на complex-flexbox.html (см. вживую).
Давайте посмотрим на код, который мы использовали для макета.
Прежде всего, мы устанавливаем дочерние элементы в виде flex блоков.
Затем мы берём первый
Наконец, мы устанавливаем размер кнопке, мы даём ему значение flex 1. Это даёт очень интересный эффект, который вы увидите, если попытаетесь изменить размер ширины окна браузера. Кнопки занимают столько места, сколько могут, и сидят на одной линии также, сколько могут. Если же они не могут комфортно расположиться на одной линии, они перепрыгнут на новые строки.
Совместимость с браузерами
Поддержка Flexbox доступна в большинстве новых браузеров: Firefox, Chrome, Opera, Microsoft Edge и IE 11, более поздних версиях Android / iOS и т. д.. Однако помните, что до сих пор используются более старые браузеры, которые не поддерживают Flexbox ( или поддерживают, но старую версию.)
Пока вы просто учитесь и экспериментируете, это не имеет большого значения. Однако, если вы рассматриваете возможность использования flexbox на реальном веб-сайте, вам необходимо провести тестирование и убедиться, что ваш пользовательский интерфейс по-прежнему приемлем в максимально возможном количестве браузеров.
Flexbox немного сложнее, чем некоторые функции CSS. Например, если в браузере отсутствует поддержка CSS тени, сайт по-прежнему будет можно использовать. А вот неподдерживаемые функции flexbox, возможно, полностью сломают макет, что сделает сайт непригодным.
Мы обсудим возможности преодоления проблем поддержки кросс-браузерности в следующем модуле.
Подытожим
Что такое Flexbox? Описание всех css свойств, основные принципы, преимущества и недостатки.
Flexbox по праву можно назвать удачной попыткой решения огромного спектра проблем при построении лейаутов в css. Но прежде чем перейти к его описанию, давайте выясним, что же не так со способами верстки, которыми мы пользуемся сейчас?
Любой верстальщик знает несколько путей выровнять что-либо по вертикали или сделать 3-х колоночный макет с резиновой средней колонкой. Но давайте признаем, что все эти способы довольно странные, похожи на хак, подходят не во всех случаях, сложны для восприятия и не работают при несоблюдении определенных магических условий, которые сложились исторически.
Случилось так потому, что html и css развивались эволюционно. В начале веб-страницы были похожи на однопоточные текстовые документы, чуть позже разбиение страницы на блоки делали таблицами, затем стало модным верстать float-ами, а после официальной смерти ie6 добавились еще и приемы с inline-block. В итоге мы получили в наследство гремучую смесь всех этих приемов, используемую для построения лейаутов 99,9% всех существующих веб-страниц.
Спецификация CSS Flexible Box Layout Module (в народе Flexbox) призвана кардинально изменить ситуацию в лучшую сторону при решении огромного количества задач. Flexbox позволяет контролировать размер, порядок и выравнивание элементов по нескольким осям, распределение свободного места между элементами и многое другое.
Основные преимущества flexbox
Поддержка браузерами
Немного истории
Мы будем рассматривать все примеры на основе новой спецификации. Если вам нужна поддержка старых Сhrome, FF и IE10, лучше использовать autoprefixer от Андрея Ситника, который автоматически добавит css правила и вендорные префиксы для устаревших спецификаций.
Начинаем погружение
Основные свойства flex-контейнера. Главная и поперечная ось.
Одним из основных понятий в fleхbox являются оси.
flex-direction – направление главной оси
Доступные значения flex-direction:
justify-content – выравнивание по главной оси.
Css свойство justify-content определяет то, как будут выровнены элементы вдоль главной оси.
Доступные значения justify-content:
align-items – выравнивание по поперечной оси.
Css свойство align-items определяет то, как будут выровнены элементы вдоль поперечной оси.
Доступные значения align-items:
Демо основных свойств flex-контейнера
Оси и выравнивания по ним – это основы flex. Расслабьтесь, покликайте по демке и используйте ее, если нужно будет освежить в памяти.
Многострочная организация блоков внутри flex-контейнера.
flex-wrap
Доступные значения flex-wrap:
flex-flow – удобное сокращение для flex-direction + flex-wrap
align-content
Важно: align-content работает только в многострочном режиме (т.е. в случае flex-wrap:wrap; или flex-wrap:wrap-reverse; )
Доступные значения align-content:
СSS свойства flex-wrap и align-content должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.
Демо свойств многострочности в flex
CSS правила для дочерних элементов flex-контейнера (flex-блоков)
flex-basis – базовый размер отдельно взятого flex-блока
flex-grow – “жадность” отдельно взятого flex-блока
Определяет то, на сколько отдельный flex-блок может быть больше соседних элементов, если это необходимо. flex-grow принимает безразмерное значение ( по умолчанию 0 )
Пример 1:
Пример 2:
Т.е абсолютное значение flex-grow не определяет точную ширину. Оно определяет его степень “жадности” по отношению к другим flex-блокам того же уровня.
flex-shrink – фактор “сжимаемости” отдельно взятого flex-блока
flex – короткая запись для свойств flex-grow, flex-shrink и flex-basis
Демо для flex-grow, flex-shrink и flex-basis
align-self – выравнивание отдельно взятого flex-блока по поперечной оси.
Делает возможным переопределять свойство flex-контейнера align-items для отдельного flex-блока.
Доступные значения align-self (те же 5 вариантов, что и для align-items )
order – порядок следования отдельно взятого flex-блока внутри flex-контейнера.
Значение order не задает абсолютную позицию элемента в последовательности. Оно определяет вес позиции элемента.
В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: item5, item1, item3, item4, item2
Демо для align-self и order
margin: auto по вертикали. Мечты сбываются!
Flexbox можно любить хотя бы за то, что привычное всем выравнивание по горизонтали через margin:auto здесь работает и для вертикали!
Вещи, которые следует помнить
В заключение
Я думаю, что flexbox, конечно же, не вытеснит все остальные способы верстки, но, безусловно, в ближайшее время займет достойную нишу при решении огромного количества задач. И уж точно, пробовать работать с ним нужно уже сейчас. Одна из следующих статей будет посвящена конкретным примерам работы с flex-версткой. Подписывайтесь на новости 😉





































