Свойство align-content задаёт тип выравнивания строк внутри flex контейнера по поперечной оси при наличии свободного пространства.
Применяется к : flex контейнеру.
Значение по умолчанию : stretch.
Flex-start Строки располагаются в начале поперечной оси. Каждая следующая строка идёт вровень с предыдущей. flex-end Строки располагаются начиная с конца поперечной оси. Каждая предыдущая строка идёт вровень со следующей. center Строки располагаются по центру контейнера. space-between Строки равномерно распределяются в контейнере и расстояние между ними одинаково. space-around Строки равномерно распределяются таким образом, чтобы пространство между двумя соседними строками было одинаковым. Пустое пространство перед первой строкой и после последней строки равно половине пространства между двумя соседними строками. space-evenly Строки распределяются равномерно. Пустое пространство перед первой строкой и после последней строки имеет ту же ширину, что и у других строк. stretch Строки равномерно растягиваются, заполняя свободное пространство.
The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis. Note, this property has no effect on a single-line flex container. Values have the following meanings:
Note: Only multi-line flex containers ever have free space in the cross-axis for lines to be aligned in, because in a single-line flex container the sole line automatically stretches to fill the space.
Applies to : flex containers.
Initial : stretch.
Flex-start Lines are packed toward the start of the flex container. The cross-start edge of the first line in the flex container is placed flush with the cross-start edge of the flex container, and each subsequent line is placed flush with the preceding line. flex-end Lines are packed toward the end of the flex container. The cross-end edge of the last line is placed flush with the cross-end edge of the flex container, and each preceding line is placed flush with the subsequent line. center Lines are packed toward the center of the flex container. The lines in the flex container are placed flush with each other and aligned in the center of the flex container, with equal amounts of space between the cross-start content edge of the flex container and the first line in the flex container, and between the cross-end content edge of the flex container and the last line in the flex container. (If the leftover free-space is negative, the lines will overflow equally in both directions.) space-between Lines are evenly distributed in the flex container. If the leftover free-space is negative this value is identical to flex-start. Otherwise, the cross-start edge of the first line in the flex container is placed flush with the cross-start content edge of the flex container, the cross-end edge of the last line in the flex container is placed flush with the cross-end content edge of the flex container, and the remaining lines in the flex container are distributed so that the spacing between any two adjacent lines is the same. space-around Lines are evenly distributed in the flex container, with half-size spaces on either end. If the leftover free-space is negative this value is identical to center. Otherwise, the lines in the flex container are distributed such that the spacing between any two adjacent lines is the same, and the spacing between the first/last lines and the flex container edges is half the size of the spacing between flex lines. space-evenly Lines are evenly distributed in the flex container. If the leftover free-space is negative this value is identical to center. Otherwise, the lines in the flex container are distributed such that the spacing between every flex line is the same. stretch Lines stretch to take up the remaining space. If the leftover free-space is negative, this value is identical to flex-start. Otherwise, the free-space is split equally between all of the lines, increasing their cross size.
На примере формы из реального тестового задания, я покажу вам, как верстать по БЭМ , используя flexbox . Вы спросите: "Почему обязательно верстать по БЭМ + Flexbox ?" Это требование исходит от работодателя. Цитата из ТЗ: "Старайтесь верстать без фреймворков (желательно на flexbox ), просто и понятно: избегайте громоздких конструкций и лишнего кода, используйте методологию БЭМ ."
Фрагмент макета секции с формой
Мои правила верстки
- Разделить макет на логические секции
- Каждую секцию начинать с тега section
- Отделять секции и CSS правили друг от друга, пустой строкой
- Каждому тегу присвоить класс
- Название класса для блока или элемента, отвечает на вопрос - Что это ?
- Имя модификатора отвечает на вопрос - Какой ?
HTML разметка
Сначала я делаю разметку, определяю вложенность блоков и придумываю названия классам. В представленном ниже коде, у нас имеются два строчных тега - h2 и input . Строчные теги - это головная боль и причина стресса, у начинающих верстальщиков. Почему? Они очень плохо себя ведут - пытаются занять всю доступную ширину, не дают установить цвет фона и размеры у всего блока.
Личная информация
Что в таком случае делает плохой верстальщик? Он оборачивает строчные элементы в блочные теги div и все нужные свойства задаёт тегу обертке. Дочерние строчные элементы, наследуют эти свойства. А стоит ли городить огород из лишнего кода? Как поступит грамотный верстальщик? Он переопределит строчный элемент в блочный или строчно-блочный, в CSS правилах.
Display: block; // для тега input
display: inline-block; // для тега h2
Логика вложенности и названия блоков
Мы видим секцию с личной информацией, так и называем класс секции - info . Секция состоит из трех дочерних элементов:
Иконка // название класса info__icon
заголовок // info__title
форма // info__form
Суть в названии классов по БЭМ , состоит в принадлежности дочернего элемента к родителю. Нельзя назвать элемент, icon . Это не просто какая-то иконка, а иконка из секции info .
Дочка и родитель в одном лице
Блок info__form , у нас особенный - он вложен в секцию info , но в тоже время, содержит поля формы. Название этому явлению - многоуровневая вложенность. Блок с формой, несет чисто оберточную функцию для инпутов, чтобы легко можно было задать внешние отступы. Ведь строчные инпуты ведут себя, как дети (кем они и являются), совсем не слушаются. Причем второй инпут, короче всех остальных и отличается только шириной.
Задаем один класс для всех инпутов с одинаковыми свойствами, кроме ширины - info__input . Обычным инпутам, добавим модификатор info__input_long , а короткому инпуту - модификатор info__input_short . Напомню, что модификатор по БЭМ , должен отвечать на вопрос - Какой ?
CSS правила для модификаторов
.info__input_long {width: 520px;
}
Info__input_short {
width: 320px;
}
CSS код
В HTML разметке создается грубая структура сайта, в CSS , мы уже размещаем элементы, согласно макету. Сегодня, мы не будем касаться внешнего вида, а сосредоточимся на позиционировании элементов. В нашей секции, два флексовых контейнера. Надо сказать, что использование флексов, при расположении всех элементов по одному в строке, очень сомнительно. Единственная получаемая польза - это свойство justify-content , выравнивающее по центру, флекс элементы. Могу сказать в своё оправдание, что, затея с флексами бессмысленная, в контексте только этой секции. Настоящий макет для верстки, обычно имеет больше разнообразия.
Info {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-top: 77px;
height: 100%;
}
Info__form {
display: flex;
justify-content: center;
flex-direction: column;
height: 100%;
margin-top: 50px;
Flexbox по праву можно назвать удачной попыткой решения огромного спектра проблем при построении лейаутов в css. Но прежде чем перейти к его описанию, давайте выясним, что же не так со способами верстки, которыми мы пользуемся сейчас?
Любой верстальщик знает несколько путей выровнять что-либо по вертикали или сделать 3-х колоночный макет с резиновой средней колонкой. Но давайте признаем, что все эти способы довольно странные, похожи на хак, подходят не во всех случаях, сложны для восприятия и не работают при несоблюдении определенных магических условий, которые сложились исторически.
Случилось так потому, что html и css развивались эволюционно. В начале веб-страницы были похожи на однопоточные текстовые документы, чуть позже разбиение страницы на блоки делали таблицами, затем стало модным верстать float-ами, а после официальной смерти ie6 добавились еще и приемы с inline-block. В итоге мы получили в наследство гремучую смесь всех этих приемов, используемую для построения лейаутов 99,9% всех существующих веб-страниц.
Многострочная организация блоков внутри flex-контейнера.
flex-wrap
Все примеры, которые мы приводили выше, были построены с учетом однострочного (одностолбцового) расположения блоков. Надо сказать, что по умолчанию flex-контейнер всегда будет располагать блоки внутри себя в одну линию. Однако, спецификацией также поддерживается многострочный режим. За многострочность внутри flex-контейнера отвечает CSS свойство flex-wrap .
Доступные значения flex-wrap :
- nowrap (значение по умолчанию) : блоки расположены в одну линию слева направо (в rtl справа налево)
- wrap: блоки расположены в несколько горизонтальных рядов (если не помещаются в один ряд). Они следуют друг за другом слева направо (в rtl справа налево)
- wrap-reverse: то-же что и wrap , но блоки располагаются в обратном порядке.
flex-flow – удобное сокращение для flex-direction + flex-wrap
По сути, flex-flow предоставляет возможность в одном свойстве описать направление главной и многострочность поперечной оси. По умолчанию flex-flow: row nowrap .
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
CSS
/* т.е. ... */ .my-flex-block{ flex-direcrion:column; flex-wrap: wrap; } /* это то же самое, что... */ .my-flex-block{ flex-flow: column wrap; }align-content
Существует также свойство align-content , которое определяет то, каким образом образовавшиеся ряды блоков будут выровнены по вертикали и как они поделят между собой все пространство flex-контейнера.
Важно: align-content работает только в многострочном режиме (т.е. в случае flex-wrap:wrap; или flex-wrap:wrap-reverse;)
Доступные значения align-content :
- flex-start: ряды блоков прижаты к началу flex-контейнера.
- flex-end: ряды блоков прижаты к концу flex-контейнера
- center: ряды блоков находятся в центре flex-контейнера
- space-between: первый ряд блоков располагается в начале flex-контейнера, последний ряд блоков блок – в конце, все остальные ряды равномерно распределены в оставшемся пространстве.
- space-around: ряды блоков равномерно распределены в от начала до конца flex-контейнера, разделяя все свободное пространство поровну.
- stretch (значение по умолчанию) : Ряды блоков растянуты, дабы занять все имеющееся пространство.
СSS свойства flex-wrap и align-content должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.
Демо свойств многострочности в flex
CSS правила для дочерних элементов flex-контейнера (flex-блоков)
flex-basis – базовый размер отдельно взятого flex-блока
Задает изначальный размер по главной оси для flex-блока до того, как к нему будут применены преобразования, основанные на других flex-факторах. Может быть задан в любых единицах измерения длинны (px , em , % , …) или auto (по умолчанию). Если задан как auto – за основу берутся размеры блока (width, height), которые, в свою очередь, могут зависеть от размера контента, если не указанны явно.
flex-grow – “жадность” отдельно взятого flex-блока
Определяет то, на сколько отдельный flex-блок может быть больше соседних элементов, если это необходимо. flex-grow принимает безразмерное значение (по умолчанию 0)
Пример 1 :
- Если все flex-блоки внутри flex-контейнера имеют flex-grow:1 , то они будут одинакового размера
- Если один из них имеет flex-grow:2 , то он будет в 2 раза больше, чем все остальные
Пример 2 :
- Если все flex-блоки внутри flex-контейнера имеют flex-grow:3 , то они будут одинакового размера
- Если один из них имеет flex-grow:12 , то он будет в 4 раза больше, чем все остальные
Т.е абсолютное значение flex-grow не определяет точную ширину. Оно определяет его степень “жадности” по отношению к другим flex-блокам того же уровня.
flex-shrink – фактор “сжимаемости” отдельно взятого flex-блока
Определяет, насколько flex-блок будет уменьшаться относительно соседних эдементов внутри flex-контейнера в случае недостатка свободного места. По умолчанию равен 1 .
flex – короткая запись для свойств flex-grow, flex-shrink и flex-basis
flex: none | [ <"flex-grow"> <"flex-shrink">? || <"flex-basis"> ]
CSS
/* т.е. ... */ .my-flex-block{ flex-grow:12; flex-shrink:3; flex basis: 30em; } /* это то же самое, что... */ .my-flex-block{ flex: 12 3 30em; }Демо для flex-grow, flex-shrink и flex-basis
align-self – выравнивание отдельно взятого flex-блока по поперечной оси.
Делает возможным переопределять свойство flex-контейнера align-items для отдельного flex-блока.
Доступные значения align-self (те же 5 вариантов, что и для align-items)
- flex-start: flex-блок прижат к началу поперечной оси
- flex-end: flex-блок прижат к концу поперечной оси
- center: flex-блок располагаются в центре поперечной оси
- baseline: flex-блок выравнен по baseline
- stretch (значение по умолчанию) : flex-блок растянут, чтобы занять все доступное место по поперечной оси, при этом учитываются min-width / max-width , если таковые заданы.
order – порядок следования отдельно взятого flex-блока внутри flex-контейнера.
По умолчанию все блоки будут следовать друг за другом в порядке, заданном в html. Однако этот порядок можно изменить с помощью свойства order . Оно задается целым числом и по умолчанию равно 0 .
Значение order не задает абсолютную позицию элемента в последовательности. Оно определяет вес позиции элемента.
HTML
В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: item5, item1, item3, item4, item2
Демо для align-self и order
margin: auto по вертикали . Мечты сбываются!
Flexbox можно любить хотя бы за то, что привычное всем выравнивание по горизонтали через margin:auto здесь работает и для вертикали!
My-flex-container { display: flex; height: 300px; /* Или что угодно */ } .my-flex-block { width: 100px; /* Или что угодно */ height: 100px; /* Или что угодно */ margin: auto; /* Магия! Блок отцентрирован по вертикали и горизонтали! */ }
Вещи, которые следует помнить
- Не следует использовать flexbox там, где в этом нет необходимости.
- Определение регионов и изменение порядка контента во многих случаях все-таки полезно делать зависимым от структуры страницы. Продумывайте это.
- Разберитесь в flexbox и знайте его основы. Так намного легче достичь ожидаемого результата.
- Не забывайте про margin-ы. Они учитываются при установке выравнивания по осям. Также важно помнить, что margin-ы в flexbox не “коллапсятся”, как это происходит в обычном потоке.
- Значение float у flex-блоков не учитывается и не имеет значения. Это, наверно, как-то можно использовать для graceful degradation при переходе на flexbox.
- flexbox очень хорошо подходит для верстки веб-компонентов и отдельных частей веб-страниц, но показал себя не с лучшей стороны при верстке базовых макетов (расположение article, header, footer, navbar и т.п.). Это все еще спорный момент, но эта статья довольно убедительно показывает недостатки xanthir.com/blog/b4580
В заключение
Я думаю, что flexbox, конечно же, не вытеснит все остальные способы верстки, но, безусловно, в ближайшее время займет достойную нишу при решении огромного количества задач. И уж точно, пробовать работать с ним нужно уже сейчас. Одна из следующих статей будет посвящена конкретным примерам работы с flex-версткой. Подписывайтесь на новости;)
Флексбоксы идеально подходят для создания широко используемых макетов веб-сайтов, вроде трёхколоночного, так называемый макет «Святой Грааль», где все колонки должны занимать полную высоту, независимо от их содержимого. При этом в исходном коде основное содержимое идёт до навигации, а на самой странице основное содержимое идёт после навигации.
Вроде этого.
До появления флексбоксов такой макет было довольно трудно получить без использования каких-либо хаков. Разработчикам часто приходилось делать такие вещи, как добавление дополнительной разметки, применение отрицательных margin и другие трюки, чтобы всё правильно выстраивалось независимо от объёма содержимого или размера экрана. Но, как показывает приведённый выше пример, на флексбоксах всё получается гораздо проще.
Вот краткое изложение кода. В данном примере мы делаем элемент #main флекс-контейнером, а шапку и подвал оставляем блочными элементами. Другими словами, флексбоксом становится только средняя часть. Вот фрагмент, который делает её флекс-контейнером.
#main { display: flex; min-height: calc(100vh - 40vh); }
Просто используем display: flex , чтобы сделать флекс-контейнер. Обратите внимание, мы также задаём значение min-height с помощью функции calc() и устанавливаем #main как 100% от высоты области просмотра минус высота шапки и подвала (по 20vh каждый). Это гарантирует, что макет будет занимать всю высоту экрана, даже если в нём мало содержимого. В итоге подвал никогда не поднимется и не оставит пустого пространства под ним, если содержимое занимает меньше высоты экрана.
Вычисление min-height было достаточно простым, учитывая, что мы применили box-sizing: border-box ко всем элементам. Если бы мы этого не сделали, тогда нужно было бы добавить значение padding к сумме для вычитания.
После установки флекс-контейнера мы имеем дело с флекс-элементами.
#main > article { flex: 1; } #main > nav, #main > aside { flex: 0 0 20vw; background: beige; } #main > nav { order: -1; }
Свойство flex является сокращением для свойств flex-grow , flex-shrink и flex-basis . В первом случае мы написали только одно значение, поэтому flex устанавливает свойство flex-grow . Во втором случае мы написали все три значения для
Если говорить коротко, то верстка с Flexbox дает нам простые решения некогда непростых задач. Например, когда нужно выровнять элемент по вертикали, или прижать подвал к низу экрана, или просто вставить несколько блоков в один ряд, так чтобы они занимали все свободно пространство. Подобные задачи решаются и без flex. Но как правило, эти решения больше похожи на «костыли» - приемы использовать css не по назначению. Тогда как с flexbox такие задачи решаются именно так, как задумывает flex-модель.
CSS Flexible Box Layout Module (CSS модуль для макетов с гибкими блоками), коротко flexbox, создана, чтобы убрать недостатки при создании самых разных HTML конструкций, в том числе адаптированных под разную ширину и высоту, и сделать верстку логичной и простой. А логичный подход, как правило работает в неожиданных местах, там где результат не проверялся - логика наше все!
Flexbox позволяет элегантно контролировать самые разные параметры элементов внутри контейнера: направление, порядок, ширину, высоту, выравнивание вдоль и поперек, распределение свободного места, растяжение и сжатие элементов.
Базовые знания
FlexBox состоит из Контейнера и его Дочерних элементов (items) (гибких элементов).
Для включения flexbox, любому HTML элементу достаточно присвоить css свойство display:flex; или display:inline-flex; .
После включения flex свойства, внутри контейнера создаются две оси: главная и поперечная (перпендикулярная (⊥), кросс ось). Все вложенные элементы (первого уровня) выстраиваются по главной оси. По умолчанию главная ось горизонтальная и имеет направление слева направо (→), а кросс ось соответственно вертикальная и направлена сверху вниз (↓).
Главную и кросс оси можно поменять местами, тогда элементы будут располагаться сверху вниз (↓) и когда перестанут вмещаться в высоту то будут двигаться слева направо (→) - то есть оси просто поменялись местами. При этом начало и конец расположения элементов не меняется - меняются только направления (оси)! Именно поэтому нужно представлять себе оси внутри контейнера. Однако не нужно думать, что есть какие-то там «физические» оси и они на что-то влияют. Ось тут - это только лишь направление движения элементов внутри контейнера. Например, если мы указали выравнивание элементов по центру основной оси и потом изменили направление этой основной оси, то изменится и выравнивание: элементы были в середине по горизонтали, а стали в середине по вертикали... См. пример.
Еще одной важной особенностью Флекс-бокс является наличие рядов в поперечном направлении. Чтобы понять о чем речь, давайте представим что есть главная горизонтальная ось, много элементов и они не «лезут» в контейнер, поэтому переходят на другой ряд. Т.е. контейнер выглядит так: контейнер, внутри него два ряда, в каждом ряду по несколько элементов. Представили? А теперь запомните, что выравнивать по вертикали мы можем не только элементы, но и ряды! Как это работает хорошо видно в примере к свойству . А вот так это выглядит схематически:
CSS свойства, которые могут влиять на модель построения макета: float , clear , vertical-align , columns не работают во flex конструкции. Тут используется другая модель построения макета и эти css свойства просто игнорируются.
CSS свойства Flexbox
Flexbox содержит разные css правила для управления всей flex конструкцией. Одни нужно применять к основному контейнеру, а другие к элементам этого контейнера.
Для контейнера
display:Включает flex свойство для элемента. Под это свойство попадает сам элемент и вложенные в него элементы: затрагиваются только потомки первого уровня - они станут элементами flex контейнера.
- flex - элемент растягивается на всю ширину и имеет свое полное пространство среди окружающих блоков. Происходит перенос строк в начале и в конце блока.
- inline-flex - элемент обтекается другими элементами. При этом его внутренняя часть форматируется как блочный элемент, а сам элемент - как встроенный.
flex и inline-flex отличаются тем что по-разному взаимодействуют с окружающими элементами, подобно display:block и display:inline-block .
flex-direction:Изменяет направление главной оси контейнера. Поперечная ось меняется соответственно.
- row (default) - направление элементов слева направо (→)
- column - направление элементов сверху вниз (↓)
- row-reverse - направление элементов справа налево (←)
- column-reverse - направление элементов снизу вверх ()
Управляет переносом непомещающихся в контейнер элементов.
- nowrap (default) - вложенные элементы располагаются в один ряд (при direction=row) или в одну колонку (при direction=column) независимо от того помещаются они в контейнер или нет.
- wrap - включает перенос элементов на следующий ряд, если они не помещаются в контейнер. Так включается движение элементов по поперечной оси.
- wrap-reverse - тоже что wrap только перенос будет не вниз, а вверх (в обратном направлении).
Объединяет оба свойства flex-direction и flex-wrap . Они часто используются вместе, поэтому чтобы писать меньше кода было создано свойство flex-flow .
flex-flow принимает значения двух этих свойств, разделенные пробелом. Или можно указать одно значение любого свойства.
/* только flex-direction */ flex-flow: row; flex-flow: row-reverse; flex-flow: column; flex-flow: column-reverse; /* только flex-wrap */ flex-flow: nowrap; flex-flow: wrap; flex-flow: wrap-reverse; /* сразу оба значения: flex-direction и flex-wrap */ flex-flow: row nowrap; flex-flow: column wrap; flex-flow: column-reverse wrap-reverse; justify-content:
Выравнивает элементы по основной оси: если direction=row, то по горизонтали, а если direction=column, то по вертикали.
- flex-start (default) - элементы будут идти с начала (в конце может остаться место).
- flex-end - элементы выравниваются по концу (место останется в начале)
- center - по центру (место останется слева и права)
- space-between - крайние элементы прижимаются к краям (место между элементами распределяется равномерно)
- space-around - свободное пространство равномерно распределяется между элементами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
- space-evenly
Выравнивает ряды, в которых находятся элементы по поперечной оси. То же что justify-content только для противоположной оси.
Заметка: Работает когда есть как минимум 2 ряда, т.е. при наличии только 1 ряда ничего не произойдет.
Т.е. если flex-direction: row , то это свойство будет выравнивать невидимые ряды по вертикали ¦ . Тут важно заметить, что высота блока должна быть задана жестко и должна быть больше высоты рядов иначе сами ряды будут растягивать контейнер и любое их выравнивание теряет смысл, потому что между ними нет свободного места... А вот когда flex-direction: column , то ряды движется по горизонтали → и ширина контейнера почти всегда больше ширины рядов и выравнивание рядов сразу приобретает смысл...
- stretch (default) - ряды растягиваются заполняя строку полностью
- flex-start - ряды группируются в верхней части контейнера (в конце может остаться место).
- flex-end - ряды группируются в нижней части контейнера (место останется в начале)
- center - ряды группируются по центру контейнера (место останется по краям)
- space-between - крайние ряды прижимаются к краям (место между рядами распределяется равномерно)
- space-around - свободное пространство равномерно распределяется между рядами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
- space-evenly - тоже что space-around , только расстояние у крайних элементов до краев контейнера такое же как и между элементами.
Выравнивает элементы по поперечной оси внутри ряда (невидимой строки). Т.е. сами ряды выравниваются через align-content , а элементы внутри этих рядов (строк) через align-items и все это по поперечной оси. По главной оси такого разделения нет, там нет понятия рядов и элементы выравниваются через justify-content .
- stretch (default) - элементы растягиваются заполняя строку полностью
- flex-start - элементы прижимаются к началу ряда
- flex-end - элементы прижимаются к концу ряда
- center - элементы выравниваются по центру ряда
- baseline - элементы выравниваются по базовой линии текста
Для элементов контейнера
flex-grow:Задает коэффициент увеличения элемента при наличии свободного места в контейнере. По умолчанию flex-grow: 0 т.е. никакой из элементов не должен увеличиваться и заполнять свободное место в контейнере.
По умолчанию flex-grow: 0
- Если всем элементам указать flex-grow:1 , то все они растянуться одинаково и заполнять все свободное место в контейнере.
- Если одному из элементов указать flex-grow:1 , то он заполнит все свободное место в контейнере и выравнивания через justify-content работать уже не будут: свободного места нет выравнивать нечего...
- При flex-grow:1 . Если один из них имеет flex-grow:2, то он будет в 2 раза больше, чем все остальные
- Если все flex-блоки внутри flex-контейнера имеют flex-grow:3 , то они будут одинакового размера
- При flex-grow:3 . Если один из них имеет flex-grow:12 , то он будет в 4 раза больше, чем все остальные
Как это работает? Допустим, что контейнер имеет ширину 500px и содержит два элемента, каждый из которых имеет базовую ширину 100px. Значит в контейнере остается 300 свободных пикселей. Теперь, если первому элементу укажем flex-grow:2; , а второму flex-grow: 1; , то блоки займут всю доступную ширину контейнера и ширина первого блока будет 300px, а второго 200px. Объясняется это тем, что доступные 300px свободного места в контейнере распределились между элементами в соотношении 2:1, +200px первому и +100px второму.
Заметка: в значении можно указывать дробные числа, например: 0.5 - flex-grow:0.5
flex-shrink:Задает коэффициент уменьшения элемента. Свойство противоположное flex-grow и определяет как элемент должен сжиматься, если в контейнере не остается свободного места. Т.е. свойство начинает работать, когда сумма размеров всех элементов больше чем размер контейнера.
По умолчанию flex-shrink:1
Допустим, что контейнер имеет ширину 600px и содержит два элемента, каждый из которых имеет ширину 300px - flex-basis:300px; . Т.е. два элемента полностью заполняют контейнер. Первому элементу укажем flex-shrink: 2; , а второму flex-shrink: 1; . Теперь уменьшим ширину контейнера на 300px, т.е. элементы должны сжаться на 300px чтобы находится внутри контейнера. Сжиматься они будут в соотношении 2:1, т.е. первый блок сожмется на 200px, а второй на 100px и новые размеры элементов станут 100px и 200px.
Заметка: в значении можно указывать дробные числа, например: 0.5 - flex-shrink:0.5
flex-basis:Устанавливает базовую ширину элемента - ширину до того как будут высчитаны остальные условия влияющие на ширину элемента. Значение можно указать в px, em, rem, %, vw, vh и т.д. Итоговая ширина будет зависеть от базовой ширины и значений flex-grow, flex-shrink и контента внутри блока. При auto элемент получает базовую ширину относительно контента внутри него.
По умолчанию: auto
Иногда лучше установить ширину элемента жестко через привычное свойство width . Например, width: 50%; будет означать, что элемент внутри контейнера будет ровно 50%, однако при этом все также будут работать свойства flex-grow и flex-shrink . Такое может быть нужно, когда элемент растягивается контентом внутри него, больше указанного во flex-basis. Пример .
flex-basis будет «жестким», если обнулить растяжение и сжатие: flex-basis:200px; flex-grow:0; flex-shrink:0; . Все это можно записать так flex:0 0 200px; .
flex: {grow shrink basis}Короткая запись трех свойств: flex-grow flex-shrink flex-basis .
По умолчанию: flex: 0 1 auto
Однако можно указать и одно, и два значения:
Flex: none; /* 0 0 auto */ /* число */ flex: 2; /* flex-grow (flex-basis переходит в 0) */ /* не число */ flex: 10em; /* flex-basis: 10em */ flex: 30px; /* flex-basis: 30px */ flex: auto; /* flex-basis: auto */ flex: content; /* flex-basis: content */ flex: 1 30px; /* flex-grow и flex-basis */ flex: 2 2; /* flex-grow и flex-shrink (flex-basis переходит в 0) */ flex: 2 2 10%; /* flex-grow и flex-shrink и flex-basis */ align-self:
Позволяет изменить свойство align-items , только для отдельного элемента.
По умолчанию: от align-items контейнера
- stretch - элемент растягиваются заполняя строку полностью
- flex-start - элемент прижимаются к началу строки
- flex-end - элемент прижимаются к концу строки
- center - элемент выравниваются по центру строки
baseline - элемент выравниваются по базовой линии текста
Позволяет менять порядок (позицию, положение) элемента в общем ряду.
По умолчанию: order: 0
По умолчанию элементы имеют order: 0 и ставятся в порядке их появления в HTML коде и направления ряда. Но если изменить значение свойства order, то элементы будут выстраиваться в порядке значений: -1 0 1 2 3 ... . Например если одному из элементов указать order: 1 , то сначала будут идти все нулевые, а потом элемент с 1.
Так можно, например, первый элемент перекинуть в конец, при этом не меняя направление движения остальных элементов или HTML код.
Заметки
Чем отличается flex-basis от width?
Ниже важные различия между flex-basis и width / height:
- При использовании свойства flex 3 значения (flex-grow/flex-shrink/flex-basis) можно скомбинировать и записать коротко, а для width grow или shrink нужно писать отдельно. Например: flex:0 0 50% == width:50%; flex-shrink:0; . Иногда это просто неудобно.
flex-basis работает только для главной оси. Это значит что при flex-direction:row flex-basis контролирует ширину (width), а при flex-direction:column контролирует высоту (height). .
flex-basis применяется только к flex элементам. А значит если отключить flex у контейнера это свойство не будет иметь эффекта.
Абсолютные элементы контейнера не участвуют во flex конструкции... А значит, flex-basis не влияет на элементы flex контейнера, если они абсолютны position:absolute . Им нужно будет указать width / height.
По возможности все же отдавайте предпочтение flex-basis . Используйте width только когда не подходит flex-basis .
Отличие flex-basis от width - баг или фича?
Контент внутри flex элемента распирает его и не может выйти за его пределы. Однако если установить ширину через width или max-width , а не flex-basis , то элемент внутри flex контейнера сумеет выйти за пределы этого контейнера (иногда нужно именно такое поведение). Пример:
Примеры Flex верстки
В примерах нигде не используются префиксы для кроссбраузерности. Сделал я так для удобного чтения css. Поэтому примеры смотрите в последних версиях Chrome или Firefox.
#1 Простой пример с выравниванием по вертикали и горизонтали
Начнем с самого простого примера - выравнивание по вертикали и горизонтали одновременно и при любой высоте блока, даже резиновой.
Или так, без блока внутри:
#1.2 Разделение (разрыв) между элементами флекс блока
Чтобы расположить элементы контейнера по краям и произвольно выбрать элемент после которого будет разрыв, нужно использовать свойство margin-left:auto или margin-right:auto .
#2 Адаптивное меню на flex
Сделаем меню в самом верху страницы. На широком экране оно должно быть справа. На среднем выравниваться по середине. А на маленьком каждый элемент должен быть на новой строке.
#3 Адаптивные 3 колонки
Этот пример показывает как быстро и удобно сделать 3 колонки, которые при сужении будут превращаться в 2 и затем в 1.
Обратите внимание, что сделать это можно без использования media правил, все на flex.
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#4 Адаптивные блоки на flex
Допустим нам нужно вывести 3 блока, один большой и два маленьких. При этом нужно чтобы блоки подстраивались под маленькие экраны. Делаем:
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#5 Галерея на flex и transition
Этот пример показывает как быстро можно сделать симпатичный аккордеон с картинками на flex. Обратите внимание на свойство transition для flex.
#6 Флекс во флекс (просто пример)
Задача сделать гибкий блок. Так чтобы начало текста в каждом блоке находилось на одной линии по горизонтали. Т.е. при сужении ширины, блоки растут в высоту. Нужно, чтобы картинка была вверху, кнопка всегда внизу, а текст по середине начинался по одной горизонтальной линии...
Для решения этой задачи, сами блоки растягиваются флексом и им установлена максимально возможная ширина. Каждый внутренний блок также является флекс конструкцией, с повернутой осью flex-direction:column; и элемент в середине (где находится текст) растягивается flex-grow:1; чтобы заполнить всё свободное пространство, так достигается результат - текст начинался с одной линии...
Еще примеры
Поддержка браузерами - 98.3%
Полной поддержки разумеется нет, однако все современные браузеры поддерживают flexbox конструкции. Для некоторых все еще нужно указывать префиксы. Для реальной картины заглянем в caniuse.com и видим, что без префиксов будут работать 96.3% используемых сегодня браузеров, с префиксами 98.3%. Это отличный показатель для того чтобы смело использовать flexbox.
Чтобы знать какие префиксы актуальны на сегодня (июнь. 2019), приведу пример всех flex правил с нужными префиксами :
/* Контейнер */ .flex { display:-webkit-box; display:-ms-flexbox; display:flex; display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; -ms-flex-wrap:wrap; flex-wrap:wrap; -ms-flex-flow:column wrap; flex-flow:column wrap; -webkit-box-pack:justify; -ms-flex-pack:justify; justify-content:space-between; -ms-flex-line-pack:distribute; align-content:space-around; } /* Элементы */ .flex-item { -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:2; flex-shrink:2; -ms-flex-preferred-size:100px; flex-basis:100px; -ms-flex:1 2 100px; flex:1 2 100px; -ms-flex-item-align:center; align-self:center; -webkit-box-ordinal-group:3; -ms-flex-order:2; order:2; }
Лучше если свойства с префиксами будут идти до оригинального свойства.
В этом списке нет ненужных на сегодня (по caniuse) префиксов, но вообще префиксов больше.
Chrome | Safari | Firefox | Opera | IE | Android | iOS |
---|---|---|---|---|---|---|
20- (old) | 3.1+ (old) | 2-21 (old) | 10 (tweener) | 2.1+ (old) | 3.2+ (old) | |
21+ (new) | 6.1+ (new) | 22+ (new) | 12.1+ (new) | 11+ (new) | 4.4+ (new) | 7.1+ (new) |
- (new) - новый синтаксис: display: flex; .
- (tweener) - старый неофициальный синтаксис 2011 года: display: flexbox; .
- (old) - старый синтаксис 2009 года: display: box;
Видео
Ну и не забывайте про видео, там порой тоже интересно и понятно. Вот парочка популярных:
Полезные ссылки по Flex
flexboxfroggy.com - игра обучающая flexbox.
Flexplorer - наглядный конструктор flex кода.