Пошук уроків, статей та іншого контенту
Спроєктуєте макет від вузьких екранів до широких, додаючи стилі через прогресивні брейкпоїнти.
Mobile First — це підхід до розроблення інтерфейсів, за якого спочатку створюють стилі для найвужчих екранів, а потім поступово адаптують макет для ширших пристроїв.
У базових стилях описують мобільну версію, а зміни для планшетів і великих екранів додають через медіазапити з min-width:
@media (min-width: 768px) {
/* Стилі для ширших екранів */
}Такий підхід називають прогресивним покращенням:
базовий макет працює на вузькому екрані;
на ширшому екрані додається більше простору;
компоненти можуть змінювати напрямок, розмір або розташування;
кожен наступний брейкпоїнт додає лише необхідні зміни.
Мобільний підхід змушує визначити найважливіше:
який контент має бути доступним насамперед;
які елементи можна розмістити вертикально;
які відступи та розміри справді потрібні;
як інтерфейс працюватиме за обмеженої ширини.
Серед переваг:
менше зайвих стилів для мобільних пристроїв;
зрозуміліша структура CSS;
простіше контролювати адаптивність;
легше забезпечити читабельність на малих екранах;
нові стилі додаються, а не скасовують велику кількість попередніх правил.
У Mobile First мобільні стилі не потрібно вкладати в медіазапит. Вони є звичайними стилями елементів:
.card {
padding: 16px;
border-radius: 12px;
}
.card-list {
display: grid;
gap: 16px;
}Ці правила застосовуються за замовчуванням, зокрема на вузьких екранах.
Стилі для ширших екранів додають пізніше:
@media (min-width: 768px) {
.card-list {
grid-template-columns: repeat(2, 1fr);
}
}На мобільному екрані картки розташовані в один стовпчик. Починаючи від ширини 768px, вони розміщуються у два стовпчики.
Брейкпоїнт — це ширина viewport, на якій макет змінює правила відображення.
Наприклад:
@media (min-width: 640px) {
/* Невеликі планшети або великі телефони */
}
@media (min-width: 768px) {
/* Планшети */
}
@media (min-width: 1024px) {
/* Невеликі ноутбуки */
}Не варто автоматично додавати брейкпоїнти для кожного популярного розміру пристрою. Краще додавати медіазапит тоді, коли поточна структура перестає бути зручною.
Наприклад, якщо навігація більше не поміщається в один рядок, саме це може бути підставою для нового брейкпоїнта.
Брейкпоїнти варто визначати за потребами макета, а не за назвами конкретних пристроїв.
min-width і max-widthДля Mobile First зазвичай використовують min-width:
/* Базові мобільні стилі */
.layout {
display: block;
}
/* Зміни для ширших екранів */
@media (min-width: 768px) {
.layout {
display: grid;
grid-template-columns: 240px 1fr;
}
}Правило з min-width: 768px застосовується на ширині 768px і більше.
Підхід із max-width починається з правил для великих екранів і потім перевизначає їх для менших:
@media (max-width: 767px) {
/* Мобільні зміни */
}Це може працювати, але така структура вже не є типовим Mobile First підходом. Коли стилі для мобільних екранів є базовими, CSS зазвичай легше читати й підтримувати.
Нижче наведено повний приклад сторінки з картками курсів. На вузьких екранах:
навігація розташована вертикально;
картки утворюють один стовпчик;
заголовок має менший розмір.
На ширших екранах:
навігація стає горизонтальною;
картки переходять у два, а потім у три стовпчики;
контейнер отримує більший горизонтальний відступ.
<!doctype html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Каталог курсів</title>
<style>
:root {
color-scheme: light;
font-family: Arial, sans-serif;
color: #172033;
background-color: #f4f6f8;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.container {
width: min(100% - 32px, 1180px);
margin-inline: auto;
}
.header {
padding-block: 20px;
background-color: #ffffff;
border-bottom: 1px solid #dfe4ea;
}
.header__content {
display: flex;
flex-direction: column;
gap: 16px;
}
.logo {
margin: 0;
font-size: 24px;
}
.navigation {
display: flex;
flex-direction: column;
gap: 8px;
}
.navigation a {
color: #3157d5;
text-decoration: none;
}
.main {
padding-block: 32px;
}
.intro {
margin-bottom: 24px;
}
.intro h1 {
margin: 0 0 8px;
font-size: 32px;
line-height: 1.1;
}
.intro p {
max-width: 620px;
margin: 0;
color: #536174;
line-height: 1.5;
}
.course-list {
display: grid;
gap: 16px;
}
.course-card {
padding: 20px;
background-color: #ffffff;
border: 1px solid #dfe4ea;
border-radius: 12px;
}
.course-card h2 {
margin: 0 0 8px;
font-size: 20px;
}
.course-card p {
margin: 0;
color: #536174;
line-height: 1.5;
}
/* Планшетна версія */
@media (min-width: 640px) {
.container {
width: min(100% - 48px, 1180px);
}
.header__content {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.navigation {
flex-direction: row;
gap: 20px;
}
.course-list {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
/* Версія для широких екранів */
@media (min-width: 1024px) {
.main {
padding-block: 56px;
}
.intro {
margin-bottom: 32px;
}
.intro h1 {
font-size: 44px;
}
.course-list {
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 24px;
}
.course-card {
padding: 24px;
}
}
</style>
</head>
<body>
<header class="header">
<div class="container header__content">
<p class="logo">Fullstack Academy</p>
<nav class="navigation" aria-label="Основна навігація">
<a href="#courses">Курси</a>
<a href="#about">Про платформу</a>
<a href="#contacts">Контакти</a>
</nav>
</div>
</header>
<main class="main">
<div class="container">
<section class="intro" id="courses">
<h1>Оберіть курс</h1>
<p>
Вивчайте технології веброзроблення за практичними матеріалами
та прикладами.
</p>
</section>
<section class="course-list" aria-label="Список курсів">
<article class="course-card">
<h2>HTML і CSS</h2>
<p>Створення структури сторінки та адаптивних інтерфейсів.</p>
</article>
<article class="course-card">
<h2>JavaScript</h2>
<p>Робота з логікою, подіями та динамічними даними.</p>
</article>
<article class="course-card">
<h2>React</h2>
<p>Побудова компонентних користувацьких інтерфейсів.</p>
</article>
</section>
</div>
</main>
</body>
</html>Перед реалізацією визначте, як компоненти поводяться на різних ширинах.
Наприклад, для блоку з картками можна скласти такий план:
картки розташовані в один стовпчик;
відстань між картками — 16px;
заголовок має помірний розмір;
елементи навігації розташовані один під одним.
картки розташовані у два стовпчики;
навігація переходить у рядок;
контейнер отримує більші горизонтальні відступи.
картки розташовані у три стовпчики;
збільшуються внутрішні відступи;
заголовок стає більшим;
основний контент отримує більше вертикального простору.
Цей план допомагає не створювати випадкові медіазапити, а послідовно розширювати макет.
У Mobile First правила зазвичай розташовані в такому порядку:
базові стилі;
медіазапит для першого ширшого екрана;
медіазапит для наступного ширшого екрана.
.component {
/* Мобільна версія */
}
@media (min-width: 640px) {
.component {
/* Додаткові зміни для середньої ширини */
}
}
@media (min-width: 1024px) {
.component {
/* Додаткові зміни для широкої ширини */
}
}Оскільки медіазапити йдуть від меншої ширини до більшої, пізніші правила можуть поступово перевизначати попередні.
Адаптивний макет не означає, що всі значення повинні бути відносними. Фіксовані значення доречні для:
невеликих відступів;
товщини меж;
радіусів;
мінімальних розмірів елементів керування.
Для ширини контейнера зручно поєднувати відносне значення та максимальну ширину:
.container {
width: min(100% - 32px, 1180px);
margin-inline: auto;
}Це означає:
контейнер займає всю доступну ширину з урахуванням бічних відступів;
на дуже широкому екрані його ширина не перевищує 1180px;
margin-inline: auto центрує контейнер.
Під час перевірки макета:
відкрийте інструменти розробника;
увімкніть режим перегляду для мобільних пристроїв;
перевірте вузьку ширину;
поступово збільшуйте ширину viewport;
спостерігайте, у який момент макет перестає бути зручним;
саме для цього моменту додайте або скоригуйте брейкпоїнт.
Перевіряйте не лише типові ширини. Протестуйте проміжні значення, наприклад між 640px і 1024px. Макет має коректно працювати не тільки на умовному телефоні, планшеті чи ноутбуці, а й на всіх ширинах між ними.
Якщо спочатку створити складний десктопний макет, для мобільного екрана доведеться скасовувати багато правил:
/* Небажаний для Mobile First порядок */
.layout {
display: grid;
grid-template-columns: 240px 1fr;
}
@media (max-width: 767px) {
.layout {
display: block;
grid-template-columns: none;
}
}Краще почати з простішого стану:
.layout {
display: block;
}
@media (min-width: 768px) {
.layout {
display: grid;
grid-template-columns: 240px 1fr;
}
}Медіазапит не потрібен лише тому, що існує певна ширина популярного пристрою. Додавайте його, коли поточний макет справді потребує змін.
Занадто велика кількість брейкпоїнтів:
ускладнює читання CSS;
збільшує кількість винятків;
може спричинити конфлікти між правилами;
ускладнює подальше редагування.
meta viewportБез цього елемента мобільний браузер може відображати сторінку у віртуальному широкому viewport, тому адаптивні правила працюватимуть не так, як очікується:
<meta name="viewport" content="width=device-width, initial-scale=1">Mobile First не означає, що мобільна версія повинна містити менше важливої інформації. Основний контент має залишатися доступним, а змінюватися можуть:
порядок елементів;
розташування;
відступи;
розмір тексту;
кількість стовпчиків.
Правило на кшталт width: 1200px спричинить горизонтальне прокручування на вузьких екранах. Для контейнерів використовуйте гнучку ширину та max-width.
Створіть адаптивний блок профілю користувача.
Вимоги:
на мобільному екрані аватар, інформація та кнопка мають розташовуватися вертикально;
від ширини 640px інформація має займати доступний простір, а кнопка — розташовуватися праворуч;
від ширини 1024px блок має збільшити внутрішні відступи;
базові стилі напишіть без медіазапитів;
для ширших екранів використайте @media (min-width: ...);
перевірте результат на вузьких і проміжних ширинах.
Mobile First починається зі стилів для найвужчого екрана.
Базові мобільні правила пишуть без медіазапитів.
Адаптацію для ширших екранів додають через @media (min-width: ...).
Брейкпоїнти визначають за потребами макета, а не за назвами пристроїв.
Макет потрібно перевіряти на вузьких, широких і проміжних ширинах.
Гнучкі контейнери та поступове додавання стилів допомагають уникати зайвих перевизначень CSS.