Мы рассмотрели основные проблемы раскладок и их реализации.
Теперь давайте посмотрим, как эти проблемы решаются в современном вебе.
И первое решение — это спецификация flexbox.
Что такое flexbox?
Flexbox — это спецификация, которая описывает набор правил, которые
позволяют контролировать размер, порядок и выравнивание элементов по нескольким осям,
а также распределение свободного места между элементами и многое другое.
Это определение достаточно большое, и мне нравится другое, которое дал Вадим Макеев:
«Flexbox — это первая система для раскладки, которая не является хаком».
Основные преимущества Flexbox следующие.
Элементы могут сжиматься и растягиваться по заданным правилам,
занимая нужное пространство.
Во Flexbox реализовано выравнивание по вертикали и горизонтали «из коробки».
Я думаю, каждый из вас, кто хоть раз центровал элемент по вертикали, знает,
что это достаточно сложная задача была.
Расположение элементов в html теперь не имеет решающего значения.
Вы можете написать их в одном порядке, а отрендерить в другом.
Элементы могут автоматически выстраиваться в несколько строк или столбцов,
занимая все предоставленное место.
Локализация для языков с другим написанием.
Ну и просто и понятно — я думаю, вы дальше увидите, как это действительно просто.
Поддержка у Flexbox действительно большая.
Фактически все последние версии всех современных браузеров уже поддерживают
Flexbox, поэтому теперь у вас нет ни единой отговорки не пользоваться им.
Давайте же, как в фильме «Матрица», примем волшебную таблетку,
после которой, правда, вам будет уже сложно верстать не с помощью Flexbox.
Но я думаю, вы постараетесь и все-таки будете применять его с умом.
Итак, что же нужно сделать?
Написать всего одного свойство: display: flex.
Рассмотрим на конкретном примере.
Допустим, у нас есть абстрактная система допуска до экзамена,
в которой 9,5 баллов дает +1 к оценке на экзамене,
а 5 баллов дает допуск до экзамена.
Такая верстка может выглядеть как-то так.
Здесь я добавил дополнительных украшений и скруглений уголков,
чтобы выглядело красиво.
Что будет, если мы обертке всех этих элементов зададим свойство flex?
Все начнет выглядеть вот так вот.
Пока магии особо не видно, но давайте немножко поиграем с этими элементами.
Например, в четвертом элементе мы хотим изменить значение,
и теперь у нас для того, чтобы допуститься до экзамена, нужно не 5 баллов, а 4.
Мы меняем...
И смотрите, что произошло: все элементы автоматически подстроили
свою высоту под высоту последнего элемента.
Это первое замечательное свойство flex-элементов.
Высота подстраивается под максимальную высоту.
Думаю, каждый из вас, кто хоть раз реализовывал колонки
одинаковой высоты не с помощью таблиц, знает, как это сложно.
Идем дальше.
Мы можем поменять элементы местами,
но вот как это сделать, я буду рассказывать немножечко попозже.
Основу спецификации Flexbox составляют оси.
В любой flex-разметке этих осей две: главная ось и поперечная ось,
при этом поперечная ось всегда перпендикулярна главной.
Главная ось задает направление выстраивания элементов,
а поперечная ось задает направление роста элементов.
Важно понимать, что эти направления и оси можно менять.
За это отвечает свойство flex-direction.
По умолчанию flex-direction равно row, но мы можем задать row-reverse,
и тогда элементы будут выстраиваться не слева направо, а справа налево.
Мы также можем вообще поменять эти оси местами и сказать,
что у нас теперь элементы выстраиваются сверху вниз, а растут слева направо.
Ну и, наконец, мы можем и это поведение развернуть.
Давайте рассмотрим на конкретных примерах.
Вот так выглядел наш предыдущий пример при flex-direction: row, а вот так он будет
выглядеть при row-reverse, а вот так — при column, и, наконец, при column-reverse.
Как вы видите, положение элементов не соответствует их положению в html.
Это один из способов поменять порядок элементов.
Следующее свойство задает выравнивание вдоль главной оси.
Оно называется justify-content и чем-то оно похоже на подобное свойство в тексте.
Значение по умолчанию — flex-start,
то есть элементы выстраиваются к началу главной оси.
В данном случае мы видим тоже какую-то систему оценки, и мы видим,
что элементы выровнены по левому краю.
Какие же еще значения есть у justify-content?
flex-end, center, и тогда все элементы выстраиваются посередине.
Но есть два замечательных свойства — это space-between,
чем-то поведение этого свойства похоже на значение justify свойства text-align,
за исключением того, что нам не нужно вставлять абстрактный последний элемент,
который будет задавать перенос.
Но еще более интересное значение — это space-around.
Когда у нас пространство есть не только между средними элементами,
но и от края содержащего элемента.
Следующее свойство — align-items, оно,
в противовес justify-content, задает выравнивание вдоль поперечной оси.
По умолчанию значение — stretch, то есть блоки
растянуты и занимают все доступное пространство вдоль поперечной оси.
Именно поведение значения свойства align-items stretch мы наблюдали,
когда увеличивали высоту крайнего элемента.
Например, в данном случае у нас первый элемент больше других,
а высота всех остальных подстраивается под него.
Давайте же рассмотрим другие значение свойства align-items.
flex-start — в таком случае у нас элементы поджимаются по контенту.
flex-end — в данном случае их содержимое не только поджимается,
но еще и выравнивается к концу поперечной оси.
center, baseline — это самое интересное значение, здесь мы, например, можем задать
padding, и тогда у нас все элементы все равно будут выстроены по базовой линии.
Следующее свойство flexbox-элементов — это многострочность.
По умолчанию, если ширина элементов внутри родителя будет больше,
чем ширина родителя, то вы увидите вот такое поведение,
то есть элементы будут продолжаться и за пределами родителя.
Так происходит потому, что свойство flex-wrap, которое отвечает за режим
форсирования выстраивания блоков в одну линию, по умолчанию имеет значение nowrap.
Если вы помните, есть точно такое же свойство и для текста — white-space,
и его значение nowrap так же влияет и на текст.
Но мы можем это поведение поменять.
Мы можем сфорсировать перестраивание блоков.
Например, мы можем сказать flex-wrap: wrap, и тогда,
если элементы не влезают на строчку, они переносятся на следующую строчку.
У flex-wrap есть забавное значение — это wrap-reverse,
когда они переносятся не на следующую строчку, а на предыдущую строчку.
Следующее свойство — flex-flow.
Это комбинация значений свойств flex-direction и flex-wrap,
то есть группирующее свойство.
Следующее свойство — align-content.
Оно похоже на свойство align-items, но определяет то,
каким образом образовавшиеся при многострочности ряды блоков будут
выровнены по вертикали и как поделят между собой все пространство flex-контейнера.
Здесь важно понимать, что align-content не работает,
если у flex-контейнера не задана высота.
По умолчанию значение stretch — ряды блоков растянуты и занимают все
имеющееся пространство.
Вот так это выглядит.
Как вы видите, все элементы занимают доступное пространство им,
но это поведение мы можем менять.
Мы можем сказать flex-start, flex-end или center — поведение,
уже знакомое вам, поэтому не будем останавливаться на этом подробнее.
Также мы можем сказать space-between и space-around,
также поведение очень похоже на justify-content.
Самое замечательное, что есть в спецификации flex,
что мы можем менять поведение для конкретных элементов flex-контейнера.
Есть специальное правило для дочерних элементов flex-контейнера.
Например, мы можем какому-то конкретному элементу задать выравнивание
только для него.
За это отвечает свойство align-self.
Здесь значения уже вам знакомы: flex-start, center и так далее.
Следующее свойство — flex-basis.
Оно задает изначальный размер элемента по главной оси.
До того, как к нему будут применены различные другие преобразования,
основанные на flex-факторах.
На самом деле здесь есть строгие алгоритмы,
но чаще всего для большинства из нас это будет какая-то магия.
Например, мы можем сказать flex-basis: 200px.
В данном случае этот элемент будет иметь действительно ширину 200 пикселей,
потому что пространство позволяет ему иметь эту ширину.
Мы можем задать flex-basis: 600px, а можем сказать — 1000.
Но 600 от 1000 ничем не отличается,
потому что дальше у нас были применены другие преобразования, которые, например,
говорят, что все элементы должны быть растянуты вдоль поперечной оси.
Ну и, соответственно, у нас ширина не применилась.
Еще два свойства, которые введены в спецификации Flexbox,
отвечают за жадность и бедность.
Соответствующие свойства называются flex-grow и flex-shrink.
flex-grow определяет то,
насколько отдельный блок может быть больше соседних блоков.
Например, в данном случае мы можем сказать фиолетовому блоку flex-grow: 2.
Если мы всем остальным блокам не зададим значения свойства Flexbox,
то этот элемент займет все доступное пространство.
Если же мы всем элементам зададим flex-grow: 2,
то здесь уже какие-то дополнительные вычисления применяются к блокам.
Или, например, мы можем задать всем элементам flex-grow: 2,
а фиолетовому блоку — flex-grow: 4,
и тогда он всегда будет стараться быть в два раза больше, чем все элементы.
В обратную сторону работает свойство flex-shrink.
Оно определяет, насколько flexbox будет уменьшаться относительно
соседних элементов внутри flex-контейнера.
В данном случае мы можем задать среднему элементу flex-shrink: 0,
и тогда оно будет работать следующим образом.
И последнее свойство, которое есть в спецификации Flexbox,
позволяет определить порядок конкретного элемента.
Я уже несколько раз говорил ранее, что порядок элементов в html для
flex-блоков не имеет значения, его можно менять.
За это отвечает свойство order.
По умолчанию оно равно 0.
Но вы можете спокойно для любого из элементов поменять его порядок.
Например, вы можете сказать второму элементу,
а цифры здесь соответствуют положению блоков в html-документе, 1.
И тогда у вас сначала выведутся все блоки с order: 0,
а потом со свойством order: 1.
И так далее, вы можете менять и ставить элемент в любое место вашей разметки.
В данном видео мы рассмотрели, что такое спецификация Flexbox и как ведут
себя flex-блоки в зависимости от различных значений flex-свойств.