Flex-сетка

Для того, чтобы перейти к практике, нам нужно рассмотреть ещё один важный вопрос: как создавать блоки и ячейки. Большая часть вёрстки будет заключаться именно в создании и комбинации блоков. Например вот так:

Red
Green
Blue

Любой блок по-умолчанию занимает 100% ширину своего контейнера. Это стандартное поведение, которое описывается свойством display: block. У блочных тэгов DIV, P, H1 и т.д. это свойство определено изначально.

Строчные тэги, например SPAN, B, I и т.д. описаны как display: inline. В отличие от блочных они не создают перенос строки.

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

У flex-блока всегда есть основной контейнер, а непосредственные его потомки автоматически будут являться ячейками, которые будут располагаться рядом друг с другом по горизонтали.

Первая ячейка
Вторая
И третья
<div class="b-flex">
    <div class="bg-red">Первая ячейка</div>
    <div class="bg-green">Вторая</div>
    <div class="bg-blue">И третья</div>
</div>

Класс b-flex объявлен так:

.b-flex { display: flex; }
Все примеры ты можешь проверять в Berry Builder.

Каждая ячейка flex-сетки, также может являться контейнером для вложенных элементов.

100
200
300
Вторая
И третья
<div class="b-flex">
    <div class="b-flex">
        <div class="bg-red100">100</div>
        <div class="bg-red200">200</div>
        <div class="bg-red300">300</div>
    </div>
    
    <div class="bg-green">Вторая</div>
    <div class="bg-blue">И третья</div>
</div>

Отступы

Отступы бывают внешние (margin) и внутренние (padding). Обычно они задаются в пикселях. В Berry CSS за них отвечают классы marXX и padXX.

Первая ячейка
Вторая
И третья
<div class="b-flex">
    <div class="mar20 pad10 bg-red">Первая ячейка</div>
    <div class="mar20 pad10 bg-green">Вторая</div>
    <div class="mar20 pad10 bg-blue">И третья</div>
</div>

Здесь мы задаём для внешнего отступа 20px, а внутри ячейки будет отступ в 10px. Это соответствует таким css-классам:

.mar20 { margin: 20px; }
.pad10 { padding: 10px; }

Отступы можно задать и более точечно — указать сторону: top, right, bottom, left. В Berry для этого используются суффиксы: -t, -r, -b, -l, -tb (top и bottom), -rl (right и left).

.mar20-t  { margin-top: 20px; }
.mar20-r  { margin-right: 20px; }
.mar20-b  { margin-bottom: 20px; }
.mar20-l  { margin-left: 20px; }
.mar20-tb { margin-top: 20px; margin-bottom: 20px; }
.mar20-rl { margin-right: 20px; margin-left: 20px; }

Ширина

Как правило у ячейки нужно задать ширину. Ширина может задаваться в абсолютных величинах — пикселях, и относительных — процентах. Поскольку современная вёрстка адаптивная, то почти всегда используются проценты. В сочетании с поведением flexbox, они прекрасно адаптируются к любому экрану.

Классы ширины wXX, где XX — процент, либо wYYpx, где YY — пиксели. Например

.w20  { width: 20%; }
.w50px  { width: 50px; }
Первая ячейка 20%
Вторая 30%
И третья 40%
<div class="b-flex">
    <div class="w20 pad10 bg-red">Первая ячейка 20%</div>
    <div class="w30 pad10 bg-green">Вторая 30%</div>
    <div class="w40 pad10 bg-blue">И третья 40%</div>
</div>

Также часто применяется 12-колоночная сетка — это когда ширина рассчитывается как часть от 12-ти колонок. Например 6 колонок — будет соответствовать 50% ширины. Для таких случаев в Berry CSS предусмотрены классы wXXcol, где XX — число колонок. Ширина рассчитывается автоматически простым делением. Эти классы можно комбинировать с «обычными».

Первая ячейка 2 колонки
Вторая 4 колонки
И третья 6 колонок
<div class="b-flex">
    <div class="w2col pad10 bg-red">Первая ячейка 2 колонки</div>
    <div class="w4col pad10 bg-green">Вторая 4 колонки</div>
    <div class="w6col pad10 bg-blue">И третья 6 колонок</div>
</div>

Поведение flex-сетки

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

В первую очередь стоит отметить, что классы ширины ячейки, носят «рекомендательный» характер. Если содержимое ячеек будет большим, то браузер изменит их ширину так, чтобы оптимально заполнить всё доступное пространство. То есть когда суммарная ширина ячеек превысит 100%, браузер их отобразит как посчитает нужным.

50%
50%
50%
<div class="b-flex">
    <div class="w50 pad10 bg-orange100">50%</div>
    <div class="w50 pad10 bg-orange200">50%</div>
    <div class="w50 pad10 bg-orange300">50%</div>
</div>

Сумма ячеек 150% и мы ожидаем, что браузер перенесёт последнюю ячейку, но этого не происходит. Именно так и работает flex-сетка.

А чтобы всё-таки разрешить перенос ячеек нужно явно это указать. Для этого используется класс flex-wrap:

.flex-wrap { flex-wrap: wrap; }
50%
50%
50%
<div class="b-flex flex-wrap">
    <div class="w50 pad10 bg-orange100">50%</div>
    <div class="w50 pad10 bg-orange200">50%</div>
    <div class="w50 pad10 bg-orange300">50%</div>
</div>
На самом деле wrap в основном используется в адаптивном дизайне, но его мы будем рассматривать позже.

«Резиновая» сетка

В подавляющем большинстве случаев, вёрстка требует «резиновой» сетки — это когда крайние ячейки прижимаются к краям контейнера. В Berry CSS для этого используется класс flex, который задан так:

.flex  { 
    display: flex;
    justify-content: space-between;
    align-items: stretch;
 }

Посмотри разницу.

1
2
3
1
2
3
<div class="b-flex">
    <div class="w20 pad10 bg-blue100">1</div>
    <div class="w30 pad10 bg-blue200">2</div>
    <div class="w20 pad10 bg-blue300">3</div>
</div>

<div class="mar30-t flex">
    <div class="w20 pad10 bg-green100">1</div>
    <div class="w30 pad10 bg-green200">2</div>
    <div class="w20 pad10 bg-green300">3</div>
</div>

Класс flex прижимает ячейки к краю ( align-items: stretch), а пустое пространство распределяет равномерно ( justify-content: space-between).

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

Ещё пример

Покажу пример, где используется вложенные сетки.

<div class="flex flex-wrap">
    <div class="w50 bg-red550 pad20 flex flex-wrap">
        <div class="bg-red100 pad20"></div>
        <div class="bg-red200 pad20"></div>
        <div class="bg-red300 pad20"></div>
        <div class="bg-red400 pad20"></div>
        <div class="bg-red500 pad20"></div>
        <div class="bg-red600 pad20"></div>
        <div class="bg-red700 pad20"></div>
        <div class="bg-red800 pad20"></div>
        <div class="bg-red900 pad20"></div>
    </div>

    <div class="w50 bg-green550 pad20 flex flex-wrap" >
        <div class="bg-green100 pad20"></div>
        <div class="bg-green200 pad20"></div>
        <div class="bg-green300 pad20"></div>
        <div class="bg-green400 pad20"></div>
        <div class="bg-green500 pad20"></div>
        <div class="bg-green600 pad20"></div>
        <div class="bg-green700 pad20"></div>
        <div class="bg-green800 pad20"></div>
        <div class="bg-green900 pad20"></div>
    </div>
</div>

То есть работа с flex достаточно проста.

  • Задаётся контейнер с классом flex.
  • Задаются ячейки и указываются классы ширины.
  • Задаются отступы ячеек и их прочее оформление.

Задания

Посмотри на странице flexbox другие свойства и примеры поведения сетки. Запоминать все классы ну нужно, но ты должен знать в каких пределах может настраиваться flex-сетка.

Попробуй сверстать (не подглядывая!) вот такой блок. Например ты уже работаешь верстальщиком и дизайнер скинул тебе вот такой макет. Переведи его в HTML. (Картинку можешь взять любую. Я использую эту.)

Котики

Котики в интернете - это неиссякаемый источник умиления

Котик
Подсказка: Здесь используются классы
  • flex
  • flex-wrap
  • w60
  • w40
  • pad40-tb
  • t-georgia
  • t-italic
  • t-pink600
  • t-gray600
Решение
<div class="flex flex-wrap">
    <div class="w60 pad40-tb">
        <h1 class="t-georgia t-italic t-pink600">Котики</h1>
        <p class="t-gray600">Котики в интернете - это неиссякаемый источник умиления</p>
    </div>
    
    <div class="w40">
        <img src="https://live.staticflickr.com/3849/15063747768_1e63529953_w.jpg" alt="Котик" title="">
    </div>
</div>