Вёрстка на флексбоксах, модульная сетка своими руками
Знаю-знаю, вы устали от англицизмов, но в этот раз мне действительно сложно перевести markup и layout на русский без потери смысла.
Маркап — это то, чем мы занимались. Примитивнейшая разметка, раскрашивание текста, семантика и прочее. Полезно, конечно, но приложения так не строятся.
Лейаут — это структура страницы. Страница вообще верстается блоками. Это фундамент, то, из чего она строится кирпичами. Для этого нам нужно изучить два концепта: флекбоксы и модульную сетку.
Помните, я всё время говорю, что ХТМЛ/ЦСС предназначались для вёрстки документов? Раньше приходилось выдумывать костыли через float
, чтобы размещать элементы на странице, но, к счастью, консорциум W3C, который пишет веб-стандарты, придумал Флексбоксы (Flexbox Layout, где Flexbox это Flexible Box).
Основная идея в том, чтобы дать более гибкий (flex, pun intended) способ работы с лейаутом.
У нас есть родитель-контейнер и вложенные в него дети. У них есть много разных свойств, но всё начинается с display: flex
у родителя
<style>
.parent {
display: flex;
}
</style>
<div class="parent">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
А где изучить все возможности? Я рекомендую A Complete Guide to Flexbox от CSS-Tricks, лучше уже не получится написать. После этого можно сыграть в Flexbox Froggy.
А шпаргалка всегда есть на cssreference.io/flexbox.
По флексбоксам быстро пробежались, примеры посмотрели, в Флексбокс Фрогги сыграли, пора переходить к модульной сетке.
Помните, я выше говорил про то что страница строится блоками? Люди пошли дальше и придумали модульную сетку.
Что мы тут видим? 12 колонок с отступами между ними в 16 пикселей. Чем это удобно?
Мы можем сделать классы от .col-1
до .col-12
, которые будут занимать нужное количество колонок. Например, в блоке Explore Airbnb у нас три карточки. Сколько занимает каждая из них? Четыре колонки (четыре, потому что 12/3 = 4). Как бы это выглядело в вёрстке?
Сверстал сразу на флексах! Выглядит очень удобно.
iframe: https://jsfiddle.net/y29uhtbL/14/embedded/result/
Но что будет, если добавить ещё один блок? Будет плохо: почему-то блок залез на ту же строку.
iframe: https://jsfiddle.net/y29uhtbL/15/embedded/result/
Как это решить? Мы же указали ему, что нужно 33.33333% занимать и не больше. Дело в том, что нужно .row
добавить свойство flex-wrap: wrap
, которое отвечает за перенос строки.
iframe: https://jsfiddle.net/y29uhtbL/16/embedded/result/
Давайте попробуем добавить бэкграунд и посмотреть сколько занимают места наши блоки.
iframe: https://jsfiddle.net/y29uhtbL/17/embedded/result/
Хм, но куда делись наши отступы? Мы их и не задавали. А как лучше задать — марджином или паддингом?
Есть одно правило, которое касается сетки: нельзя мешать классы сетки и свои. Своя вёрстка должна быть внутри колонок, поэтому мы можем колонкам поставить паддинг — ведь если всё-таки будет дизайн, где нужно будет ставить колонки впритык, мы можем просто повесить класс на колонку.
iframe: https://jsfiddle.net/y29uhtbL/18/embedded/result/
Всё сломалось! Почему у нас не три элемента на строке? box-sizing
помните? Его проблемы помните? Ставим box-sizing: border-box
на .col-4
.
iframe: https://jsfiddle.net/y29uhtbL/19/embedded/result/
Сместим бэкграунд с .col-4
на .card
, добавим бордер, марджина снизу и выравнивание по центру.
iframe: https://jsfiddle.net/y29uhtbL/20/embedded/result/
Как доделать эту сетку?
- Во-первых, нужно сделать
col-1..col-12
. - Во-вторых, на современных сайтах есть контейнер — блок фиксированной ширины, который ограничивает расползание контента.
Первое делается легко: мы указываем общие стили для всех колонок и уникальные для каждой из.
Второе тоже: мы делаем класс .container
с шириной 992 - 16 пикселей. Что? Откуда эти значения?
- 992 пикселя это константа — в последнее время дизайнеры верстают десктопные макеты именно с такой шириной,
- 16 пикселей это паддинги слева и справа у колонок.
992-16=976 пикселей должна быть ширина нашего контейнера.
Но если мы попытаемся завести этот код, то почему-то эта вёрстка окажется слева.
<div class="container">
<div class="row">
<div class="col-4">
<div class="card">
<img src="./homes.png">
<p>Homes</p>
</div>
</div>
<div class="col-4">
<div class="card">
<img src="./experiences.png">
<p>Experiences</p>
</div>
</div>
<div class="col-4">
<div class="card">
<img src="./restaurants.png">
<p>Restaurants</p>
</div>
</div>
<div class="col-4">
<div class="card">
<img src="./restaurants.png">
<p>Homes 2</p>
</div>
</div>
</div>
</div>
Потому что нам нужно выровнять контейнер. Как это сделать? Не text-align
же использовать? Ведь тогда текст будет посередине выравниваться, нам это не нужно.
Нам помогут марджины. Нам нужно поставить margin-left: auto; margin-right: auto
— тогда браузер сам будет выравнивать блок посередине свободного места.
На этом наша сетка готова: у нас есть контейнер (для десктопа), у нас есть роу, который отвечает за строку, у нас есть куча классов от 1 до 12 колонок.
Предвосхищая вопросы:
- можно ли использовать не 992 пикселя? Можно.
- можно ли использовать меньше или больше 12 колонок? Можно хоть 64 — лишь бы вам было удобно.
- нужен ли всегда контейнер? Что делать, если я не хочу фиксировать ширину? Не фиксируйте.
- нужно ли делать новый
div.row
когда в нём набралось больше 12 колонок? Не нужно — у нас свойствоflex-wrap: wrap
отвечает за перенос элементов.
- Во-первых, нужно было подключить нормалайз — как минимум, он сбросил отступы у
body
в ноль. - Во-вторых, можно было переместить
nav
вheader
, чтобы проще было стилизовать. - В-третьих, нужно было добавить класс второму этажу, чтобы застилизовать только его, а не каждый
section
на странице.
Сегодня мы разобрали флексбоксы — способ построения лейаута страницы.
Изучили модульные сетки — что это такое, чем удобно, как их строить, зачем нужен контейнер.
В следующем задании — адаптивная вёрстка и позиционирование.
Пора возвращаться в первый этап и переходить к реальному заданию.