От автора: карточный шаблон в последнее время стал пользоваться большой популярностью, однако CSS ограничивает нас в создании таких шаблонов. Так было до сих пор. CSS Grid и Flexbox позволяют нам создать аккуратно выровненные карточки, которые ведут себя адаптивно и подстраиваются под внутренний контент. Давайте же узнаем, как создавать такие шаблоны!
Что мы будем делать
Мы хотим создать карточный интерфейс (в полноэкранной версии можно понять принцип):
На различных экранах карточки будут перестраиваться:
CSS Grid или Flexbox
Когда вышел Flexbox, весь мир оглушили крики радости. Наконец, у нас появился макетный модуль, который решал все проблемы с выравниваниями. Но все оказалось слегка не так. Flexbox хорошо выравнивает элементы вдоль одной оси: горизонтальной или вертикальной. Построить по-настоящему жидкую сетку с помощью Flexbox трудно.
CSS Grid же предназначен для выравнивания элементов по двум осям (измерениям): горизонтальной и вертикальной. В этом уроке мы возьмем самое лучшее от обоих способов и создадим по-настоящему надежный шаблон. Поехали!
Вдохновение
Совсем недавно bbc.co.uk запустили в бета режиме свою последнюю версию сайта. Благодаря карточному интерфейсу, сайт стал чище и просторнее. Если не смотреть на страшные заголовки, дизайн смотрится замечательно.
Верхние карточки выровнены в ряд при помощи Flexbox. Мы же усложним макет и добавим в него сетку.
Обратите внимание: чтобы работать дальше, вам понадобится браузер с поддержкой CSS Grid. Ознакомиться с сеткой можете по ссылке.
Карточная разметка
Начнем с обертки <div class=»band»>, пары элементов сетки <div class=»item»>, с помощью которых будем всем управлять, и пары якорей (каждый якорь будет отдельной карточкой):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<div class="band"> <!-- grid item, containing a card --> <div class="item-1"> <a href="" class="card"> <div class="thumb"></div> <article> <h1>Post title</h1> <span>Author</span> </article> </a> </div> <!-- элемент сетки, содержит внутри карточку --> <div class="item-2"> ... </div> <!-- элемент сетки, содержит внутри карточку --> <div class="item-3"> ... </div> </div> |
Карточек можете вставить сколько захотите, мы возьмем 7. У каждой карточки есть свое превью <div class=»thumb»>, на которое немного позже мы будем выводить фоновое изображение. Также у нас есть тег article, внутри которого размещены теги h1 и span для информации об авторе. Может быть, мы даже добавим параграф p с кратким описанием.
Базовая сетка
Теперь давайте пропишем немного стилей и расставим наши элементы внутри сетки. Мы пойдем техникой mobile-first, поэтому первые стили зададут блоку-обертке ширину и поместят его по центру. Чуть ниже добавим немного правил по сетке:
1 2 3 4 5 6 7 8 9 10 11 |
.band { width: 90%; max-width: 1240px; margin: 0 auto; display: grid; grid-template-columns: 1fr; grid-template-rows: auto; grid-gap: 20px; } |
Самый важный момент – мы задали для .band свойство display: grid;. Дальше мы указали grid-template-columns: 1fr, т.е. каждая колонка будет занимать одну доступную область. Пока что мы объявили всего одну колонку, поэтому каждая колонка будет занимать всю ширину.
Следующее свойство — grid-template-rows: auto;. Это значение по умолчанию, которое можно было бы и не записывать. Оно означает, что высота ряда будет зависеть только от контента. Последнее свойство — grid-gap: 20px. Оно добавляет отступы между рядами и колонками.
Медиа запрос номер 1
На более широких экранах (500px взято произвольно) мы будем изменять свойство grid-template-columns, чтобы поместить две карточки в один ряд. Теперь у нас будет две колонки, каждая будет занимать свою область.
1 2 3 4 5 |
@media only screen and (min-width: 500px) { .band { grid-template-columns: 1fr 1fr; } } |
Медиа запрос номер 2
И для очень больших экранов мы сделаем четыре колонки.
1 2 3 4 5 |
@media only screen and (min-width: 850px) { .band { grid-template-columns: 1fr 1fr 1fr 1fr; } } |
Можно было спокойно написать repeat(4, 1fr) вместо 1fr 1fr 1fr 1fr. Что же это нам дало?
Стилизуем карточки
Это дало нам довольно хороший макет сетки. Если вы любите брутализм, можете все оставить прямо так, ну а для всех остальных мы сделаем карточки похожими на карточки. И начнем с этого:
1 2 3 4 5 6 7 8 9 |
.card { background: white; text-decoration: none; color: #444; box-shadow: 0 2px 5px rgba(0,0,0,0.1); display: flex; flex-direction: column; min-height: 100%; } |
Мы прописали базовые стили: белый фон, убрали подчеркивания текста, серый текст и небольшая тень box-shadow для большей глубины.
Дальше мы превратили нашу карточку в флекс-ячейку с помощью display: flex;. Очень важно, мы будем выравнивать контент карточки по вертикали с помощью Flexbox. Именно поэтому мы задали вертикальную ось flex-direction: column;. Чтобы карточки заполняли всю высоту родителя (ячейки сетки), мы указали min-height: 100%;. Хорошо потрудились! Вот что у нас получилось:
Состояние hover
Перед углублением в Flexbox добавим пару улучшений. Добавьте position: relative; и transition, чтобы мы могли двигать карточку при наведении мыши:
1 2 3 |
position: relative; top: 0; transition: all .1s ease-in; |
По событию hover поднимаем карточку и делаем тень немного насыщеннее:
1 2 3 4 |
.card:hover { top: -2px; box-shadow: 0 4px 5px rgba(0,0,0,0.2); } |
Типографика
Добавим базовые стили для шрифтов, чтобы менялся цвет и отступы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
.card article { padding: 20px; } /* шрифт */ .card h1 { font-size: 20px; margin: 0; color: #333; } .card p { line-height: 1.4; } .card span { font-size: 12px; font-weight: bold; color: #999; text-transform: uppercase; letter-spacing: .05em; margin: 2em 0 0 0; } |
Вот что должно получиться:
Превью
Превью будет в виде фонового изображения, поэтому нам придется добавить немного лишней разметки:
1 |
<div class="thumb" style="background-image: url(thumb.jpg);"></div> |
Необходимо проверить, чтобы у .thumb были заданы размеры, а фоновый рисунок правильно заполнял блок:
1 2 3 4 5 |
.card .thumb { padding-bottom: 60%; background-size: cover; background-position: center center; } |
Хорошо, вот что у нас получилось:
Flexbox и элемент article
Имя автора необходимо выровнять по нижней границе карточки, независимо от количества контента сверху. Вот тут нам поможет Flexbox:
1 2 3 4 5 6 7 8 |
.card article { padding: 20px; flex: 1; display: flex; flex-direction: column; justify-content: space-between; } |
С помощью сокращения flex: 1; мы делаем так, чтобы флекс-ячейка (дочерний элемент флекс-контейнера) занимала все свободное пространство.
Далее мы указываем, что тег article является отдельным флекс-контейнером, и задаем flex-direction: column; для вертикального выравнивания. Последнее свойство justify-content: space-between; равномерно распределяет все флекс-элементы по оси на одинаковых расстояниях друг от друга.
Отлично, только теперь появились какие-то странные параграфы посередине карточек.
Для правильного выравнивания добавим flex-grow: 1; (или просто flex: 1;) к ним, чтобы эти параграфы занимали оставшееся вертикальное пространство и прижимались к верхней границе.
1 2 3 4 |
.card p { flex: 1; /* растягиваем p */ line-height: 1.4; } |
Лучше!
Переключение сетки
Мы почти закончили. Однако CSS Grid позволяет нам полностью перестраивать макет, размещая элементы в любом порядке и любых размеров. В нашем демо мы хотели растянуть нашу первую карточку на две колонки (назовем ее избранной) на всех экранах кроме самых маленьких. Сделаем это в нашем медиа запросе номер 1:
1 2 3 4 5 6 7 8 9 |
@media only screen and (min-width: 500px) { ... .item-1 { grid-column: 1/ span 2; } } |
Возвращаясь к вводному уроку по grid областям, мы говорим, что кроме того, что первый элемент должен быть 500px, он также должен начинаться на первой строке сетки и занимать две колонки. Остальные элементы сетки размещаются автоматически.
В этом же медиа запросе я изменил font-size заголовка в избранной карточке.
Заключение
Хороший урок по Grid и Flexbox. Grid обрабатывает наш главный макет в двух измерениях, а Flexbox работает с вертикальным выравниванием элементов внутри карточек. Поиграйтесь с кодом!
Автор: Ian Yates
Источник: //webdesign.tutsplus.com/
Редакция: Команда webformyself.