Russian (Pусский) translation by Pembelight (you can also view the original English article)
Flexbox позволяет нам размещать флекс-элементы в любом порядке и направлении. Распределение порядка элементов с flexbox проще, чем с помощью float или CSS-сетки, даже если вы с этим не согласны. Поскольку flexbox — это модель одномерного макета, в отличие от CSS-сетки, которая является двумерной, вам нужно обращать внимание только на одно направление. W3C четко определелил правила, поэтому вам больше не придется иметь дело с float и clearfix.
В данном уроке вы узнаете, как использовать следующие свойства flexbox для расстановки элементов:
flex-direction
flex-wrap
flex-flow
order
Расстановка Vs. Перестановка элементов
Обсуждая тему расстановки flexbox, мы должны прояснить разницу между расстановкой и перестановкой элементов.
Что такое расстановка?
Когда мы настраиваем макет flexbox, сначала нужно определить исходный порядок, то есть мы должны решить, как позиционируются оси flex контейнера. Я подробно описал flexbox оси в своем уроке по выравниванию flexbox.
Вкратце, каждый flex контейнер имеет две оси: главную и поперечную. Главная ось будет иметь одно из четырех направлений, а поперечная ось всегда перпендикулярна первой:
- слева направо
- справа налево
- сверху вниз
- снизу вверх
Мы устанавливаем главную ось с помощью свойства flex-direction
, а затем решаем, как будут ужиматься flex элементы, используя свойство flex-wrap
. Эти два свойства определяют, каким образом браузер разместит элементы в flex контейнере.
Так что же такое перестановка элементов?
Flexbox по умолчанию позволяет нам управлять порядком элементов, эффективно их переставляя с помощью свойства order
. Перестановка элементов означает, что мы визуально меняем позиционирование элементов, в то время как исходный порядок остается без изменений.
Используя такие возможности flexbox, нам не приходится менять структуру HTML документа только ради его визуального отображения. Таким образом, скринридеры (и поисковые системы) считывают логически структурированный контент (например, боковая панель не имеет приоритета над основным контентом).
Свойство оrder для Flexbox
Порядок элементов во Flexbox происходит со свойствами flex-direction и flex-wrap: flex-direction
указывает направление главной оси. Свойство оrder может принимать следующие значения:
-
row
(по умолчанию) главной оси: слева направо -
row-reverse
главной оси: справа налево -
column
главной оси : сверху вниз -
column-reverse
главной оси: снизу вверх
Flex-wrap
определяет, расположены ли flex-элементы в один ряд или в несколько. Он также контролирует направление поперечной оси. Может иметь три значения:
-
nowrap
(по умолчанию) размещает flex-элементы в одну строку; поперечная ось стоит в положении по умолчанию -
wrap
размещает flex-элементы в несколько строк; поперечная ось стоит в положении по умолчанию -
wrap-reverse
размещает flex-элементы в несколько строк; поперечная ось в обратном порядке
Положение поперечной оси по умолчанию:
- сверху вниз в случае
row
иrow-reverse
- слева направо в случае
column
иcolumn-reverse
В моей предыдущей статье о выравнивании flexbox вы можете найти четыре подробных примера (с демонстрациями) о том, как настроить основную ось в четырех разных направлениях, используя свойство flex-direction
. Однако, когда возникает вопрос расстановки элементов во флексбоксе, по моему мнению более важно знать, как совместно использовать свойства flex-direction
и flex-wrap
для достижения грамотного исходного кода.
Пример шорткода
Мы используем простой код, чтобы увидеть, как работает flexbox расстановка элементов. В данном примере HTML состоит из нескольких элементов:
1 |
<div class="container"> |
2 |
<div class="item item-1">1</div> |
3 |
<div class="item item-2">2</div> |
4 |
<div class="item item-3">3</div> |
5 |
<div class="item item-4">4</div> |
6 |
<div class="item item-5">5</div> |
7 |
<div class="item item-6">6</div> |
8 |
<div class="item item-7">7</div> |
9 |
<div class="item item-8">8</div> |
10 |
<div class="item item-9">9</div> |
11 |
</div>
|
Элемент .container
div будет flex-контейнером, а div с классом .item
будут flex-элементами. Мы будем использовать (почти) один и тот же CSS код во всех примерах, только поменяются свойства flex-direction
и flex-wrap
. Вот как выглядит наш CSS со значениями row
и wrap
:
1 |
html { |
2 |
background: #fff7f6; |
3 |
}
|
4 |
.container { |
5 |
display: flex; |
6 |
flex-direction: row; |
7 |
flex-wrap: wrap; |
8 |
}
|
9 |
.item { |
10 |
font-size: 2rem; |
11 |
line-height: 1; |
12 |
text-align: center; |
13 |
padding: 3rem; |
14 |
background: mistyrose; |
15 |
border: 3px solid tomato; |
16 |
color: tomato; |
17 |
margin: 6px; |
18 |
}
|
Тот же пример в демонстрации на CodePen:
Расстановка элементов с помощью Row
и Column
Теперь мы действительно дошли до самого интересного! Теоретически понять принцип расстановки элементв с помощью флексбокса не так уж и сложно, но на практике, безусловно, могут возникать проблемы. Это происходит из-за того, что трудно предугадать, как разные варианты направления flex-direction
и flex-wrap
комбинируются между собой.
В подключенном ниже примере вы увидите, как макеты flex-direction: row
и flex-direction: column
взаимодействуют между собой с разными значениями свойства flex-wrap
. Используйте выпадающие списки, чтобы увидеть их комбинации.
Как вы видите, когда flex-direction
является row
, flex-элементы располагаются горизонтально слева направо. Когда вместо wrap
мы используем wrap-reverse
, flexbox начинает выкладывать элементы снизу вверх, а не наоборот. Это происходит потому, что wrap-reverse
меняет направление перпендикулярной оси.
Когда flex-direction
это column
, элементы располагаются вертикально сверху вниз. И когда мы используем wrap-reverse
вместо wrap
, flexbox начинает размещать элементы справа (теперь это начальная точка поперечной оси), а не слева.
Расстановка элементов с помощью row-reverse
и column-reverse
Теперь давайте посмотрим на то, как flexbox размещает элементы, когда flex-direction — это row-reverse
и column-reverse
.
Как видно из демонстрации выше, в обоих случаях flexbox начинает выкладывать элементы, как и раньше, с начала по главной оси. Главная ось row-reverse
проходит справа налево, поэтому flexbox начинает раскладывать элементы справа. Кроме того, главная ось макета column-reverse
проходит снизу вверх, поэтому элементы начинают размещаться снизу вверх flex контейнера.
Когда мы используем flex-wrap: wrap
, flexbox начинает размещать элементы со свойством flex-direction
: сверху row-reverse
, и слева column-reverse
, так как они соответсвенно являются начальными точками поперечной оси.
Когда мы меняем направление на flex-wrap: wrap-reverse
, поперечная ось будет двигаться в противоположном направлении. Она будет размещать элементы при flex-direction
снизу вверх row-reverse
и справа налево при column-reverse
.
Ускорьте процесс с помощью flex-flow
Также значения flex-direction
и flex-wrap
могут применяться к одному классному CSS свойству. Оно называется flex-flow. Чтобы его использовать, нам нужно прописать эти два значения вместе, как это сделано ниже:
1 |
.container-1 { |
2 |
flex-flow: row wrap; |
3 |
}
|
4 |
.container-2 { |
5 |
flex-flow: column-reverse wrap-reverse; |
6 |
}
|
Перестановка элементов в Flexbox
Пришло время взглянуть на вещи немного по-другому.
Свойство order изменяет порядок по умолчанию для flex-элементов, который мы определяем с помощью flex-direction
и flex-flow
. Он влияет только на визуальное расположение элементов, но он не влияет на то, как скринридеры и другие пользовательские агенты, не относящиеся к CSS, читают исходный код.
В отличие от свойств, упомянутых ранее, мы используем order
для flex элементов, а не flex контейнера. Оно может принимать любое целое значение и его значение по умолчанию равно 0.
В следующем примере .item-3
перемещается в начальную точку главной оси. Поскольку все элементы имеют значение по умолчанию 0, достаточно использовать правило order: -1
, чтобы сделать его первым элементом в контейнере:
1 |
.item-3 { |
2 |
order: -1; |
3 |
}
|
Вы заметили, что эту же логику можно использовать для перемещения .item-3
к концу главной оси. Для этого нам только нужно назначить положительное значение свойства order
.
Конечно, мы можем переставить столько flex элементов, сколько пожелаем (хотя имейте в виду, что перестановка всех элементов, скорее всего, не самое грамотное решение). Свойства order
различных flex элементов всегда расположены относительно друг к другу. Ниже вы увидете, как можно поменять порядок нескольких элементов во flex контейнере.
1 |
.item-3 { |
2 |
order: -1; |
3 |
}
|
4 |
.item-4 { |
5 |
order: -2; |
6 |
}
|
7 |
.item-5 { |
8 |
order: 2; |
9 |
}
|
10 |
.item-7 { |
11 |
order: 1; |
12 |
}
|
Порядок и доступность
Самое важное — это то, что свойство order
не влияет на порядок стилизации, контент и логическую навигацию элементов. Это значит, что когда мы изменяем порядок наших flex элементов, невизуальные ползователи не заметят изменения. Например, люди, использующие навигацию с помощью клавиатуры, будут по-прежнему перемещаться по ссылкам в исходном порядке.
Такое поведение flexbox может пригодиться в некоторых случаях. Например, можно сделать так называемый «Макет Святого Грааля» доступным с помощью порядка во флексбоксе. Макет Святого Грааля — это популярный макет блога с хедером, футером и двумя боковыми сайдбарами: слева и справа от основного контента.
В HTML коде этого макета мы обычно ставим левый сайдбар перед основным содержимым. Однако с точки зрения доступности пользователи вспомогательных технологий должны в первую очередь знакомиться с основным контентом. Flexbox с этим справляется идеально. В нашей разметке мы можем разместить основной контент перед двумя боковыми панелями. Затем нам остается только правильно позиционировать сайдбар и основное содержимое, используя свойство order
:
1 |
.sidebar-left { |
2 |
order: 1; |
3 |
}
|
4 |
article { |
5 |
order: 2; |
6 |
}
|
7 |
.sidebar-right { |
8 |
order: 3; |
9 |
}
|
Flexbox & Writing Modes
Все сказанное в этом уроке относится к режиму записи LTR (left to right — слева направо). Оси Flexbox фактически следуют направлению письма документа, которое можно настроить с помощью свойств direction и writing-mode. Вот почему в режиме записи LTR главная ось движется слева направо, когда flex-direction
является row
. В режиме записи RTL (right to left — справа налево) он работает в противоположном направлении, справа налево, и все остальное меняется соответственно.
Это (Flex) Wrap!
Этот урок был второй частью из моей серии по flexbox. Обязательно прочитайте первую часть о выравнивании flexbox, чтобы узнать, как выровнять flex-элементы вдоль главной и поперечной оси. Если вы хотите больше узнать о расстановке элементов во flexbox, MDN предлагает очень информативную статью на данную тему.
Узнайте больше
New layout methods such as Flexbox and Grid bring with them the possibility of controlling the order of content. In this article, we will take a look at ways in which you can change the visual order of your content when using Flexbox. We will also consider the implications of reordering items from an accessibility point of view.
Reverse the display of the items
the flex-direction
property can take one of four values:
row
column
row-reverse
column-reverse
The first two values keep the items in the same order that they appear in the document source order and display them sequentially from the start line.
The second two values reverse the items by switching the start and end lines.
Remember that the start line relates to writing modes. The row-related examples above demonstrate how row
and row-reverse
work in a left-to-right language such as English. If you are working in a right-to-left language like Arabic then row
would start on the right, row-reverse
on the left.
This can seem like a neat way to display things in reverse order however you should be mindful that the items are only visually displayed in reverse order. The specification says the following on this matter:
«Note: The reordering capabilities of flex layout intentionally affect only the visual rendering, leaving speech order and navigation based on the source order. This allows authors to manipulate the visual presentation while leaving the source order intact for non-CSS UAs and for linear models such as speech and sequential navigation.» — Ordering and Orientation
If your items were links or some other element that the user could tab to, then the tabbing order would be the order that these items appear in the document source — not your visual order.
If you are using a reverse value, or otherwise reordering your items, you should consider whether you actually need to change the logical order in the source. The specification continues with a warning not to use reordering to fix issues in your source:
«Authors must not use order or the *-reverse values of flex-flow/flex-direction as a substitute for correct source ordering, as that can ruin the accessibility of the document.»
Note: For some years Firefox had a bug whereby it would attempt to follow the visual order and not the source order, making it behave differently from other browsers. This has now been fixed. You should always take the source order as the logical order of the document as all up-to-date user agents will be following the specification and doing so.
In the live example below I have added a focus style in order that as you tab from link to link you can see which is highlighted. If you change the order using flex-direction
you can see how the tab order continues to follow the order that the items are listed in the source.
In the same way that changing the value of flex-direction
does not change the order in which items are navigated to, changing this value does not change paint order. It is a visual reversal of the items only.
The order property
In addition to reversing the order in which flex items are visually displayed, you can target individual items and change where they appear in the visual order with the order
property.
The order
property is designed to lay the items out in ordinal groups. What this means is that items are assigned an integer that represents their group. The items are then placed in the visual order according to that integer, lowest values first. If more than one item has the same integer value, then within that group the items are laid out as per source order.
As an example, I have 5 flex items, and assign order
values as follows:
- Source item 1:
order: 2
- Source item 2:
order: 3
- Source item 3:
order: 1
- Source item 4:
order: 3
- Source item 5:
order: 1
These items would be displayed on the page in the following order:
- Source item 3:
order: 1
- Source item 5:
order: 1
- Source item 1:
order: 2
- Source item 2:
order: 3
- Source item 4:
order: 3
You can play around with the values in this live example below and see how that changes the order. Also, try changing flex-direction
to row-reverse
and see what happens — the start line is switched so the ordering begins from the opposite side.
Flex items have a default order
value of 0
, therefore items with an integer value greater than 0 will be displayed after any items that have not been given an explicit order
value.
You can also use negative values with order
, which can be quite useful. If you want to make one item display first and leave the order of all other items unchanged, you can give that item order of -1
. As this is lower than 0 the item will always be displayed first.
In the live code example below I have items laid out using Flexbox. By changing which item has the class active
assigned to it in the HTML, you can change which item displays first and therefore becomes full width at the top of the layout, with the other items displaying below it.
The items are displayed in what is described in the specification as order-modified document order. The value of the order property is taken into account before the items are displayed.
Order also changes the paint order of the items; items with a lower value for order
will be painted first and those with a higher value for order
painted afterwards.
The order property and accessibility
Use of the order
property has exactly the same implications for accessibility as changing the direction with flex-direction
. Using order
changes the order in which items are painted, and the order in which they appear visually. It does not change the sequential navigation order of the items. Therefore if a user is tabbing between the items, they could find themselves jumping around your layout in a very confusing way.
By tabbing around any of the live examples on this page, you can see how order
is potentially creating a strange experience for anyone not using a pointing device of some kind. To read more about this disconnect of visual order and logical order and some of the potential problems it raises for accessibility, see the following resources.
- Flexbox and the keyboard navigation disconnect
- HTML Source Order vs CSS Display Order
- The Responsive Order Conflict for Keyboard Focus
Use cases for order
There are sometimes places where the fact that the logical and therefore reading order of flex items is separate from the visual order, is helpful. Used carefully the order
property can allow for some useful common patterns to be easily implemented.
You might have a design, perhaps a card that will display a news item. The heading of the news item is the key thing to highlight and would be the element that a user might jump to if they were tabbing between headings to find the content they wanted to read. The card also has a date; the finished design we want to create is something like this.
Visually the date appears above the heading, in the source. However, if the card was read out by a screen reader I would prefer that the title was announced first and then the publication date. We can make this so using the order
property.
The card is going to be our flex container, with flex-direction
set to column. I then give the date an order
of -1
. This pulls it up above the heading.
These small tweaks are the sort of cases where the order
property makes sense. Keep the logical order as the reading and tab order of the document, and maintain that in the most accessible and structured fashion. Then use order
for purely visual design tweaks. When doing so take care that you are not reordering items that could be accessed by the keyboard as a user is tabbing around. Especially when using newer layout methods you should ensure that your browser testing includes testing the site using only a keyboard, rather than a mouse or a touchscreen. You will quickly see if your development choices make getting around the content difficult.
- order
Flexbox (флексбокс) предназначен для вёрстки гибких макетов. Ежели свойство display
контейнера принимает значение flex
, его прямые потомки становятся flex-элементами, порядком следования которых можно управлять с помощью свойств flex-flow
и order
.
order
0 0 1 2 1 2 3 4 |
||
initial
|
0
|
|
---|---|---|
inherit
|
наследует значение родителя | |
unset
|
0
|
<style> .raz { display: flex; flex-flow: wrap; background: green; } .raz div { margin: .5em; padding: 1em; background: rgb(255, 255, 0); } .raz div:nth-child(2) { order: 0; background: red; } .raz div:nth-child(3) { order: 1; } .raz div:nth-child(4) { order: 2; } </style> <div class="raz"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div>
Если у flex-элементов одинаковое значение order
, то нижние в коде теги показаны после верхних (поведение по умолчанию)
<style> .raz { display: flex; flex-flow: wrap; background: green; } .raz div { margin: .5em; padding: 1em; background: rgb(255, 255, 0); order: 3; } </style> <div class="raz"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </div>
Чем меньше значение order
, тем раньше показан flex-элемент
Переместить 3-ий flex-элемент первым
<style> .raz { display: flex; flex-flow: wrap; background: green; } .raz div { margin: .5em; padding: 1em; background: rgb(255, 255, 0); } .raz div:nth-child(3) { order: -1; background: red; } </style> <div class="raz"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </div>
Поместить 3-ий flex-элемент последним
<style> .raz { display: flex; flex-flow: wrap; background: green; } .raz div { margin: .5em; padding: 1em; background: rgb(255, 255, 0); } .raz div:nth-child(3) { order: 1; background: red; } </style> <div class="raz"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </div>
Поставить flex-элемент с классом .ad
третьим
<style> .raz { display: flex; flex-flow: wrap; background: green; } .raz div { margin: .5em; padding: 1em; background: rgb(255, 255, 0); } .raz .ad { background: red; } .raz div:nth-child(n+3):not(.ad) { order: 1; } </style> <div class="raz"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div class="ad">5</div> <div>6</div> </div>
Поменять flex-элементы рандомно (хаотично, беспорядочно, случайным образом)
<style> .raz { display: flex; flex-flow: wrap; background: green; } .raz div { margin: .5em; padding: 1em; background: rgb(255, 255, 0); } .raz div:nth-child(1) { order: 1; } .raz div:nth-child(2) { order: 2; } .raz div:nth-child(3) { order: 3; } .raz div:nth-child(4) { order: 4; } .raz div:nth-child(5) { order: 5; } .raz div:nth-child(6) { order: 6; } </style> <div class="raz"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </div>
Свойство order
меняет только визуальный порядок
То есть по прежнему в порядке, указанном в HTML-коде, будет осуществляться
- сканирование/воспроизведение страницы программами чтения, поисковыми роботами,
- переход по ссылкам с помощью клавиши клавиатуры Tab, искл., Mozilla Firefox (можно менять с помощью атрибута
tabindex
).
Автор изображения [adrianroselli.com]
Пример: боковую колонку поменять местами с центральной с помощью CSS
длина окна:
<style> main { display: flex; flex-flow: wrap; padding: .5em 0 .5em .5em; text-align: center; color: #fff; background: #595959; } article, aside { margin-right: .5em; } aside { flex: 0 1 7em; order: -1; background: #3b3b3b; } article { flex: auto; background: #4b4b4b; } @media (max-width: 30em) { main { display: block; } } </style> <main> <article><code><article></code><br><br></article> <aside><code><aside></code></aside> </main>
Полное руководство по CSS flexbox. Это полное руководство объясняет все о flexbox, сосредотачиваясь на всех возможных свойствах для родительского элемента (контейнер flex) и дочерних элементов (элементы flex). Оно также включает в себя историю, демонстрации, шаблоны и таблицу поддержки браузеров.
Background
Модуль Flexbox Layout (Flexible Box) (W3C Candidate Recommendation от октября 2017 г.) направлен на обеспечение более эффективного способа размещения, выравнивания и распределения пространства между элементами в контейнере, даже если их размер неизвестен и / или динамичен (Flex значит «гибкий»).
Основная идея flex layout состоит в том, чтобы дать контейнеру возможность изменять ширину / высоту его элементов (и порядок), чтобы наилучшим образом заполнить доступное пространство (главным образом, для отображения на всех типах устройств с любым размером экрана). Flex контейнер расширяет элементы, чтобы заполнить доступное свободное пространство, или сжимает их, чтобы предотвратить переполнение.
Наиболее важно то, что макет flexbox не зависит от направления, в отличие от обычных макетов (block на вертикальной основе и inline на горизонтальной основе). Хотя они хорошо работают для страниц, им не хватает гибкости (без каламбура :-)) для поддержки больших или сложных приложений (особенно когда речь идет об изменении ориентации, изменении размера, растяжении, сжатии и т.д.).
Примечание: Flexbox layout наиболее подходит для компонентов приложения и мелкомасштабных макетов, а Grid layout предназначен для макетов большего масштаба.
Основы и терминология
Поскольку flexbox — это целый модуль, а не одно свойство, он включает в себя множество элементов с набором свойств. Некоторые из них предназначены для установки в контейнере (родительский элемент принято называть «flex контейнер»), в то время как другие предназначены для установки в дочерних элементах (так называемые «flex элементы»).
Если «обычная» компоновка основана как на блочном, так и на inline направлениях, flex layout основана на «направлениях flex-flow». Пожалуйста, посмотрите на этот рисунок из спецификации, объясняющий основную идею гибкого макета.
Элементы будут расположены либо в направлении главной оси (main axis от main-start до main-end) или в направлении поперечной оси (cross axis от cross-start до cross-end).
- main axis — главная ось flex контейнера — это основная ось, вдоль которой располагаются flex элементы. Будьте внимательны, эта ось не обязательно горизонтальная; это зависит от flex-direction свойства (см. ниже).
- main-start | main-end — flex элементы помещаются в контейнер, начиная с main-start и заканчивая main-end.
- main size — ширина или высота flex элемента, в зависимости от того, что находится в основном измерении. Определяется основным размером flex элементов т.е. свойством ‘width’ или ‘height’, в зависимости от того, что находится в основном измерении.
- cross axis — ось перпендикулярная главной оси, называется поперечной осью. Её направление зависит от направления главной оси.
- cross-start | cross-end — flex строки заполняются элементами и помещаются в контейнер, начиная от cross-start flex контейнера по направлению к cross-end.
- cross size — ширина или высота flex элемента. В зависимости от css свойства flex-direction, это ширина или высота элемента. Это всегда поперечный размер flex элементов.
Свойства для Родителя (flex контейнер)
display
Определяет flex контейнер; inline или block в зависимости от заданного значения. Включает flex контекст для всех потомков первого уровня.
.container {
display: flex; /* or inline-flex */
}
Имейте в виду:
Обратите внимание, что CSS-столбцы columns не влияют на flex контейнер.
flex-direction
Устанавливает основную ось, таким образом определяя направление flex элементов, помещаемых в flex контейнер. Flexbox — это (помимо дополнительной упаковки) концепция однонаправленного макета. Думайте о flex элементах, как о первичных раскладках в горизонтальных рядах или вертикальных столбцах.
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row (по умолчанию): слева направо в ltr; справа налево в rtl
- row-reverse справа налево ltr; слева направо в rtl
- column: так же, как и row но сверху вниз
- column-reverse: то же самое, row-reverse но снизу вверх
flex-wrap
По умолчанию гибкие элементы будут пытаться уместиться на одной строке. Вы можете изменить это и позволить элементам переходить на новую строку по мере необходимости с помощью этого свойства.
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
- nowrap (по умолчанию): все flex элементы будут в одной строке
- wrap: flex-элементы будут перенесены на несколько строк сверху вниз.
- wrap-reverse: flex-элементы будут перенесены на несколько строк снизу вверх.
Посмотреть визуальные демоверсии поведения flex-wrap можно здесь.
flex-flow (Применяется к: родительскому элементу flex-контейнера)
Это сокращение для flex-direction и flex-wrap свойств, которые вместе определяют основные и поперечные оси flex контейнера. Значением по умолчанию является row nowrap.
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
justify-content
Это свойство определяет выравнивание вдоль главной оси. Оно помогает распределить дополнительный остаток свободного пространства, когда-либо все flex элементы в строке негибкие, либо гибкие, но достигли своего максимального размера. Это также обеспечивает некоторый контроль над выравниванием элементов, когда они переполняют линию.
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}
- flex-start (по умолчанию): элементы сдвинуты в начало flex-direction направления.
- flex-end: элементы сдвинуты ближе к концу flex направления.
- start: элементы сдвинуты к началу writing-mode направления.
- end: элементы сдвинуты в конце writing-mode направления.
- left: элементы сдвинуты по направлению к левому краю контейнера, если это не имеет смысла flex-direction, тогда он ведет себя как start.
- right: элементы сдвинуты по направлению к правому краю контейнера, если это не имеет смысла flex-direction, тогда он ведет себя как start.
- center: элементы центрированы вдоль линии
- space-between: элементы равномерно распределены по линии; первый элемент находится в начале строки, последний элемент в конце строки
- space-around: элементы равномерно распределены по линии с одинаковым пространством вокруг них. Обратите внимание, что визуально пространства не равны, так как все элементы имеют одинаковое пространство с обеих сторон. Первый элемент будет иметь одну единицу пространства напротив края контейнера, но две единицы пространства между следующим элементом, потому что у следующего элемента есть свой собственный интервал, который применяется.
- space-evenly: элементы распределяются таким образом, чтобы расстояние между любыми двумя элементами (и расстояние до краев) было одинаковым.
Обратите внимание, что поддержка браузером этих значений имеет свои нюансы. Например, space-between никогда не получал поддержку Edge, а start / end / left / right еще нет в Chrome. В MDN есть подробные графики. Самые безопасные значения это flex-start, flex-end и center.
Есть также два дополнительных ключевых слова, которые вы можете связать с этими значениями: safe и unsafe. Использование safe гарантирует, что как бы вы ни занимались этим типом позиционирования, вы не сможете расположить элемент таким образом, чтобы он отображался за пределами экрана (например, сверху) так, чтобы содержимое тоже не могло быть прокручено (это называется «потеря данных»).
align-items
Это свойство определяет поведение по умолчанию того, как flex элементы располагаются вдоль поперечной оси на текущей линии. Думайте об этом как о justify-content версии для поперечной оси (перпендикулярной главной оси).
.container {
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}
- stretch (по умолчанию): растягивать, чтобы заполнить контейнер (все еще соблюдаются min-width / max-width)
- flex-start / start / self-start: элементы размещаются в начале поперечной оси. Разница между ними невелика и заключается в соблюдении flex-direction правил или writing-mode правил.
- flex-end / end / self-end: элементы располагаются в конце поперечной оси. Разница опять-таки тонкая и заключается в соблюдении flex-direction или writing-mode правил.
- center: элементы центрированы по поперечной оси
- baseline: элементы выровнены, по их базовой линии
safe и unsafe ключевые слова модификаторов могут быть использованы в сочетании со всеми из этих ключевых слов (хотя это поддерживается не всеми браузерами), это помогает предотвратить выравнивание элементов таким образом, что содержание становится недоступным.
align-content
Это свойство выравнивает линии в пределах flex контейнера, когда есть дополнительное пространство на поперечной оси, подобно тому, как justify-content выравнивает отдельные элементы в пределах главной оси.
Примечание: это свойство не действует, когда есть только одна строка flex элементов.
.container {
align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}
- flex-start / start: элементы, сдвинуты в начало контейнера. Более поддерживаемый flex-start использует, flex-direction в то время как start использует writing-mode направление.
- flex-end / end: элементы, сдвинуты в конец контейнера. Более поддерживаемый flex-end использует flex-direction в то время как end использует writing-mode направление.
- center: элементы выровнены по центру в контейнере
- space-between: элементы равномерно распределены; первая строка находится в начале контейнера, а последняя — в конце
- space-around: элементы равномерно распределены с равным пространством вокруг каждой строки
- space-evenly: элементы распределены равномерно, вокруг них одинаковое пространство
- stretch (по умолчанию): линии растягиваются, чтобы занять оставшееся пространство
safe и unsafe ключевые слова модификаторов могут быть использованы в сочетании со всеми из этих ключевых слов (хотя это поддерживается не всеми браузерами), это помогает предотвратить выравнивание элементов таким образом, что содержание становится недоступным.
Свойства для первых дочерних элементов(flex элементы)
order
По умолчанию flex элементы располагаются в исходном порядке. Однако свойство order управляет порядком их появления в контейнере flex.
.item {
order: <integer>; /* default is 0 */
}
flex-grow
Это свойство определяет способность flex элемента растягиваться в случае необходимости. Оно принимает значение от нуля, которое служит пропорцией. Это свойство, какое количество доступного пространства внутри гибкого контейнера должен занимать элемент.
Если для всех элементов flex-grow установлено значение 1, оставшееся пространство в контейнере будет равномерно распределено между всеми дочерними элементами. Если один из дочерних элементов имеет значение 2, этот элемент займет в два раза больше места, чем остальные (или попытается, по крайней мере).
.item {
flex-grow: <number>; /* default 0 */
}
Отрицательные числа не поддерживаются.
flex-shrink
Это свойство определяет способность гибкого элемента сжиматься при необходимости.
.item {
flex-shrink: <number>; /* default 1 */
}
Отрицательные числа не поддерживаются.
flex-basis
Это свойство определяет размер элемента по умолчанию перед распределением оставшегося пространства. Это может быть длина (например, 20%, 5rem и т.д.) Или ключевое слово. Ключевое слово auto означает «смотри на мое width или height свойство». Ключевое слово content означает «размер на основе содержимого элемента» — это ключевое слово все еще не очень хорошо поддерживается, так что трудно проверить что для него используется max-content, min-content или fit-content.
.item {
flex-basis: <length> | auto; /* default auto */
}
Если установлено значение 0, дополнительное пространство вокруг содержимого не учитывается. Если установлено значение auto, дополнительное пространство распределяется в зависимости от его flex-grow значения.
Смотрите этот рисунок.
flex
Это сокращение для использования flex-grow, flex-shrink и flex-basis вместе. Второй и третий параметры (flex-shrink и flex-basis) являются необязательными. По умолчанию это 0 1 auto.
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
Рекомендуется использовать это сокращенное свойство, а не устанавливать отдельные свойства. Это сокращение разумно устанавливает другие значения.
align-self
Это свойство позволяет переопределить выравнивание по умолчанию (или указанное с помощью align-items) для отдельных элементов flex.
Пожалуйста, смотрите align-items свойство, чтобы понять доступные значения.
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
Обратите внимание что свойства float, clear и vertical-align не влияют на flex элементы.
Примеры
Давайте начнем с очень простого примера, решающего почти ежедневную проблему: идеальное центрирование. Самое простое решение для этой задачи — это использовать flexbox.
.parent {
display: flex;
height: 300px; /* Или что угодно */
}
.child {
width: 100px; /* Или что угодно */
height: 100px; /* Или что угодно */
margin: auto; /* Магия! */
}
Так происходит благодаря тому, что свойство вертикального выравнивания margin установленное в auto во flex контейнере, поглощает дополнительное пространство. Таким образом, установка margin в auto сделает объект идеально отцентрированным по обеим осям.
Теперь давайте используем еще несколько свойств. Рассмотрим список из 6 элементов, все с фиксированными размерами, но могут быть и авторазмеры. Мы хотим, чтобы они были равномерно распределены по горизонтальной оси, чтобы при изменении размера браузера все масштабировалось хорошо и без медиа запросов.
.flex-container {
/* Сначала мы создаем flex контекст */
display: flex;
/* Затем мы определяем flex-direction и разрешаем элементам переходить на новые строки
* Запомните, что это то же самое что и:
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
/* Затем мы определяем, как распределяется оставшееся пространство */
justify-content: space-around;
}
Готово. Все остальное — это просто стайлинг.
Если изменить разрешение экрана ли масштаб, то будет так:
Давайте попробуем что-нибудь еще. Представьте, что у нас есть выровненные по правому краю элементы навигации в верхней части нашего веб-сайта, но мы хотим, чтобы они были выровнены по ширине на экранах среднего размера и располагались в один столбец на небольших устройствах. Это достаточно просто.
/* Большие экраны */
.navigation {
display: flex;
flex-flow: row wrap;
/* Это выровняет элементы по конечной части линии на главной оси */
justify-content: flex-end;
}
/* Средние экраны */
@media all and (max-width: 800px) {
.navigation {
/* На экранах среднего размера мы центрируем элементы, равномерно распределяя пустое пространство вокруг элементов */
justify-content: space-around;
}
}
/* Маленькие экраны */
@media all and (max-width: 500px) {
.navigation {
/* На маленьких экранах мы больше не используем направление строки, а используем столбец */
flex-direction: column;
}
}
Большие экраны
Средние экраны
Маленькие экраны
Давайте попробуем что-то еще лучше, играя с гибкостью flex элементов! Как насчет 3-колоночного макета в полную высоту страницы с хедором и футером. И не зависит от исходного порядка элементов.
.wrapper {
display: flex;
flex-flow: row wrap;
}
/* Мы говорим, что все элементы имеют ширину 100%, через flex-base */
.wrapper > * {
flex: 1 100%;
}
/* Мы используем исходный порядок для первого мобильно варианта
* 1. header
* 2. article
* 3. aside 1
* 4. aside 2
* 5. footer
*/
/* Средние экраны */
@media all and (min-width: 600px) {
/* Мы говорим обеим боковым панелям встать в одну строку */
.aside { flex: 1 auto; }
}
/* Большие экраны */
@media all and (min-width: 800px) {
/* Мы инвертируем порядок первой боковой панели и основной и говорим главному элементу, чтобы он занимал вдвое большую ширину, чем две другие боковые панели
*/
.main { flex: 2 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
Большие экраны
Средние экраны
Маленькие экраны
Префикс для Flexbox
Flexbox требует префикса для лучшей поддержки в разных браузерах. Он не только включает в себя предварительные настройки с префиксом вендора, в нем есть совершенно разные имена свойств и значений. Это связано с тем, что спецификации Flexbox со временем менялись, существуют «старые», «tweener» и «новые» версии.
Возможно, лучший способ справиться с этим — написать новый (и последний) синтаксис и запустить свой CSS через Autoprefixer, который очень хорошо справляется с fallback.
Кроме того, вот Sass @mixin, чтобы помочь с некоторыми префиксами, который также дает вам представление о том, что нужно сделать:
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}
Ошибки
Flexbox, конечно, не без ошибок. Лучшая коллекция из них, которую я видел, — это Flexbugs Филипа Уолтона и Грега Витворта. Это репозиторий с открытым исходным кодом для отслеживания всех из них, поэтому я думаю, что лучше всего просто сослаться на него.
Поддержка в браузерах
Разбита по «версии» flexbox:
- (new) означает недавний синтаксис из спецификации (например display: flex;)
- (tweener) означает странный неофициальный синтаксис с 2011 года (например display: flexbox;)
- (old) означает старый синтаксис с 2009 года (например display: box;)
Blackberry Browser 10+ поддерживает новый синтаксис.
Для получения дополнительной информации о том, как смешивать синтаксисы, чтобы получить лучшую поддержку браузера, пожалуйста, обратитесь к этой статье (CSS-хитрости) или этой статье (DevOpera).
В этой статье познакомимся с технологией CSS Flexbox, предназначенной для создания гибких макетов веб-страниц.
CSS Flexbox предназначен для создания гибких макетов. С помощью этой технологии можно очень просто и гибко расставить элементы в контейнере, распределить доступное пространство между ними, и выровнять их тем или иным способом даже если они не имеют конкретных размеров.
CSS Flexbox позволяет создать адаптивный дизайн намного проще, чем с использованием Float и позиционирования.
Flexbox можно использовать как для CSS разметки целой страницы, так и её отдельных блоков.
Поддержка CSS Flexbox браузерами
CSS Flexbox поддерживается всеми используемые на сегодняшний момент современными браузерами (с использованием префиксов: IE10+, Edge12+, Firefox 2+, Chrome 4+, Safari 3.1+, Opera 12.1+, iOS Safari 3.2, Opera mini, Android 2.1+, Blackberry 7+).
Основы CSS Flexbox
Создание CSS разметки с помощью Flexbox начинается с установки необходимому HTML элементу CSS-свойства display
со значением flex
или flex-inline
.
После этого данный элемент становится flex-контейнером, а все его непосредственные дочерние элементы – flex-элементами. При этом когда мы говорим о flexbox то подразумеваем под этим только элемент с display:flex
или display:flex-inline
и все элементы непосредственно расположенные в нём. Таким образом в CSS Flexbox имеется всего два типа элементов: flex-контейнер и flex-элемент.
<style> .flex-container { display: flex; /* flex || inline-flex */ } <style> <!-- flex-контейнер --> <div class="flex-container"> <div>flex-элемент #1</div> <div>flex-элемент #2</div> <div>flex-элемент #3</div> </div>
По умолчанию flex-элементы во flex-контейнере занимают всю его высоту.
Значение flex
или flex-inline
определяет то, как flex-контейнер будет представлен на странице. Если его необходимо отобразить в виде блока, то используйте значение flex
. Если элемент необходимо представить как строку, то используйте значение flex-inline
. В этом случае он будет занимать столько места странице, сколько необходимо для отображения его элементов.
Устройство flex-контейнера. Направление осей
На рисунке представлена схема устройства flex-контейнера:
Направление расположение flex-элементы в flex-контейнере определяется посредством осей.
В CSS Flexbox имеются две оси. Первая ось называется главной (по умолчанию она направлена слева направо). Вторая — поперечная (по умолчанию направлена сверху вниз), она всегда перпендикулярно главной. Главная ось задаёт основное направление flex-элементов во flex-контейнере, а поперечная ось определяет их направление при переносе на новую линию.
По умолчанию элементы во flex-контейнере располагаются вдоль направления главной оси (т.е. слева направо) на одной линии.
Направление главной оси можно изменить, осуществляется это с помощью CSS-свойства flex-direction
.
flex-direction: row; /* row (слева направо) - по умолчанию row-reverse (справа налево) column (сверху вниз) column-reverse (снизу вверх) */
С помощью этого свойства можно сделать так, чтобы flex-элементы располагались не рядами (rows), а колонками (columns). Осуществляется это с помощью значения column
или column-reverse
.
По умолчанию flex-элементы не переносятся на новую линию, даже когда им не хватает места в текущей линии. Они просто выходят за её пределы.
Но это можно изменить. Разрешить перенос flex-элементов на новые линии осуществляется с помощью установки flex-контейнеру CSS свойства flex-wrap
со значением wrap
или wrap-reverse
.
flex-wrap: wrap; /* nowrap (только на одной линии - по умолчанию) wrap (разрешить перенос flex-элементов на новые линии) wrap-reverse (осуществлять перенос flex-элементов в обратном порядке) */
Значения wrap
и wrap-reverse
CSS-свойства flex-wrap
определяют направление поперечной оси.
Свойства flex-direction
и flex-wrap
можно указать с помощью универсального CSS свойства flex-flow
:
flex-flow: row nowrap; /* 1 значение - flex-direction, 2 значение - flex-wrap */
Выравнивание flex-элементов
Во Flexbox выравнивание элементов внутри контейнера осуществляется по двум направлениям (осям).
Выравнивание flex-элементов по направлению главной оси
Выравнивание элементов вдоль основной оси осуществляется с помощью CSS свойства justify-content
:
justify-content: flex-start; /* flex-start (flex-элементы выравниваются относительно начала оси) – по умолчанию flex-end (flex-элементы выравниваются относительно конца оси) center (по центру flex-контейнера) space-between (равномерно, т.е. с одинаковым расстоянием между flex-элементами) space-around (равномерно, но с добавлением половины пространства перед первым flex-элементом и после последнего) */
Выравнивание flex-элементов вдоль поперечной оси
Выравнивание flex-элементов во flex-контейнере по направлению поперечной оси осуществляется с помощью CSS-свойства align-items
:
align-items: stretch; /* stretch (растягиваются по всей длине линии вдоль направления поперечной оси) – по умолчанию flex-start (располагаются относительно начала поперечной оси) flex-end (относительно конца поперечной оси) baseline (относительно базовой линии) center (по центру) */
Выравнивание линий flex-контейнера
CSS Flexbox позволяет выравнивать не только сами flex-элементы, но и линии на которых они расположены.
align-content: stretch /* stretch (растягиваются по всей длине поперечной оси) – по умолчанию flex-start (относительно начала поперечной оси) flex-end (относительно конца поперечной оси) center (по центру) space-between (равномерно, т.е. с одинаковым расстоянием между линиями) space-around (равномерно, но с добавлением половины пространства перед первой линией и после последней) */
Свойство align-content
имеет смысл использовать только тогда, когда flex-элементы во flex-контейнере располагаются на нескольких линиях. Чтобы это произошло, необходимо, во-первых, чтобы ширина всех flex-элементов была больше ширины flex-контейнера, а во-вторых flex-контейнер должен иметь в качестве CSS-свойства flex-wrap
значение wrap
или wrap-reverse
.
CSS-свойство align-self
Свойство align-self
в отличие от предыдущих (justify-content
, align-items
и align-content
) предназначено для flex-элементов. Оно позволяет изменить выравнивание flex-элемента вдоль направления поперечной оси. Свойство align-self
может принимать такие же значения как align-items
.
align-items: stretch; /* auto (по умолчанию) || stretch || flex-start || flex-end || baseline || center */
Пример:
<div class="flex-container"> <div class="flex-container_element-1"> 1 </div> <div class="flex-container_element-2"> 2 </div> <div class="flex-container_element-3"> 3 </div> <div class="flex-container_element-4"> 4 </div> </div>
CSS:
.flex-container { display: flex; width: 300px; height: 150px; align-items: center; padding: 10px; background-color: #efefef; } .flex-container_element-1, .flex-container_element-2, .flex-container_element-3, .flex-container_element-4 { flex-basis: 70px; text-align: center; padding: 15px; font-size: 30px; } .flex-container_element-1 { align-self: flex-start; background: #fe4; } .flex-container_element-2 { align-self: flex-end; background: pink; } .flex-container_element-3 { align-self: stretch; background: lime; } .flex-container_element-4 { align-self: auto; background: cyan; }
Изменение порядка следования flex-элементов
По умолчанию flex-элементы отображаются во flex-контейнере в том порядке, в котором они расположены в HTML коде. Для изменения порядка следования одних flex-элементов относительно других в CSS Flexbox можно использовать свойство order
. Данное CSS свойство выстраивает flex-элементы во flex-контейнере в порядке возрастания их номеров.
order: 0; /* 0 (по умолчанию) целое положительное или отрицательное число */
Например:
<div class="flex-container"> <div class="flex-container_element-1">...</div> <div class="flex-container_element-2">...</div> <div class="flex-container_element-3">...</div> <div class="flex-container_element-4">...</div> </div> CSS: .flex-container { display: flex; } /* переместим 2 flex-элемент в конец */ .flex-container_element-2 { order: 2; } /* передвинем 3 элемент до 2 */ .flex-container_element-3 { order: 1; } /* расположим 4 flex-элемент до 1 */ .flex-container_element-4 { order: -1; }
Управление шириной flex-элемента
Во Flexbox есть несколько CSS свойств, определяющих то, какая ширина может быть у flex-элемента.
CSS-свойство flex-basis
Данное свойство предназначено для установления начальной ширины flex-элементу. Задавать значение ширины можно посредством различных единиц измерения, таких как px, %, em и др. По умолчанию данное свойство имеет значение auto
(в этом случае ширина элемента будет рассчитываться автоматически на основании его содержимого).
Конечная ширина flex-элемента будет определяться в зависимости от значений CSS-свойств flex-grow
и flex-shrink
, которые установлены не только для этого элемента, но и для других flex-элементов этого flex-контейнера.
CSS-свойство flex-grow
Это свойство определяет, может ли начальная ширина flex-элемента увеличиваться (расти). Увеличение ширины flex-элемента осуществляется за счёт свободного пространства линии. В качестве значения CSS-свойства flex-grow
указывается целое число. Именно это значение и определяет (если оно больше или равно 1) какую часть свободного пространства flex-элемент заберёт себе.
Например:
<div class="flex-container"> <div class="flex-container_element-1">...</div> <div class="flex-container_element-2">...</div> </div> CSS: .flex-container { display: flex; width: 600px; } .flex-container_element-1 { flex-basis: 40%; flex-grow: 1; } .flex-container_element-2 { flex-basis: 40%; flex-grow: 4; }
В этом примере, если flex-элементы расположены на одной линии и в ней есть свободное пространство (600×(1-0,8)=120px):
- к ширине элемента
.flex-container_element-1
добавится 1/5 часть этого пространства (120×1/5=24px); - к ширине элемента
.flex-container_element-2
добавится 4/5 части этого пространства (120×4/5=96px).
Другими словами, CSS свойство flex-grow
позволяет не просто указать, что ширина flex-элемента может вырасти, но и задать, насколько эта величина может вырасти по отношению к другим элементам.
По умолчанию CSS свойство flex-grow имеет значение 0. Это означает, что flex-элемент не может расти (увеличивать свою ширину).
CSS-свойство flex-shrink
Данное свойство определяет, может ли ширина flex-элемента уменьшиться. Уменьшение ширины flex-элемента будет осуществляться только в том случае, если ширины линии будет не достаточно для отображения всех flex-элементов, расположенных в ней. Необходимая ширина рассчитывается на основании начальной ширины, который имеет каждый flex-элемент в ней.
Например:
<div class="flex-container"> <div class="flex-container_element-1">...</div> <div class="flex-container_element-2">...</div> </div> CSS: .flex-container { display: flex; width: 500px; } .flex-container_element-1 { flex-basis: 300px; flex-shrink: 1; } .flex-container_element-2 { flex-basis: 300px; flex-shrink: 3; }
Ширина flex-контейнера 500px. Для отображения flex-элементов необходимо 600px. В итоге не хватает 100px. В этом примере уменьшаться могут 2 flex-элемента (.flex-container_element-1
и .flex-container_element-2
). Ширина первого flex-элемента .flex-container_element-1
в данном случае составит 300 – 1/4*100= 275px. Ширина второго flex-элемента .flex-container_element-2
в данном случае составит 300 – 3/4*100= 225px.
Значение по умолчанию:
flex-shrink: 1;
Если вам необходимо запретить уменьшение ширины flex-элементу, то в качестве значения свойства flex-shrink
необходимо указать число 0.
CSS-свойство flex
Для удобной установки flex-grow
, flex-shrink
и flex-basis
можно использовать CSS свойство flex
.
Значение по умолчанию:
flex: 0 1 auto; /* 0 - flex-grow (1 значение) 1 - flex-shrink (2 значение) auto - flex-basis (3 значение) */
Пример верстки макета на CSS Flexbox
В этом разделе создадим простой адаптивный макет всей страницы на CSS Flexbox.
Структура макета будет состоять из 3 секций:
- header (для вывода заголовка и основного меню);
- main (для отображения основной части);
- footer (для футера).
Основную часть (main) в свою очередь разделим ещё на 2 раздела (их позиционирование будем осуществлять с помощью CSS Flexbox). На больших экранах (>=992px) эти разделы выстроим горизонтально, а на остальных — вертикально (<992px).
<style> /* контейнер */ .container { width: 100%; max-width: 1200px; padding-right: 15px; padding-left: 15px; margin-left: auto; margin-right: auto; } /* flex-контейнер */ .row { display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; } /* общие настройки для flex-элементов */ .col { position: relative; width: 100%; padding-right: 15px; padding-left: 15px; } /* ширина блоков .col__article и .col__aside по умолчанию */ .col__article, .col__aside { -ms-flex: 0 0 100%; flex: 0 0 100%; max-width: 100%; } /* ширина блоков .col__article и .col__aside для больших экранов */ @media (min-width: 992px) { /* 2/3 от ширины контейнера */ .col__article { -ms-flex: 0 0 66.666667%; flex: 0 0 66.666667%; max-width: 66.666667%; } /* 1/3 от ширины контейнера */ .col__aside { -ms-flex: 0 0 33.333333%; flex: 0 0 33.333333%; max-width: 33.333333%; } } </style> <header class="container"> <!-- Шапка страницы --> </header> <main class="container"> <div class="row"> <article class="col col__article"> <!-- Основная часть --> </article> <aside class="col col__aside"> <!-- Боковая область --> </aside> </div> </main> <footer class="container"> <!-- Футер --> </footer>
В CSS для поддержки макета большинством браузеров добавлены свойства с префиксами и max-width
.
Для «превращения» блока во flex-контейнер используется класс row
. Установку ширины flex-элементам .col__article
и .col__aside
внутри flex-контейнера выполнено с использованием CSS-свойства flex
.
В качестве примера разметим посредством flexbox ещё футер и создадим в элементе .col__article
блок состоящий из трёх элементов (минимальная ширина одного элемента — 300px). В футере разместим четыре блока (минимальная ширина одного блока — 200px).
<style> /* ... */ .col__other-article { -ms-flex: 1 0 0; flex: 1 0 0; min-width: 300px; } .col__footer { -ms-flex: 1 0 0; flex: 1 0 0; min-width: 200px; } </style> <header class="container"> <!-- Шапка страницы --> </header> <main class="container"> <div class="row"> <article class="col col__article"> <!-- Основная часть --> <div class="row"> <div class="col col__other-article"> <!-- Ещё 1 --> </div> <div class="col col__other-article" style="padding-bottom: 15px;"> <!-- Ещё 2 --> </div> <div class="col col__other-article" style="padding-bottom: 15px;"> <!-- Ещё 3 --> </div> </div> </article> <aside class="col col__aside"> <!-- Боковая область --> </aside> </div> </main> <footer class="container"> <div class="row"> <div class="col col__footer"> <!-- Секция футера 1 --> </div> </div> <div class="row"> <div class="col col__footer"> <!-- Секция футера 2 --> </div> </div> <div class="row"> <div class="col col__footer"> <!-- Секция футера 3 --> </div> </div> <div class="row"> <div class="col col__footer"> <!-- Секция футера 4 --> </div> </div> </footer>
- Марат Таналин
- Опубликовано:
- 2011-06-05
- Обновлено:
- 2017-06-28
- Краткое описание
- Кроссбраузерный способ полноценной вертикальной перестановки блоков произвольной высоты средствами CSS.
Современные браузеры — Flexbox
Произвольный порядок
В современных браузерах (в том числе Internet Explorer 11 и Edge) управлять визуальным порядком элементов можно с помощью CSS-свойства order
, являющегося частью механизма Flexbox. Блоки следуют в порядке возрастания значений свойства order
. Значением свойства order
должно быть целое число, которое может быть как положительным, так и отрицательным. Значение по умолчанию — 0
.
- HTML:
<div class="example">
<div class="a">Первый</div>
<div class="b">Второй</div>
<div class="c">Третий</div>
</div>
- CSS:
.example {
display: flex;
flex-direction: column;
}.example > .a {order: 3; } /* Отобразится третьим */
.example > .b {order: 2; } /* Отобразится вторым */
.example > .c {order: 1; } /* Отобразится первым */
Объявление display: flex
включает Flexbox для элемента-контейнера. Объявление flex-direction: column
задаёт вывод дочерних элементов контейнера друг под другом вместо горизонтального вывода, используемого во Flexbox по умолчанию.
Вертикальное положение переупорядочиваемых является взаимозависимым: увеличение высоты любого из блоков приводит к автоматическому вертикальному сдвигу визуально следующих за ним блоков, в том числе при динамическом изменении высоты блоков, например, вследствие увеличения размера шрифта средствами браузера.
Обратный порядок
Если требуется просто вывести элементы в обратном порядке, можно использовать объявление flex-direction: column-reverse
для содержащего их контейнера без необходимости явно задавать расположение каждого элемента:
.example {
display: flex;
flex-direction: column-reverse;
}
Устаревшие браузеры — display: table
В браузерах, не поддерживающих Flexbox (IE 10 и ниже), вертикальный порядок следования блоков на HTML-странице можно изменить, придав им табличное представление при помощи CSS-свойств семейства display: table
. Вне зависимости от порядка расположения блоков в HTML-коде, «шапка» (display: table-header-group
) такой таблицы отображается в её верхней части, «подвал» (table-footer-group
) — в нижней, а основная часть таблицы (table-row-group
) — между ними.
.example {
display: table;
width: 100%;
}
.example > .a {display: table-footer-group; } /* Отобразится внизу псевдотаблицы */
.example > .b {display: table-row-group; } /* Отобразится посередине */
.example > .c {display: table-header-group; } /* Отобразится вверху */
Описанным образом можно изменять порядок до трёх соседних блоков. Дополнительно можно задействовать display: table-caption
(отображение блока в роли подписи к таблице) в сочетании с CSS-свойством caption-side
со значением top
или bottom
.
Метод работает в большинстве распространённых браузеров, в том числе в Internet Explorer начиная с версии 9 (IE8 — с оговорками, см. далее).
Internet Explorer 6, 7 и 8 — DOM
Устаревшие браузеры IE6 и IE7 не поддерживают CSS-свойства семейства display: table*
.
Кроме того, в IE8 в некоторых случаях наблюдается динамическая ошибка рендеринга: если перемещаемый блок содержит в себе псевдотабличные элементы (display: table*
) (проявление нюанса замечено только в этом случае), возможно спонтанное пропадание некорых ячеек (всегда разных и в разном количестве) псевдотаблицы при первичной отрисовке страницы.
Поэтому для IE8 и ниже можно отменить CSS-правила, придающие блокам табличный вид, и дополнительно переместить блоки в нужные позиции DOM-дерева HTML-документа уже с помощью JavaScript:
/**
* Перестраивает соседние элементы в DOM-дереве в заданном порядке.
* @param {Array} elems Соседние элементы в необходимом порядке.
*/
function reorderElements(elems) {
// http://tanalin.com/articles/css-block-order/
var count = elems.length;
if (!count) {
return;
}
var parent = elems[0].parentNode;
for (var i = count - 1; i >= 0; i--) {
parent.insertBefore(elems[i], parent.firstChild);
}
}
Определение возможностей браузера
Использовать разные стили для современных и устаревших браузеров можно путём определения возможностей браузера средствами JavaScript.
Определить, поддерживает ли браузер Flexbox, можно путём проверки существования свойства order
объекта, доступного через свойство style
корневого элемента документа (<html></html>
) — document.documentElement
.
Версию Internet Explorer можно определить путём проверки существования нестандартного объекта document.all
, доступного только в IE 10 и ниже, в сочетании с существованием или отсутствием одного из стандартных объектов.
if ('order' in document.documentElement.style) {
// Flexbox-совместимый браузер.
// Используем `order` или `flex-direction: column-reverse`.
}
else if (document.all && !document.addEventListener) {
// IE8 или ниже.
// Изменяем реальный порядок блоков в DOM-дереве средствами JS.
}
else {
// Браузер без поддержки Flexbox, в том числе IE 9/10.
// Используем `display: table`.
}
CSS Flexbox позволяет размещать и упорядочивать элемент по горизонтали и вертикали, что делает веб-страницу гибкой и простой для понимания. Flexbox — то не просто свойство, это модуль макета CSS.
- CSS Flexbox — это модуль компоновки CSS , который используется для упорядочивания элементов на веб-страницах в одном направлении, т. е. по горизонтали и вертикали.
- Помогает создавать отзывчивые макеты, где мы можем настраивать гибкие элементы внутри flex-контейнера.
- Используется для заполнения дополнительного доступного пространства или уменьшения размера содержимого, если оно переполняется.
Синтаксис:
display: flex;
Рассмотрим пример. Расположим боксы внутри flex-контейнера:
<div class="container container--flex">
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
</div>
Контейнеру присвоим свойство display со значением flex:
.container--flex {
display: flex;
}
Боксы будут располагаться по горизонтали слева — направо по умолчанию:
Основы и термины CSS Flexbox
Flexbox не является свойством. Это встроенный модуль CSS, который сам имеет множество свойств. Например, свойство flex-direction помогает выравнивать элемент в нужном направлении. Давайте разберемся с некоторыми базовыми терминами CSS flexbox и узнаем, как он работает.
Основные термины CSS Flexbox:
- Flex Container — используется как контейнер для flex-элементом (flex-items). Чтобы сделать контейнер гибким, мы устанавливаем свойство display как flex.
- Главная ось — используется в качестве основной оси для flex-контейнера для выравнивания flex-элементов. Вдоль основной оси выравниваются все flex-элементы. Устанавливается с помощью свойства flex-direction.
- Поперечная ось — всегда перпендикулярна главной оси.
- Основной размер — обозначает ширину и высоту гибкого контейнера, которые зависят от основной оси.
- Перекрестный размер — обозначает ширину и высоту гибких элементов, которые находятся в поперечном измерении.
Давайте более подробно разберем основную ось. Она может иметь следующие направления:
- Слева направо. flex-direction: row.
- Справа налево. flex-direction: row-reverse.
- Снизу вверх. flex-direction: column.
- Сверху вниз. flex-direction: column-reverse.
Поперечная ось всегда перпендикулярна основной. Чтобы поменять направление основной оси на противоположное используется reverse:
Как работает CSS Flexbox
- Flexbox работает с сеткой осей, как показано на изображении выше.
- Используя flexbox, мы можем изменить порядок элементов без изменения исходного кода.
- Flexbox помогает контролировать свободное пространство. Если осталось место, то гибкие элементы увеличиваются, чтобы заполнить доступное пространство. Если места не осталось, то flex-элементы сживаются, чтобы предотвратить переполнение.
- Flex-элементы можно располагать в любом направлении.
Свойства для flex-контейнера
В таблице показаны свойства CSS flexbox с их значениями. Вы можете использовать его в качестве справочного материала при работе над проектами.
Свойство | Возможные значения |
---|---|
display | flex |
flex-direction | row | row-rewerse | column | column-reverse |
justify-content | flex-start | flex-end | center | space-between | space-around |
align-items | baseline | flex-start | flex-end | center | scretch |
align-content | flex-start | flex-end | center | scretch |
align-self | auto | flex-start | flex-end | center | baseline |
flex-grow | числовое значение |
flex-shrink | числовое значение |
order | числовое значение |
Отображение flex-элементов
Чтобы создать flex-контейнер мы задаем элементу следующее свойство:
display: flex;
Давайте рассмотрим на простом примере создание навигационного меню:
HTML:
<div class="container">
<ul class="menu">
<li><a href="#">Home</a></li>
<li><a href="#">Prices</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
CSS:
.menu {
display: flex;
}
.menu > li {
margin-right: 10px;
}
Получим результат:
Как мы говорили ранее, свойство display со значением flex упорядочивает flex-элемент в ряд слева направо.
Flex-direction
CSS flex-direction используется для установки ориентации и направления flex-элементов. Свойство flex-direction может иметь четыре значения — row (слева направо), row-reverse (справа налево), column (сверху вниз), column-reverse (снизу вверх).
Если явно не задать свойство flex-direction, то будет использовано значение row.
Синтаксис:
flex-direction: column;
В качестве примера зададим боксам направление row-reverse.
HTML:
<div class="container container--row-reverse">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
<div class="box">Box 6</div>
</div>
CSS:
.container--row-reverse {
display: flex;
flex-direction: row-reverse;
}
Получим результат:
Flex-wrap
Flex-wrap определяет должны ли переноситься flex-элементы на новую строку.
Синтаксис:
flex-wrap: wrap;
Свойство flex-wrap принимает следующие значения:
Свойство | Что означает |
---|---|
flex-wrap: wrap | flex-элементы будут перенесены, если это необходимо |
flex-wrap: nowrap | это значение по умолчанию, означающее, что элементы не будут переноситься |
flex-wrap: wrap-reverse | flex-элементы будут переноситься в обратном порядке, если это необходимо |
Мы используем flex-wrap для упорядочивания flex-элементов в соответствии с размером контейнера.
Пример:
HTML:
<div class="container container--wrap">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
<div class="box">Box 6</div>
<div class="box">Box 7</div>
<div class="box">Box 8</div>
</div>
CSS:
.container--wrap {
display: flex;
flex-wrap: wrap;
}
Видим, что два крайних бокса перенеслись на новую строку:
Justify-content
Justify-content позволяет выравнивать flex-элементы по главной оси. Он определяет распределение пространства вокруг flex-элементов вдоль главной оси flex-контейнера.
Синтаксис:
display: flex;
Свойство justify-content может принимать следующие значения:
Свойство | Что означает |
---|---|
justify-content: start | значение по умолчанию, элементы располагаются вдоль начала главной оси |
justify-content: end | элементы располагаются вдоль конца главной оси |
justify-content: center | элементы располагаются по центру главной оси |
justify-content: space-between | элементы располагаются равномерно вдоль главной оси |
justify-content: space-around | элементы располагаются равномерно вдоль главной оси (с учетом боковых отступов) |
В качестве примера расположим боксы равномерно вдоль контейнера:
HTML:
<div class="container container--space-between">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
</div>
CSS:
.container--space-between {
display: flex;
justify-content: space-between;
}
В результате получим:
Флекс-элементы располагаются с интервалом между строками вдоль главной оси.
Align-items
Свойство align-items используется для выравнивания flex-элементов вдоль поперечной оси
Синтаксис:
align-items: center;
Свойство align-items может принимать следующие значения:
align-items: start; | элементы располагаются в начале поперечной оси |
---|---|
align-items: end; | элементы располагаются в конце поперечной оси |
align-items: center; | элементы располагаются по центру поперечной оси |
align-items: stretch; | значение по умолчанию, flex-элементы равномерно растягиваются вдоль поперечной оси |
В качестве примера выравниваем наши элементы по центру высоту:
HTML:
<div class="container container--center">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
</div>
CSS:
.container--center {
display: flex;
align-items: center;
height: 100px;
}
Получаем:
Главная и поперечная ось расположены по умолчанию (так как мы явно не задавали свойство flex-direction). Боксы располагаются по центру высоты, так как поперечная ось направлена сверху вниз.
Чтобы элементы точно расположились по центру, мы должны явно задать высоту flex-контейнеру. В нашем примере это 100 px
Stretch — это значение по умолчанию, которое растягивает flex-элементы, чтобы заполнить контейнер. Давайте рассмотрим его также на примере.
CSS:
.container--stretch {
display: flex;
align-items: stretch;
height: 75px;
}
Боксы заполнили по высоте весь контейнер (с учетом отступов).
Чтобы предотвратить такое поведение необходимо задать значение flex-start, либо явно задать высоту бокса
Align-content
Align-content используется для распределение пространства между элементами вдоль поперечной оси. Действует аналогично justify-content.
Синтаксис:
align-content: space-evenly;
Свойство align-content может принимать следующие значения:
Свойство | Что значит |
---|---|
align-content: start | расположить flex-элементы с начала |
align-content: end | расположить flex-элементы с конца |
align-content: center | расположить flex-элементы по центру |
align-content: space-around | распределить flex-элементы равномерно: отступов для крайних элементов нет |
align-content: space-between | распределить flex-элементы равномерно: с учетом половинных отступов в начале и конце |
align-content: space-evenly | распределить flex-элементы равномерно: все элементы имеют одинаковый отступ слева и справа |
В качестве примера распределим flex-элементы равномерно, чтобы они имели одинаковое вокруг себя пространство.
HTML:
<div class="container container--space-evenly">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
<div class="box">Box 6</div>
<div class="box">Box 7</div>
<div class="box">Box 8</div>
<div class="box">Box 9</div>
<div class="box">Box 10</div>
<div class="box">Box 11</div>
<div class="box">Box 12</div>
<div class="box">Box 13</div>
</div>
CSS:
.container--space-evenly {
display: flex;
flex-wrap: wrap;
align-content: space-evenly;
width: 300px;
height: 150px;
margin-bottom: 50px;
}
Благодаря свойству wrap мы переносим боксы на новую строку. Свободное пространство между ними вдоль поперечной оси распределяется равномерно:
Gap
Свойство gap используется для установки промежутка между строкой (row-gap) и столбцом (column-gap).
Синтаксис:
.container--gap {
flex-wrap: wrap;
gap: 20px 10px; /* 20px - строка, 10px - колонка */
row-gap: 20px;
column-gap: 10px;
}
Свойство для дочерних flex-элементов
Выше мы рассматривали те свойства, которые применяются только для flex-контейнера. Элементы внутри flex-контейнера называются дочерними flex-элементами. Давайте рассмотрим теперь свойства для них.
Order
Свойство order влияет на порядок элементов. Он применяется только к flex-элементам, а не к flex-контейнеру. Мы можем назначить определенный номер flex-элементу, как показано ниже.
Синтаксис:
.box--order {
order: 5;
}
Рассмотрим пример:
<div class="container">
<div class="box" style="order: 5">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
</div>
В данном примере мы помещаем первый бокс на место пятого. А место первого бокса занимает второй:
Мы видим, что можно менять порядок flex-элементов и при этом не затрагивает HTML-разметку.
Flex-grow
Часто возникает такая ситуация, когда остается свободное пространство во flex-контейнере и его необходимо распределить между flex-элементами. Свойство flex-grow позволяет увеличить размер flex-элемента при наличии пространства во flex-контейнере.
Синтаксис:
.box--flex-grow {
flex-grow: 1;
}
Число, которые мы указываем для flex-grow обозначает коэффициент расширения.
Давайте рассмотрим следующий пример:
<div class="container container--flex">
<div class="box" style="flex-grow: 2">Box 1</div>
<div class="box" style="flex-grow: 1">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
</div>
Во flex-контейнере есть пять боксов, которые распределены равномерно. При этом контейнер довольно большой и остается свободное пространство в конце. Третий, четвертый и пятый боксы не будут расширяться и займут столько места, сколько им надо. Первый бокс займет в два раза больше места чем второй. Так как у него установлен коэффициент расширения 2.
Flex-shrink
Свойство flex -shrink помогает уменьшить размер, если размер flex-элемент больше, чем flex-контейнер. Он работает противоположно flex-grow. Значение CSS flex-shrink по умолчанию равно 1.
Синтаксис:
.box--flex-shrink {
flex-shrink: 1;
}
Мы должны удалить свойство flex-wrap, чтобы заставить flex-shrink работать.
Flex-basis
Flex-basis используется для определения начального размера flex-элемента.
Синтаксис:
.box--flex-basis {
flex-basis: 100px;
}
Мы можем установить размер flex-элемента, используя свойство flex-basis.
Пример:
<div class="container container--flex">
<div class="box" style="flex-basis: 100px">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box">Box 5</div>
</div>
Мы задали первому элементу начальный размер 100 пикселей.
Flex
Чтобы использовать flex-grow, flex-shrink и flex-basis, мы используем свойство CSS flex, которое является сокращенным свойством. Порядок будет такой:
- flex-grow
- flex-shrink
- flex-basis
Синтаксис:
.box--flex {
flex: 1 0 200px; /* grow - shrink - basis */
flex-grow: 1;
flex-shrink: 0;
flex-basis: 200px;
}
Align-self
Чтобы выровнять flex-элемент во flex-контейнере, мы используем свойство align-self. Его значения совпадают со свойством align-items в родительском классе. Мы можем переопределить выравнивание отдельного элемента.
Синтаксис:
.box--align-self {
align-self: flex-start;
}
Пример:
<div class="container container--flex">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
<div class="box" style="align-self: flex-end">Box 5</div>
</div>
В этом примере мы выравниваем располагаем пятый бокс снизу:
Подведем итоги
- CSS Flexbox помогает пользователю создавать гибкие и адаптивные макеты, совместимые со всеми устройствами.
- Flex-контейнер используется для размещения элементов как по горизонтали, так и по вертикали.
- Чтобы применить свойства flexbox ко всему контейнеру, у нас есть родительские свойства flexbox, такие как CSS display, align-items и т. д.
- Чтобы применить свойства flexbox индивидуально к flex-элементу или дочернему элементу, у нас есть дочерние свойства flexbox, такие как flex, flex-basis и т. д.