Flex html примеры. Полное руководство по Flexbox

  • Перевод

Об авторе : Рэйчел Эндрю - не только главный редактор журнала Smashing Magazine, но и веб-разработчик, писатель и спикер. Она автор ряда книг, в том числе The New CSS Layout , один из разработчиков системы управления контентом Perch . Пишет о бизнесе и технологиях на своём сайте rachelandrew.co.uk .

Краткое содержание: в этой статье мы рассмотрим свойства выравнивания во Flexbox и некоторые основные правила, как работает выравнивание по основной и поперечной осям.

Значения точно так же работают по вертикали, то есть если flex-direction применяется для column . Правда, у вас в столбце может не оказаться свободного места для распределения, если не добавить высоту или block-size контейнера, как в этом демо .

Выравнивание по осям с помощью align-content

Если в контейнере несколько осей и указано flex-wrap: wrap , то можно использовать align-content для выравнивания строк на поперечной оси. Но требуется дополнительное пространство. В этой демонстрации поперечная ось работает в направлении колонки, и я указала высоту контейнера 60vh . Поскольку это больше, чем необходимо для отображения всех элементов, то появляется свободное пространство по вертикали.

Затем я могу применить align-content с любым из значений .

Если в качестве flex-direction указано column , то align-content работает как в следующем примере .

Как и в случае с justify-content , мы работаем с группой строк и распределяем свободное пространство.

Свойство по place-content

В спецификации Box Alignment можно найти свойство place-content . Использование этого свойства означает, что вы одновременно устанавливаете justify-content и align-content . Первое значение - для align-content , второе для justify-content . Если задано только одно значение, то оно применяется к обоим свойствам:

Container { place-content: space-between stretch; }
Соответствует этому:

Container { align-content: space-between; justify-content: stretch; }
А такой код:

Container { place-content: space-between; }
Равноценен следующему:

Container { align-content: space-between; justify-content: space-between; }

Выравнивание по осям с помощью align-items

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


Как вариант, её можно определить свойством height в контейнере:


Почему элементы растягиваются до размера самого высокого элемента - это потому что начальным значением параметра align-items является stretch . Элементы растягиваются по поперечной оси до размера контейнера в этом направлении.

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

Кроме начального значения stretch , можно присвоить элементам align-items значение flex-start , в этом случае они выравниваются по началу контейнера и больше не растягиваются по высоте.


Значение flex-end перемещает их в конец контейнера по поперечной оси.


Если вы используете значение center , то элементы центрируются относительно друг друга:


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


Все эти варианты можно попробовать в демо .

Индивидуальное выравнивание с помощью align-self

Свойство align-items задаёт выравнивание всех элементов одновременно. В действительности оно устанавливает значения align-self для всех элементов группы. Можно также использовать свойство align-self для любого отдельного элемента, чтобы выровнять его внутри строки и относительно других элементов.

В следующем примере в контейнере используется align-items для выравнивания всей группы по центру, но также align-self для первого и последнего элементов.

Почему нет justify-self ?

Часто возникает вопрос, почему невозможно выровнять один элемент или группу элементов по главной оси. Почему во Flexbox нет свойства -self для выравнивания по главной оси? Если вы представите justify-content и align-content как способ распределения пространства, то ответ становится более очевидным. Мы имеем дело с элементами как с группой и размещаем свободное пространство определённым образом: либо в начале, либо в конце группы, либо между элементами.

Также может быть полезно подумать, как justify-content и align-content работают в CSS Grid Layout. В Grid эти свойства используются для распределения свободного пространства в grid-контейнере между grid-дорожками . Здесь тоже мы берём группу дорожек - и с помощью этих свойств распределяем между ними свободное пространство. Поскольку мы оперируем в группе и в Grid, и во Flexbox, то не можем взять отдельный элемент и сделать с ним что-то другое. Тем не менее, есть способ получить оформление макета, которое хотят верстальщики, когда говорят о свойстве self на главной оси. Это использование автоматических полей.

Использование автоматических полей на основной оси

Если вы когда-нибудь центрировали блок в CSS (например, враппер для контента главной страницы, установив поля слева и справа в auto), то у вас уже есть некоторый опыт работы с автоматическими полями. Значение auto для полей заполняет максимальное пространство в установленном направлении. Для центрирования блока мы устанавливаем и левое, и правое поля в auto: каждое из них пытается занять как можно больше места, и поэтому помещает наш блок в центр.

Автоматические поля очень хорошо работают во Flexbox для выравнивания отдельных элементов или групп элементов на главной оси. В следующем примере показан типичный случай. Есть панель навигации, элементы отображаются в виде строки и используют начальное значение justify-content: start . Я хочу, чтобы последний пункт отображался отдельно от других в конце строки - при условии, что в строке достаточно места для этого.

Берём этот элемент и указываем для свойства margin-left значение auto . Это значит, что поле пытается получить как можно больше места слева от элемента, то есть элемент выталкивается к правой границе.

Если вы используете автоматические поля на главной оси, то justify-content перестанет действовать, так как автоматические поля займут всё пространство, которое в противном случае распределялось бы с помощью justify-content .

Запасное выравнивание

Для каждого метода выравнивания описан запасной вариант - что произойдёт, если заданное выравнивание невозможно. Например, если у вас есть только один элемент в контейнере, а вы указали justify-content: space-between , что должно произойти? В этом случае применяется запасное выравнивание flex-start - один элемент будет выровнен по началу контейнера. В случае justify-content: space-around используется запасное выравнивание center .

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

Безопасное и небезопасное выравнивание

Недавним дополнением к спецификации Box Alignment стала концепция безопасного и небезопасного выравнивания с использованием ключевых слов safe и unsafe .

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

Container { display: flex; flex-direction: column; width: 100px; align-items: unsafe center; } .item:last-child { width: 200px; }


Безопасное выравнивание предотвращает потерю данных, перемещая переполнение на другую сторону.

Container { display: flex; flex-direction: column; width: 100px; align-items: safe center; } .item:last-child { width: 200px; }


Эти ключевые слова пока поддерживаются не всеми браузерами, однако демонстрируют, как спецификации Box Alignment добавляют контроля во Flexbox.

Заключение

Свойства выравнивания начинались со списка в Flexbox, но теперь обзавелись собственной спецификацией и применяются к другим контекстам макетирования. Вот несколько ключевых фактов, которые помогут запомнить их использование во Flexbox:
  • justify- для основных осей, а align- для поперечных;
  • для align-content и justify-content требуется свободное пространство;
  • свойства align-content и justify-content применяются к элементам в группе, распределяя пространство между ними. Нельзя указывать выравнивание отдельного элемента, потому что свойство -self отсутствует;
  • если хотите выровнять один элемент или разбить группу по основной оси, используйте автоматические поля;
  • align-items устанавливает одинаковые свойства align-self для всей группы. Используйте align-self для дочернего элемента группы, чтобы установить ему значение индивидуально.

Теги: Добавить метки

Спецификация Flexbox (Flexible Box Layout Module) – это метод позиционирования элементов в горизонтальном или вертикальном направлениях.

Flexbox объединяет в себе набор свойств для родительского flex-контейнера и для дочерних flex-элементов.

Чтобы элемент стал flex-контейнером, ему надо присвоить display: flex; или display: inline-flex; (блочный или строчный соответственно).

Внутри flex-контейнера создаются две оси: главная и перпендикулярная ей поперечная. Сначала flex-элементы выстраиваются по главной оси, а потом уже по поперечной.

Свойства flex-контейнера

flex-direction Определяет направление главной оси. Возможные значения:
  • row – слева направо (по умолчанию);
  • row-reverse – справа налево;
  • column – сверху вниз;
  • column-reverse – снизу вверх.
flex-wrap Определяет многострочность контейнера. Возможные значения:
  • nowrap – flex-элементы выстраиваются в одну строку, если не помещаются в контейнер, то выходят за его границы (по умолчанию);
  • wrap – flex-элементы выстраиваются в несколько строк, если не помещаются в одну;
  • wrap-reverse – похоже на wrap , но перенос происходит снизу вверх.
flex-flow Определяет сразу два параметра: flex-direction и flex-wrap.
Например, flex-flow: column wrap;
justify-content Определяет выравнивание элементов по главной оси. Возможные значения:
  • flex-start – flex-элементы прижимаются к началу главной оси (по умолчанию);
  • flex-end – flex-элементы прижимаются к концу главной оси;
  • center – flex-элементы выравниваются по центру главной оси;
  • space-between – flex-элементы распределяются вдоль главной оси, при этом первый элемент прижат к началу оси, а последний - к концу;
  • space-around – flex-элементы распределяются вдоль главной оси, при этом свободное пространство делится поровну между элементами. Но стоит отметить, что промежутки суммируются и расстояние между элементами в два раза больше, чем расстояние между краями контейнера и крайними элементами.
align-items Определяет выравнивание элементов по поперечной оси. Возможные значения:
  • flex-start – flex-элементы прижимаются к началу поперечной оси (по умолчанию);
  • flex-end – flex-элементы прижимаются к концу поперечной оси;
  • center – flex-элементы выравниваются по центру поперечной оси;
  • baseline – flex-элементы выравниваются по своей базовой линии. Базовая линия – это воображаемая линия, проходящая по нижнему краю символов без учёта свисаний, таких как у букв «д», «р», «ц», «щ»;
  • stretch – flex-элементы растягиваются, занимая все доступное место по поперечной оси. Но если для элементов задана высота, то stretch будет проигнорирован.
align-content Определяет выравнивание целых строк flex-элементов по поперечной оси. Возможные значения:
  • flex-start – строки flex-элементов прижимаются к началу поперечной оси (по умолчанию);
  • flex-end – строки flex-элементов прижимаются к концу поперечной оси;
  • center – fстроки flex-элементов выравниваются по центру поперечной оси;
  • space-between – строки flex-элементов распределяются вдоль поперечной оси, при этом первая строка прижата к началу оси, а последняя - к концу;
  • space-around – строки flex-элементов распределяются вдоль поперечной оси, при этом свободное пространство делится поровну между строками. Но стоит отметить, что промежутки суммируются и расстояние между строками в два раза больше, чем расстояние между краями контейнера и крайними строками.
  • stretch – строки flex-элементов растягиваются, занимая все доступное место по поперечной оси. Но если для элементов задана высота, то stretch будет проигнорирован.

Это свойство не работает для однострочного flex-контейнера.


Свойства flex-элементов

order Определяет порядок следования отдельно взятого flex-элемента внутри flex-контейнера. Задается целым числом. По умолчанию равно 0, тогда элементы следуют друг за другом в порядке естественного потока. Значение order задает вес позиции элемента в последовательности, а не абсолютную позицию.
flex-basis Определяет базовый размер flex-элемента перед распределением пространства в контейнере. Может быть задан в px, %, em и остальных единицах измерения. По сути это своего рода отправная точка, относительно которой происходит растягивание или сжатие элемента. Значение по умолчанию – auto , при этом размер элемента зависит от размера внутреннего контента.
flex-grow Определяет, какую долю свободного места внутри контейнера добавит к своему базовому размеру flex-элемент. Задается целым числом, служащим пропорцией. По умолчанию равно 0. Если у всех элементов flex-grow: 1 , то все они будут одинакового размера. Если одному flex-элементу задать значение 2, то к его базовому размеру добавится в два раза больше, чем к другим.
flex-shrink Определяет, на сколько в случае недостатка места будет уменьшаться flex-элемент относительно уменьшения соседних элементов внутри flex-контейнера. Задается целым числом, служащим пропорцией. По умолчанию равно 1. Если одному flex-элементу задать значение flex-shrink: 2 , то из его базового размера вычтется в два раза больше, чем из других, если контейнер меньше, чем сумма базовых размеров входящих в него элементов.
flex Определяет сразу три параметра: flex-grow, flex-shrink, flex-basis.
Например, flex: 1 1 200px;
align-self Переопределяет выравнивание, заданное по умолчанию или в align-items , для конкретного flex-элемента. Возможные значения:
  • flex-start – flex-элемент прижимается к началу поперечной оси (по умолчанию);
  • flex-end – flex-элемент прижимается к концу поперечной оси;
  • center – flex-элемент выравнивается по центру поперечной оси;
  • baseline – flex-элемент выравнивается по базовой линии;
  • stretch – flex-элементы растягивается, занимая все доступное место по поперечной оси. Но если задана высота, то stretch будет проигнорирован.

Особенности применения Flexbox на практике

1. Выравнивание по правому краю

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

item1
item2
item3
item4
item5

В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: 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; /* Магия! Блок отцентрирован по вертикали и горизонтали! */ }

Вещи, которые следует помнить

  1. Не следует использовать flexbox там, где в этом нет необходимости.
  2. Определение регионов и изменение порядка контента во многих случаях все-таки полезно делать зависимым от структуры страницы. Продумывайте это.
  3. Разберитесь в flexbox и знайте его основы. Так намного легче достичь ожидаемого результата.
  4. Не забывайте про margin-ы. Они учитываются при установке выравнивания по осям. Также важно помнить, что margin-ы в flexbox не “коллапсятся”, как это происходит в обычном потоке.
  5. Значение float у flex-блоков не учитывается и не имеет значения. Это, наверно, как-то можно использовать для graceful degradation при переходе на flexbox.
  6. flexbox очень хорошо подходит для верстки веб-компонентов и отдельных частей веб-страниц, но показал себя не с лучшей стороны при верстке базовых макетов (расположение article, header, footer, navbar и т.п.). Это все еще спорный момент, но эта статья довольно убедительно показывает недостатки xanthir.com/blog/b4580

В заключение

Я думаю, что flexbox, конечно же, не вытеснит все остальные способы верстки, но, безусловно, в ближайшее время займет достойную нишу при решении огромного количества задач. И уж точно, пробовать работать с ним нужно уже сейчас. Одна из следующих статей будет посвящена конкретным примерам работы с flex-версткой. Подписывайтесь на новости;)

One of the reasons that flexbox quickly caught the interest of web developers is that it brought proper alignment capabilities to the web for the first time. It enabled proper vertical alignment, so we can at last easily center a box. In this guide, we will take a thorough look at how the alignment and justification properties work in Flexbox.

To center our box we use the align-items property to align our item on the cross axis, which in this case is the block axis running vertically. We use justify-content to align the item on the main axis, which in this case the inline axis running horizontally.

You can take a look at the code of this example below. Change the size of the container or nested element and the nested element always remains centered.

Properties that control alignment

The properties we will look at in this guide are as follows.

  • justify-content - controls alignment of all items on the main axis.
  • align-items - controls alignment of all items on the cross axis.
  • align-self - controls alignment of an individual flex item on the cross axis.
  • align-content - described in the spec as for “packing flex lines”; controls space between flex lines on the cross axis.

We will also discover how auto margins can be used for alignment in flexbox.

Note : The alignment properties in Flexbox have been placed into their own specification - CSS Box Alignment Level 3 . It is expected that this spec will ultimately supersede the properties as defined in Flexbox Level One.

The Cross Axis

The align-items and align-self properties control alignment of our flex items on the cross axis, down the columns if flex-direction is row and along the row if flex-direction is column .

We are making use of cross-axis alignment in the most simple flex example. If we add display: flex to a container, the child items all become flex items arranged in a row. They will all stretch to be as tall as the tallest item, as that item is defining the height of the items on the cross axis. If your flex container has a height set, then the items will stretch to that height, regardless of how much content is in the item.

The reason the items become the same height is that the initial value of align-items , the property that controls alignment on the cross axis, is set to stretch .

We can use other values to control how the items align:

  • align-items: flex-start
  • align-items: flex-end
  • align-items: center
  • align-items: stretch
  • align-items: baseline

In the live example below, the value of align-items is stretch . Try the other values and see how all of the items align against each other in the flex container.

Aligning one item with align-self

The align-items property sets the align-self property on all of the flex items as a group. This means you can explicitly declare the align-self property to target a single item. The align-self property accepts all of the same values as align-items plus a value of auto , which will reset the value to that which is defined on the flex container.

In this next live example, the flex container has align-items: flex-start , which means the items are all aligned to the start of the cross axis. I have targeted the first item using a first-child selector and set that item to align-self: stretch ; another item has been selected using its class of selected and given align-self: center . You can change the value of align-items or change the values of align-self on the individual items to see how this works.

Changing the main axis

So far we have looked at the behaviour when our flex-direction is row , and while working in a language written top to bottom. This means that the main axis runs along the row horizontally, and our cross axis alignment moves the items up and down.

If we change our flex-direction to column, align-items and align-self will align the items to the left and right.

You can try this out in the example below, which has a flex container with flex-direction: column yet otherwise is exactly the same as the previous example.

Aligning content on the cross axis - the align-content property

So far we have been aligning the items, or an individual item inside the area defined by the flex-container. If you have a wrapped multiple-line flex container then you might also want to use the align-content property to control the distribution of space between the rows. In the specification this is described as packing flex lines .

For align-content to work you need more height in your flex container than is required to display the items. It then works on all the items as a set, and dictates what happens with that free space, and the alignment of the entire set of items within it.

The align-content property takes the following values:

  • align-content: flex-start
  • align-content: flex-end
  • align-content: center
  • align-content: space-between
  • align-content: space-around
  • align-content: stretch
  • align-content: space-evenly (not defined in the Flexbox specification)

In the live example below, the flex container has a height of 400 pixels, which is more than needed to display our items. The value of align-content is space-between , which means that the available space is shared out between the flex lines, which are placed flush with the start and end of the container on the cross axis.

Try out the other values to see how the align-content property works.

Once again we can switch our flex-direction to column in order to see how this property behaves when we are working by column. As before, we need enough space in the cross axis to have some free space after displaying all of the items.

Note : the value space-evenly is not defined in the flexbox specification and is a later addition to the Box Alignment specification. Browser support for this value is not as good as that of the values defined in the flexbox spec.

Если говорить коротко, то верстка с Flexbox дает нам простые решения некогда непростых задач. Например, когда нужно выровнять элемент по вертикали, или прижать подвал к низу экрана, или просто вставить несколько блоков в один ряд, так чтобы они занимали все свободно пространство. Подобные задачи решаются и без flex. Но как правило, эти решения больше похожи на «костыли» - приемы использовать css не по назначению. Тогда как с flexbox такие задачи решаются именно так, как задумывает flex-модель.

CSS Flexible Box Layout Module (CSS модуль для макетов с гибкими блоками), коротко flexbox, создана, чтобы убрать недостатки при создании самых разных HTML конструкций, в том числе адаптированных под разную ширину и высоту, и сделать верстку логичной и простой. А логичный подход, как правило работает в неожиданных местах, там где результат не проверялся - логика наше все!

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

Базовые знания

FlexBox состоит из Контейнера и его Дочерних элементов (items) (гибких элементов).

Для включения flexbox, любому HTML элементу достаточно присвоить css свойство display:flex; или display:inline-flex; .

1
2

После включения 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 - направление элементов снизу вверх ()
flex-wrap:

Управляет переносом непомещающихся в контейнер элементов.

  • nowrap (default) - вложенные элементы располагаются в один ряд (при direction=row) или в одну колонку (при direction=column) независимо от того помещаются они в контейнер или нет.
  • wrap - включает перенос элементов на следующий ряд, если они не помещаются в контейнер. Так включается движение элементов по поперечной оси.
  • wrap-reverse - тоже что wrap только перенос будет не вниз, а вверх (в обратном направлении).
flex-flow: direction 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
align-content:

Выравнивает ряды, в которых находятся элементы по поперечной оси. То же что 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-items:

Выравнивает элементы по поперечной оси внутри ряда (невидимой строки). Т.е. сами ряды выравниваются через 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:

Позволяет менять порядок (позицию, положение) элемента в общем ряду.

По умолчанию: order: 0

По умолчанию элементы имеют order: 0 и ставятся в порядке их появления в HTML коде и направления ряда. Но если изменить значение свойства order, то элементы будут выстраиваться в порядке значений: -1 0 1 2 3 ... . Например если одному из элементов указать order: 1 , то сначала будут идти все нулевые, а потом элемент с 1.

Так можно, например, первый элемент перекинуть в конец, при этом не меняя направление движения остальных элементов или 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 конструкции... А значит, flex-basis не влияет на элементы flex контейнера, если они абсолютны position:absolute . Им нужно будет указать width / height.

  • При использовании свойства flex 3 значения (flex-grow/flex-shrink/flex-basis) можно скомбинировать и записать коротко, а для width grow или shrink нужно писать отдельно. Например: flex:0 0 50% == width:50%; flex-shrink:0; . Иногда это просто неудобно.

По возможности все же отдавайте предпочтение 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.

1
2
3
4
5
6

Перейдите в jsfiddle.net и изменяйте ширину секции «результат»

#4 Адаптивные блоки на flex

Допустим нам нужно вывести 3 блока, один большой и два маленьких. При этом нужно чтобы блоки подстраивались под маленькие экраны. Делаем:

1
2
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 кода.