Урок 5.3: Адаптивность
Модуль 5 — Продвинутый CSS
Что такое адаптивный дизайн
Адаптивный (или отзывчивый) дизайн — это подход, при котором сайт одинаково хорошо выглядит на любом устройстве: от 4K-монитора до старого iPhone. Не существует «мобильной версии» и «десктопной версии» — есть один сайт, который подстраивается под размер экрана.
Раньше сайты делали фиксированной ширины (например, 960px). Если открыть такой сайт на телефоне — контент уезжает за правый край, приходится зумить и скроллить по горизонтали. Кошмар. Сейчас так никто не делает.
Адаптивный дизайн строится на трёх китах:
- Гибкая сетка — элементы используют проценты, а не пиксели
- Гибкие изображения — картинки масштабируются под контейнер
- Медиа-запросы — CSS-правила, которые включаются на определённой ширине экрана
/* Главный принцип: контент подстраивается под экран, а не наоборот */
/* Плохо: фиксированная ширина */
.container {
width: 960px; /* на телефоне вылезет */
}
/* Хорошо: гибкая ширина */
.container {
max-width: 960px;
width: 100%;
padding: 0 16px;
}
Первое правило адаптивности: никогда не используй фиксированную ширину там, где можно использовать max-width или проценты. max-width: 960px + width: 100% означает: «контейнер шириной не больше 960px, но на маленьких экранах — на всю ширину с отступами».
meta viewport tag — самое важное для мобильных
Без этого тега адаптивность не будет работать. Вообще. Ты можешь написать идеальные медиа-запросы, но на телефоне сайт будет показываться как уменьшенная копия десктопа.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Что делает этот тег:
width=device-width— говорит браузеру: «используй реальную ширину устройства, не выдумывай 980px»initial-scale=1.0— начальный масштаб 100% (не зум)
Без него iPhone и Android будут рендерить страницу как на десктопе шириной 980px и потом масштабировать. Контент будет мелким. Пользователю придётся зумить пальцами. С этим тегом страница использует реальные пиксели устройства.
Этот тег должен быть в <head> каждого HTML-документа. Если ты забудешь его — всё, что мы будем обсуждать дальше, не имеет смысла.
<meta name="viewport" content="width=device-width, initial-scale=1.0"> в каждую страницу. Даже если ты делаешь «просто страничку». Это стандарт.
@media (max-width: 768px) — точка перелома
@media (медиа-запросы) — это CSS-правила, которые применяются только при определённых условиях. Чаще всего — при определённой ширине экрана.
/* Базовые стили — для всех экранов */
.grid {
display: flex;
gap: 20px;
}
.grid .item {
flex: 1;
background: #e94560;
padding: 20px;
}
/* Когда экран УЖЕ 768px или МЕНЬШЕ — включаются эти стили */
@media (max-width: 768px) {
.grid {
flex-direction: column;
}
.grid .item {
background: #10b981;
}
}
max-width: 768px означает: «если ширина экрана меньше или равна 768px, примени эти стили». Это называется точка перелома (breakpoint) — граница, при достижении которой макет перестраивается.
Попробуй изменить ширину окна браузера. Ниже — демонстрация точки перелома на 600px. Когда ширина меньше 600px, блоки встают в колонку и меняют цвет:
Сузь окно до <600px — блоки станут в колонку и покраснеют
Стандартные точки перелома, которые используют в вебе:
- 320px — старые смартфоны
- 480px — современные смартфоны
- 768px — планшеты
- 1024px — маленькие ноутбуки и iPad в landscape
- 1280px — десктоп
Но на практике не стоит ориентироваться на конкретные устройства. Точки перелома должны определяться контентом — смотри, в какой момент макет начинает выглядеть плохо, и ставь breakpoint там.
/* Mobile-first подход: сначала база для мобилок */
.grid {
display: flex;
flex-direction: column;
gap: 16px;
}
/* Потом улучшаем для планшетов */
@media (min-width: 768px) {
.grid {
flex-direction: row;
flex-wrap: wrap;
}
.grid .item {
flex: 1 1 calc(50% - 16px);
}
}
/* И для десктопа */
@media (min-width: 1024px) {
.grid .item {
flex: 1;
}
}
Обрати внимание: здесь используется min-width, а не max-width. Это Mobile-first подход: стили по умолчанию — для мобильных, а медиа-запросы добавляют улучшения для больших экранов. Это проще и чище, чем наоборот.
min-width в медиа-запросах (mobile-first), а не max-width. Так ты начинаешь с мобильной версии и добавляешь стили для широких экранов. Меньше шансов что-то сломать.
vw, vh, % — относительные единицы
Пиксели (px) — абсолютные единицы. 100px — это 100px на любом экране. Для адаптивности этого мало. Нужны относительные единицы, которые подстраиваются под размер экрана.
Основные относительные единицы:
- % — процент от родителя.
width: 50%— половина ширины родителя. - vw — процент от ширины окна.
width: 50vw— половина окна браузера. - vh — процент от высоты окна.
height: 100vh— на всю высоту окна. - em — относительно размера шрифта родителя.
padding: 2em— 2 × размер шрифта родителя. - rem — относительно корневого шрифта (
<html>).margin: 1.5rem— 1.5 × размер шрифта в<html>.
Меняй ширину окна — относительные единицы (%, vw) меняются, пиксели — нет.
font-size: 1.2em — размер зависит от родительского шрифта
Где что использовать:
- % — для ширины колонок, карточек, контейнеров
- vw — для глобальных отступов, крупных заголовков, секций на всю ширину
- vh — для секций на всю высоту экрана (hero, full-screen блоки)
- rem — для отступов, размеров текста (удобно, если пользователь меняет базовый размер шрифта)
- em — для отступов, которые должны масштабироваться с размером шрифта
Классический пример — секция на всю высоту экрана:
.hero {
width: 100vw; /* на всю ширину окна */
height: 100vh; /* на всю высоту окна */
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea, #764ba2);
}
Эта секция будет ровно на весь экран, независимо от размера устройства. Ни тебе фиксированной высоты, ни скролла — чистая адаптивность.
Ещё один приём — адаптивный текст через clamp(). Это CSS-функция, которая задаёт диапазон значений:
/* font-size: от 16px до 32px, пропорционально ширине окна */
h1 {
font-size: clamp(1.5rem, 4vw, 2.5rem);
}
/* padding: от 16px до 48px */
.container {
padding: clamp(1rem, 3vw, 3rem);
}
clamp(min, preferred, max) — минимальное значение, желаемое (гибкое), максимальное. Идеально для адаптивных заголовков и отступов.
Практика: меню, которое на телефоне становится вертикальным
Давай сделаем полноценную адаптивную страницу. У нас будет меню, которое на десктопе — горизонтальное, а на мобилке — вертикальное, плюс сетка карточек, которая на телефоне превращается в одну колонку.
Вот полный код. Скопируй, открой в браузере и меняй ширину окна:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Адаптивный сайт</title>
<style>
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', system-ui, sans-serif;
margin: 0;
background: #f5f5f5;
color: #333;
}
/* Хедер */
.header {
background: linear-gradient(135deg, #1a1a2e, #16213e);
color: #fff;
padding: 16px 24px;
display: flex;
align-items: center;
justify-content: space-between;
}
.header .logo {
font-size: 1.3em;
font-weight: bold;
}
/* Навигация */
.nav {
display: flex;
gap: 4px;
}
.nav a {
color: #ccc;
text-decoration: none;
padding: 8px 18px;
border-radius: 6px;
transition: background 0.2s, color 0.2s;
font-size: 0.95em;
}
.nav a:hover {
background: #533483;
color: #fff;
}
.nav-toggle {
display: none;
background: none;
border: 1px solid rgba(255,255,255,0.3);
color: #fff;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 0.9em;
}
/* Контент */
.content {
max-width: 1100px;
margin: 0 auto;
padding: 40px 24px;
}
.content h1 {
font-size: clamp(1.8rem, 4vw, 2.5rem);
margin-bottom: 12px;
}
.content > p {
color: #666;
font-size: 1.05em;
max-width: 600px;
margin-bottom: 40px;
line-height: 1.7;
}
/* Сетка карточек */
.card-grid {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.card {
background: #fff;
border-radius: 14px;
padding: 28px 24px;
flex: 1 1 calc(33.333% - 14px);
min-width: 240px;
box-shadow: 0 2px 8px rgba(0,0,0,0.04);
transition: transform 0.3s, box-shadow 0.3s;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.08);
}
.card .icon {
font-size: 2em;
margin-bottom: 12px;
}
.card h3 {
margin: 0 0 8px;
font-size: 1.15em;
}
.card p {
color: #777;
font-size: 0.9em;
line-height: 1.6;
margin: 0;
}
/* Футер */
.footer {
text-align: center;
padding: 30px 24px;
color: #999;
font-size: 0.85em;
border-top: 1px solid #e0e0e0;
margin-top: 40px;
}
/* Адаптация: планшеты */
@media (max-width: 768px) {
.card {
flex: 1 1 calc(50% - 10px);
}
}
/* Адаптация: телефоны */
@media (max-width: 640px) {
.nav {
display: none;
position: absolute;
top: 60px;
left: 0;
width: 100%;
background: #1a1a2e;
flex-direction: column;
padding: 12px;
border-top: 1px solid #2a2a4a;
}
.nav.open {
display: flex;
}
.nav a {
display: block;
padding: 14px 16px;
border-bottom: 1px solid #2a2a4a;
border-radius: 0;
}
.nav a:last-child {
border-bottom: none;
}
.nav-toggle {
display: block;
}
.card {
flex: 1 1 100%;
}
.header {
position: relative;
}
}
</style>
</head>
<body>
<header class="header">
<div class="logo">🌟 MySite</div>
<button class="nav-toggle" onclick="this.nextElementSibling.classList.toggle('open')">☰ Меню</button>
<nav class="nav">
<a href="#">Главная</a>
<a href="#">О нас</a>
<a href="#">Услуги</a>
<a href="#">Блог</a>
<a href="#">Контакты</a>
</nav>
</header>
<main class="content">
<h1>Адаптивный дизайн — это просто</h1>
<p>
Сузь окно браузера — меню превратится в вертикальное, а карточки
встанут в одну колонку. На десктопе они располагаются в три колонки,
на планшете — в две, на телефоне — одна под другой.
</p>
<div class="card-grid">
<div class="card">
<div class="icon">📱</div>
<h3>Mobile-first</h3>
<p>Сначала проектируем для мобильных устройств, потом добавляем улучшения для больших экранов.</p>
</div>
<div class="card">
<div class="icon">📐</div>
<h3>Гибкая сетка</h3>
<p>Элементы используют проценты, flexbox и относительные единицы вместо фиксированных пикселей.</p>
</div>
<div class="card">
<div class="icon">📏</div>
<h3>Медиа-запросы</h3>
<p>CSS-правила, которые включаются на определённой ширине экрана и перестраивают макет.</p>
</div>
<div class="card">
<div class="icon">🖼️</div>
<h3>Гибкие изображения</h3>
<p>Картинки масштабируются с помощью max-width: 100%, чтобы не вылезать за контейнер.</p>
</div>
<div class="card">
<div class="icon">🔤</div>
<h3>Относительные единицы</h3>
<p>vw, vh, %, rem, em — единицы, которые подстраиваются под размер экрана и шрифта.</p>
</div>
<div class="card">
<div class="icon">🎯</div>
<h3>Точки перелома</h3>
<p>Breakpoints в 640px, 768px, 1024px — стандартные границы, где макет перестраивается.</p>
</div>
</div>
</main>
<footer class="footer">
© 2026 MySite. Работает на всех устройствах.
</footer>
<script>
// Закрывать меню при клике на ссылку
document.querySelectorAll('.nav a').forEach(link => {
link.addEventListener('click', () => {
document.querySelector('.nav').classList.remove('open');
});
});
</script>
</body>
</html>
Давай разберём, как работает адаптивность в этом примере:
1. meta viewport — первая строка в head. Без неё ничего не работает.
2. Mobile-first меню:
- На десктопе (шире 640px) —
.navэтоdisplay: flex, ссылки в ряд. - На телефоне (уже 640px) —
@media (max-width: 640px)делает.navскрытым (display: none), кнопка.nav-toggleстановится видимой (display: block). При клике на кнопку (onclick) добавляется класс.open, и меню показывается вертикальным списком.
3. Адаптивная сетка карточек:
- По умолчанию (десктоп) —
flex: 1 1 calc(33.333% - 14px), три в ряд. - На планшете (≤768px) —
flex: 1 1 calc(50% - 10px), две в ряд. - На телефоне (≤640px) —
flex: 1 1 100%, одна колонка.
4. Гибкий контейнер:
max-width: 1100px+ авто-отступы — контейнер не становится шире 1100px, но на маленьких экранах использует всю ширину с padding'ами.
5. Адаптивный заголовок:
font-size: clamp(1.8rem, 4vw, 2.5rem)— от 1.8rem до 2.5rem в зависимости от ширины окна.
Вот ещё несколько приёмов адаптивности, которые пригодятся:
/* 1. Гибкое изображение */
img {
max-width: 100%;
height: auto;
display: block;
}
/* 2. Адаптивные отступы */
.container {
padding: clamp(1rem, 3vw, 2rem);
}
/* 3. Скрытие элементов на мобилке */
.desktop-only { display: block; }
.mobile-only { display: none; }
@media (max-width: 640px) {
.desktop-only { display: none; }
.mobile-only { display: block; }
}
/* 4. Адаптивный текст */
p {
font-size: clamp(0.95rem, 2vw, 1.1rem);
}
/* 5. Сетка без медиа-запросов (auto-fill) */
.grid-auto {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
Последний приём — auto-fill — особенно крут. Он автоматически создаёт столько колонок, сколько влезает, при минимальной ширине 280px. Медиа-запросы не нужны — сетка адаптируется сама.
Давай подведём итог. Вот шпаргалка по адаптивности:
/* АДАПТИВНОСТЬ — ШПАРГАЛКА */
/* 1. Всегда в head */
<meta name="viewport" content="width=device-width, initial-scale=1.0">
/* 2. Гибкий контейнер */
.container {
max-width: 1200px;
width: 100%;
margin: 0 auto;
padding: 0 16px;
}
/* 3. Гибкие изображения */
img, video, iframe {
max-width: 100%;
height: auto;
}
/* 4. Mobile-first медиа-запросы */
/* База — для мобилок */
.card { flex: 1 1 100%; }
/* Планшет */
@media (min-width: 768px) {
.card { flex: 1 1 calc(50% - 10px); }
}
/* Десктоп */
@media (min-width: 1024px) {
.card { flex: 1 1 calc(33.333% - 14px); }
}
/* 5. Относительные единицы */
width: 100%; /* от родителя */
height: 100vh; /* на весь экран */
font-size: clamp(1rem, 3vw, 2rem); /* адаптивный текст */
padding: 2rem; /* от корневого шрифта */
/* 6. Точки перелома (по контенту!) */
/* 640px — телефоны */
/* 768px — планшеты */
/* 1024px — десктоп */
Главное, что нужно запомнить:
<meta name="viewport">— обязателен для адаптивности- Mobile-first: сначала стили для телефона, потом для больших экранов
- Медиа-запросы — перестраивают макет под размер экрана
- Относительные единицы (%, vw, vh, rem) — подстраиваются под экран
- Точки перелома ставятся там, где контент начинает выглядеть плохо
max-width: 100%на картинках — чтобы они не вылезали за родителяclamp()— удобная функция для адаптивных размеров
Адаптивность — это не магия и не сложно. Это просто привычка писать гибкие стили. Начни с meta viewport и max-width вместо фиксированной ширины — и ты уже на полпути к сайту, который одинаково хорошо выглядит на любом устройстве.
Поздравляю! Ты прошёл модули 4 и 5. Теперь ты умеешь работать с блочной моделью, flexbox, позиционированием, анимациями и адаптивностью. Это основа современного CSS. В следующих модулях мы перейдём к JavaScript — и там эти знания пригодятся каждый день.
<meta name="viewport">, если его нет. Замени фиксированную ширину на max-width с процентами. Добавь один медиа-запрос для телефона, чтобы меню стало вертикальным. Посмотри, как страница преобразится на мобильном устройстве.
Урок 5.3: Адаптивность
5 вопросов