CSS. Flexbox верстка
05.02.2019
Теги: CSS • HTML • Web-разработка • Верстка
Модель flexbox-разметки связана с определенным значением CSS-свойства display
родительского элемента (flex-контейнер), содержащего внутри себя дочерние блоки (flex-элементы).
.flex-container {
display: flex; /* контейнер как блочный элемент */
}
.flex-container {
display: inline-flex; /* контейнер как строчный элемент */
}
После установки значения flex
для свойства display
каждый дочерний элемент автоматически становится flex-элементом, выстраиваясь в ряд (вдоль главной оси) колонками одинаковой высоты, равной высоте блока-контейнера. При этом блочные и строчные дочерние элементы ведут себя одинаково, т.е. ширина блоков равна ширине их содержимого с учетом внутренних полей и рамок элемента.
<section> <div>Lorem ipsum</div> <div>Lorem ipsum dolor sit amet</div> <div>Lorem ipsum</div> <div>Lorem ipsum dolor sit amet</div> <div>Lorem ipsum</div> </section>
section {
display: flex;
padding: 10px;
background: #eee;
width: 800px;
height: 300px;
}
section > div {
box-sizing: border-box;
padding: 10px;
color: #fff;
}
section > div:nth-child(odd) {
background: #9f9;
}
section > div:nth-child(even) {
background: #f99;
}
Направление выстраивания flex-элементов
Указание направления выстраивания flex-элементов внутри flex-контейнера осуществляется посредством осей: главной (по умолчанию направлена вправо) и поперечной (по умолчанию направлена вниз). Установка направления главной оси:
.flex-container {
display: flex;
flex-direction: row; /* по умолчанию — row (вправо) */
}
Другие значения свойства flex-direction
— row-reverse
(влево), column
(вниз), column-reverse
(вверх).
Выстраиваются flex-элементы в flex-контейнере по направлению главной оси и располагаются в одну линию даже тогда, когда им не хватает места:
Чтобы разрешить перенос flex-элементов на новые линии (если им не хватает места в текущей линии):
.flex-container {
display: flex;
flex-wrap: wrap; /* по умолчанию — nowrap, перенос запрещен */
}
Свойства flex-direction
и flex-wrap
можно указать с помощью универсального свойства flex-flow
:
.flex-container {
display: flex;
flex-flow: row wrap;
}
Выравнивание flex-элементов вдоль оси
Выравнивание элементов вдоль главной оси
Свойство justify-content
помогает распределить лишнее свободное пространство, когда все элементы имеют фиксированный размер или достигли своего максимального размера.
.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: flex-start; /* по умолчанию — flex-start, относительно начала оси */
}
Другие значения свойства justify-content
:
flex-end
— элементы выравниваются относительно конца осиcenter
— элементы выравниваются по центру контейнераspace-between
— равномерно, с одинаковым расстоянием между элементамиspace-around
— равномерно, с добавлением половины пространства перед первым элементом и после последнего
Выравнивание элементов вдоль поперечной оси
Свойство align-items
определяет стандартное поведение того, как элементы будут располагаться вдоль поперечной оси на заданной строке. Это своебразная версия justify-content
, но только для поперечной оси, которая перпендикулярна главной.
.flex-container {
display: flex;
flex-flow: row wrap;
align-items: stretch; /* по умолчанию — stretch, растягиваются по всей длине поперечной оси */
}
Другие значения свойства align-items
:
flex-start
— относительно начала поперечной осиflex-end
— относительно конца поперечной осиbaseline
— относительно базовой линииcenter
— по центру
Свойство align-self
, заданное для определенного элемента, позволяет перезаписать свойство align-items
, заданное для всех элементов в контейнере:
.flex-container {
display: flex;
flex-flow: row wrap;
align-items: flex-start;
}
.flex-container > div:last-child {
align-self: flex-end;
}
Выравнивание линий flex-контейнера
Свойство align-content
выравнивает и распределяет строки контейнера, когда есть свободное пространство в поперечной оси, подобно тому как свойство justify-content
выравнивает элементы по главной оси.
.flex-container {
display: flex;
flex-flow: row wrap;
align-content: stretch; /* по умолчанию — stretch, растягиваются по всей длине поперечной оси */
}
Другие значения свойства align-content
:
flex-start
— относительно начала поперечной осиflex-end
— относительно конца поперечной осиcenter
— по центруspace-between
— равномерно, с одинаковым расстоянием между линиямиspace-around
— равномерно, но с добавлением половины пространства перед первой линией и после последней
align-content
имеет смысл использовать только тогда, когда flex-элементы во flex-контейнере располагаются на нескольких линиях.
Изменение порядка следования flex-элементов
Для изменения порядка следования flex-элементов в контейнере используется свойство order
, которое по умолчанию имеет значение ноль. Свойство выстраивает элементы в порядке возрастания их номеров.
<div class="flex-container"> <div id="flex-element-1">1</div> <div id="flex-element-2">2</div> <div id="flex-element-3">3</div> <div id="flex-element-4">4</div> </div>
.flex-container {
display: flex;
}
/* переместим 2-ой элемент в конец */
#flex-element-2 {
order: 1;
}
/* переместим 4-ый элемент в начало */
#flex-element-4 {
order: -1;
}
Управление шириной flex-элементов
Свойство flex-basis
Данное свойство предназначено для установления начальной ширины flex-элементу. Задавать значение ширины можно посредством различных единиц измерения, таких как px, %, em и др. По умолчанию данное свойство имеет значение auto
— в этом случае ширина элемента будет рассчитываться автоматически на основании его содержимого.
Конечная ширина flex-элемента будет определяться в зависимости от значений CSS-свойств flex-grow
и flex-shrink
, которые установлены не только для этого элемента, но и для других flex-элементов контейнера.
Свойство flex-grow
Это свойство определяет, может ли начальная ширина flex-элемента увеличиваться за счёт свободного пространства линии. В качестве значения CSS-свойства flex-grow указывается целое число. Именно это значение и определяет, какую часть свободного пространства flex-элемент заберёт себе.
<div class="flex-container"> <div>1</div> <div>2</div> </div>
.flex-container {
display: flex;
width: 600px;
}
.flex-container > div {
flex-basis: 30%;
}
.flex-container > div:first-child {
flex-grow: 1;
}
.flex-container > div:last-child {
flex-grow: 4;
}
В этом примере flex-элементы расположены на одной линии и в ней есть свободное пространство 240px
. После установки значений для свойства flex-grow
:
- ширина первого элемента будет увеличена на
1/5
часть свободного пространства - ширина первого элемента будет увеличена на
4/5
части свободного пространства
Другими словами, свойство flex-grow
позволяет не просто указать, что ширина flex-элемента может вырасти, но и задать, насколько эта величина может вырасти по отношению к другим элементам.
По умолчанию CSS свойство flex-grow
имеет значение 0
. Это означает, что flex-элемент не может расти (увеличивать свою ширину).
Свойство flex-shrink
Данное свойство определяет, может ли ширина flex-элемента уменьшаться. Уменьшение ширины flex-элемента будет осуществляться только в том случае, если ширины линии будет не достаточно для отображения всех элементов, расположенных в ней. Необходимая ширина рассчитывается на основании начальной ширины, который имеет каждый flex-элемент в ней.
<div class="flex-container"> <div>1</div> <div>2</div> </div>
.flex-container {
display: flex;
width: 400px;
}
.flex-container > div {
flex-basis: 300px;
flex-shrink: 0; /* запрет на уменьшение ширины */
}
.flex-container > div:first-child {
flex-shrink: 1;
}
.flex-container > div:last-child {
flex-shrink: 3;
}
Ширина flex-контейнера 400px
, для отображения flex-элементов необходимо 600px
, не хватает 200px
. После установки значений больше нуля, уменьшаться могут оба элемента:
- ширина первого элемента будет уменьшена на
1/4
от тех200px
, которых не хватает - ширина второго элемента будет уменьшена на
3/4
от тех200px
, которых не хватает
Значение свойства по умолчанию равно единице. Нулевое значение запрещает уменьшение ширины элемента.
Для удобной установки flex-grow
, flex-shrink
и flex-basis
можно использовать свойство flex
. Значение по умолчанию:
.flex-element {
flex: 0 1 auto; /* flex-grow: 0; flex-shrink: 1; flex-basis: auto; */
}
Макет страницы на Flexbox
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Макет Flexbox</title> <link rel="stylesheet" type="text/css" href="style.css" /> </head> <body> <header> <p>Header</p> </header> <main> <article> <h1>Lorem Ipsum</h1> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor...</p> </article> <nav> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p> </nav> <aside> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p> </aside> </main> <footer> <p>Footer</p> </footer> </body> </html>
/* Верстка по принципу mobile first, для больших экранов медиа-запрос */
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
}
body {
/* flex-контейнер для <header>, <main> и <footer> */
display: flex;
/* flex-элементы <header>, <main> и <footer> выстаиваются по вертикали */
flex-direction: column;
/* вся высота viewport браузера */
min-height: 100vh;
}
header {
/* не может увеличиваться или уменьшаться, всегда 100px */
flex: 0 0 100px;
}
main {
/*
может как увеличиваться, так и уменьшаться, чтобы вместе с
<header> и <footer> занять всю высоту viewport браузера
*/
flex: 1 1 auto;
/* flex-контейнер для <article>, <nav> и <aside> */
display: flex;
/*
на маленьких экранах flex-элементы <article>, <nav> и <aside> выстаиваются
по вертикали; для больших экранов отдельный media-запрос
*/
flex-direction: column;
}
article {
/* базовый размер 50%, может увеличиваться или уменьшаться */
flex: 2 2 50%;
}
nav, aside {
/* базовый размер 25%, могут увеличиваться или уменьшаться */
flex: 1 1 25%;
}
nav {
/* будет первым, хотя в html-коде идет вторым */
order: -1;
}
footer {
/* не может увеличиваться или уменьшаться, всегда 100px */
flex: 0 0 100px;
}
@media screen and (min-width: 800px) { /* медиа-запрос для больших экранов */
main {
/* на больших экранах <article>, <nav> и <aside> выстаиваются по горизонтали */
flex-direction: row;
}
article {
/* отступ слева и справа, чтобы отделить левую и правую колонки */
padding: 0 1em 0 1em;
}
}
Дополнительно
Поиск: CSS • HTML • Web-разработка • Верстка • Flexbox • flex-direction • justify-content • align-items • align-self • align-content • order • flex-basis • flex-grow • flex-shrink • Контейнер • Элемент