Вирішуємо проблеми з CSS Grid і Flexbox з допомогою карткового інтерфейсу

2

Від автора: картковий шаблон останнім часом став користуватися великою популярністю, проте CSS обмежує нас у створенні таких шаблонів. Так було досі. CSS Grid і Flexbox дозволяють нам створити акуратно вирівняні картки, які ведуть себе адаптивно і підлаштовуються під внутрішній контент. Давайте ж дізнаємося, як створювати такі шаблони!

Що ми будемо робити

Ми хочемо створити картковий інтерфейс (повноекранної версії можна зрозуміти принцип):

На різних екранах картки будуть перебудовуватися:

CSS Grid або Flexbox

Коли вийшов Flexbox, весь світ оглушили крики радості. Нарешті, у нас з’явився макетний модуль, який вирішував всі проблеми з выравниваниями. Але все виявилося трохи не так. Flexbox добре вирівнює елементи уздовж однієї осі: горизонтальної або вертикальної. Побудувати по-справжньому рідку сітку з допомогою Flexbox важко.

CSS Grid призначений для вирівнювання елементів по двох осях (вимірами): горизонтальної і вертикальної. У цьому уроці ми візьмемо найкраще від обох способів і створимо по-справжньому надійний шаблон. Поїхали!

Натхнення

Зовсім недавно bbc.co.uk запустили в бета режимі свою останню версію сайту. Завдяки картковому інтерфейсу, сайт став чистішим і просторіше. Якщо не дивитися на страшні заголовки, дизайн виглядає чудово.

Верхні картки вирівняні в ряд за допомогою Flexbox. Ми ж ускладнимо макет і додамо в нього сітку.

Зверніть увагу: щоб працювати далі, вам знадобиться браузер з підтримкою CSS Grid. Ознайомитися з сіткою можете за посиланням.

Карткова розмітка

Почнемо з обгортки

, пари елементів сітки

, з допомогою яких будемо всім керувати, і пари якорів (кожен якір буде окремою карткою):

Post title

Author

Карток можете вставити скільки захочете, ми візьмемо 7. У кожної картки є своє превью

, на яке трохи пізніше ми будемо виводити фонове зображення. Також у нас є тег article, всередині якого розміщені теги h1 і для span інформації про автора. Може бути, ми навіть додамо параграф p з коротким описом.

Базова сітка

Тепер давайте пропишемо трохи стилів і розставимо наші елементи всередині сітки. Ми підемо технікою mobile-first, тому перші стилі зададуть блоку-обгортці ширину і помістять його по центру. Трохи нижче додамо трохи правил по сітці:

.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, щоб помістити дві картки в один ряд. Тепер у нас буде дві колонки, кожна буде займати свою область.

@media only screen and (min-width: 500px) {
.band {
grid-template-columns: 1fr 1fr;
}
}

Медіа запит номер 2

І для дуже великих екранів ми зробимо чотири колонки.

@media only screen and (min-width: 850px) {
.band {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
}

Можна було спокійно написати repeat(4, 1fr) замість 1fr 1fr 1fr 1fr. Що ж це нам дало?

Стилізуємо картки

Це дало нам досить гарний макет сітки. Якщо ви любите бруталізм, можете все залишити просто так, ну а для всіх інших ми зробимо картки схожі на картки. І почнемо з цього:

.card {
background: white;
text-decoration: none;
color: #444;
box-shadow: 2px 0 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, щоб ми могли рухати картку при наведенні миші:

position: relative;
top: 0;
transition: all .1s ease-in;

За події hover піднімаємо картку і робимо тінь трохи насиченіший:

.card:hover {
top: -2px;
box-shadow: 0 4px 5px rgba(0,0,0,0.2);
}

Типографіка

Додамо базові стилі шрифтів, щоб змінювався колір і відступи.

.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;
}

Ось що повинно вийти:

Превью

Превью буде у вигляді фонового зображення, тому нам доведеться додати трохи зайвої розмітки:

Необхідно перевірити, щоб у .thumb були задані розміри, а фоновий малюнок правильно заповнював блок:

.card .thumb {
padding-bottom: 60%;
background-size: cover;
background-position: center center;
}

Добре, ось що у нас вийшло:

Flexbox і елемент article

Ім’я автора необхідно вирівняти по нижній межі картки, незалежно від кількості контенту зверху. Ось тут нам допоможе Flexbox:

.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;) до них, щоб ці параграфи займали залишився вертикальне простір і притискалися до верхньої межі.

.card p {
flex: 1; /* розтягуємо p */
line-height: 1.4;
}

Краще!

Перемикання сітки

Ми майже закінчили. Однак CSS Grid дозволяє нам повністю перебудовувати макет, розміщуючи елементи в будь-якому порядку та будь-яких розмірів. У нашому демо ми хотіли розтягнути нашу першу картку на дві колонки (назвемо її обраною) на всіх екранах крім самих маленьких. Зробимо це в нашому медіа запиті номер 1:

@media only screen and (min-width: 500px) {

.item-1 {
grid-column: 1/ span 2;
}
}

Повертаючись до вступного уроку за grid областях, ми говоримо, що крім того, що перший елемент повинен бути 500px, він також повинен починатися на першої рядку сітки і займати дві колонки. Інші елементи сітки розміщуються автоматично.

В цьому ж медіа запиті я змінив font-size заголовка в обраній картці.

Висновок

Хороший урок з Grid і Flexbox. Grid обробляє наш головний макет у двох вимірах, а Flexbox працює з вертикальним вирівнюванням елементів всередині карток. Поиграйтесь з кодом!