Урок 8 из 49 · Месяц 1. HTML5 и CSS3

CSS-переменные и медиазапросы

Содержание урока

Когда стилей становится много, один и тот же цвет или отступ повторяется в десятках мест, и поменять его — настоящая мука. В этом уроке познакомимся с CSS-переменными, которые решают эту проблему, и с медиазапросами — способом применять стили только при определённых условиях, например на узком экране. Полноценную адаптивную вёрстку будем разбирать позже, а сейчас поймём сам механизм. В конце урока установим Git — он понадобится уже в следующем месяце.

CSS-переменные

Проблема

Посмотрите на стили из прошлых уроков:

.btn        { background-color: #3182ce; }
.card-price { color: #3182ce; }
.link:hover { color: #3182ce; }
.tab        { border-bottom: 3px solid #3182ce; }

Синий #3182ce — фирменный цвет — повторяется четыре раза. Дизайнер решил сменить его на зелёный — нужно найти и заменить все вхождения, ничего не пропустить и не задеть похожий, но другой цвет. В реальном проекте таких мест сотни.

Решение: переменная

CSS-переменная (официально — custom property, «пользовательское свойство») — это именованное значение, которое задают один раз и используют сколько угодно. Как контакт в телефоне: вы не помните номер, а звоните «Маме», и если номер поменяется, его правят в одном месте.

:root {
  --color-primary: #3182ce;
}

.btn        { background-color: var(--color-primary); }
.card-price { color: var(--color-primary); }
.link:hover { color: var(--color-primary); }
.tab        { border-bottom: 3px solid var(--color-primary); }

Теперь, чтобы сменить фирменный цвет на всём сайте, достаточно поменять одну строку.

Как это устроено

  • Имя переменной обязательно начинается с двух дефисов: --color-primary.
  • Объявляется она как обычное свойство внутри селектора.
  • :root — псевдокласс, который выбирает корневой элемент <html>. Переменные, объявленные в нём, видны на всей странице.
  • var(--имя) — подставить значение переменной.
  • Имена чувствительны к регистру: --Color и --color — разные переменные.

Что хранить в переменных

Всё, что повторяется: цвета, шрифты, отступы, скругления, тени. Это та самая «шпаргалка» из урока Планирование вёрстки, шрифты и картинки, только теперь прямо в коде.

:root {
  /* Цвета */
  --color-primary: #3182ce;
  --color-primary-dark: #2b6cb0;
  --color-text: #1a202c;
  --color-muted: #718096;
  --color-bg: #f7fafc;
  --color-white: #ffffff;

  /* Шрифты */
  --font-main: "Inter", Arial, sans-serif;

  /* Отступы */
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 2rem;

  /* Прочее */
  --radius: 12px;
  --shadow: 0 10px 20px rgb(0 0 0 / 10%);
}

body {
  font-family: var(--font-main);
  color: var(--color-text);
  background-color: var(--color-bg);
}

.card {
  padding: var(--space-lg);
  border-radius: var(--radius);
  background-color: var(--color-white);
  box-shadow: var(--shadow);
}

.btn {
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius);
  background-color: var(--color-primary);
  color: var(--color-white);
}

.btn:hover {
  background-color: var(--color-primary-dark);
}

Запасное значение

Если переменная не объявлена, var() может подставить запасное значение — его пишут через запятую:

.alert {
  color: var(--color-danger, red);   /* если --color-danger нет — будет red */
}

Переменные наследуются и переопределяются

Переменные подчиняются каскаду и наследуются вниз по дереву. Значит, их можно переопределить для части страницы:

<button class="btn">Обычная</button>
<button class="btn btn-danger">Удалить</button>
.btn {
  --btn-bg: var(--color-primary);
  background-color: var(--btn-bg);
  color: white;
}

.btn-danger {
  --btn-bg: #e53e3e;   /* меняем только переменную */
}

У второй кнопки оба класса: .btn задаёт фон через переменную, а .btn-danger (он ниже в коде при той же специфичности) меняет значение переменной. Остальные стили кнопки остаются общими.

Переменные в вычислениях: calc

Функция calc() позволяет считать прямо в CSS, в том числе с переменными и разными единицами:

:root {
  --header-height: 64px;
}

.page {
  min-height: calc(100vh - var(--header-height));   /* экран минус шапка */
}

.section {
  padding: calc(var(--space-lg) * 2) var(--space-md);  /* 4rem 1rem */
}

Вокруг + и - внутри calc обязательны пробелы: calc(100% - 20px) работает, а calc(100%-20px) — нет.

Медиазапросы

Что это

Медиазапрос (media query) — это условие, при котором применяется блок стилей. Как правило «если идёт дождь — возьми зонт»: «если ширина экрана меньше 768px — сделай колонки друг под другом».

@media (max-width: 768px) {
  .cards {
    flex-direction: column;
  }
}
  • @media — начало медиазапроса;
  • (max-width: 768px) — условие: ширина окна не больше 768px;
  • внутри фигурных скобок — обычные CSS-правила, которые действуют только при выполнении условия.

Где писать медиазапросы

Медиазапросы пишут после основных стилей. Они не повышают специфичность, поэтому при одинаковых селекторах выигрывает то, что ниже — работает обычное правило порядка каскада.

/* Основные стили */
.title {
  font-size: 3rem;
}

/* Изменения для узких экранов — ниже */
@media (max-width: 600px) {
  .title {
    font-size: 2rem;
  }
}

Если поставить медиазапрос выше основного правила, основное его перебьёт, и уменьшения шрифта не будет.

max-width и min-width

Условие Когда срабатывает Читается как
(max-width: 768px) Ширина ≤ 768px «до 768px»
(min-width: 768px) Ширина ≥ 768px «от 768px»
(min-width: 600px) and (max-width: 1024px) От 600 до 1024px «между»

В современных браузерах можно писать и короче, через знаки сравнения:

@media (width <= 768px) {
  .menu { display: none; }
}

@media (600px <= width <= 1024px) {
  .container { padding: 0 2rem; }
}

Обе записи работают одинаково; классическую max-width вы чаще встретите в чужом коде.

Пример: как это выглядит на практике

<div class="layout">
    <aside class="sidebar">Фильтры</aside>
    <main class="content">Товары</main>
</div>
.layout {
  display: flex;
  gap: 2rem;
}

.sidebar {
  flex: 0 0 250px;
  background-color: #edf2f7;
  padding: 1rem;
}

.content {
  flex: 1;
}

@media (max-width: 768px) {
  .layout {
    flex-direction: column;
  }

  .sidebar {
    flex-basis: auto;
  }
}

На широком экране фильтры слева, товары справа. Если окно ≤ 768px — фильтры встают сверху, товары под ними. Проверить легко: откройте страницу и сужайте окно браузера, или включите в DevTools режим устройства (Ctrl + Shift + M, на macOS Cmd + Shift + M) — там можно задать точную ширину.

Другие условия

/* Пользователь включил тёмную тему в системе */
@media (prefers-color-scheme: dark) {
  :root {
    --color-text: #f7fafc;
    --color-bg: #1a202c;
  }
}

/* Пользователь попросил меньше анимаций */
@media (prefers-reduced-motion: reduce) {
  * {
    transition: none;
  }
}

/* Стили для печати */
@media print {
  .header,
  .footer {
    display: none;
  }
}

Пример с тёмной темой показывает силу связки переменных и медиазапросов: мы меняем всего две переменные, а цвета всего сайта переключаются сами.

Почему пока «без адаптива»

Адаптивная вёрстка — это целый подход: как планировать сетку под разные устройства, какие брейкпоинты (точки перелома) выбирать, как начинать с мобильной версии (mobile first). Сейчас наша цель — понять механизм: медиазапрос — это просто условие для блока стилей. Полноценные адаптивные макеты разберём позже по курсу.

Ещё одно ограничение: переменные нельзя использовать в самом условии медиазапроса. @media (max-width: var(--bp)) не сработает — ширину пишут числом.

Установка Git

Git — система контроля версий. Она запоминает историю изменений в проекте, как «машина времени» для кода: можно посмотреть, что и когда менялось, вернуться к рабочей версии и работать над проектом в команде. Работать с Git мы начнём в следующем месяце, в уроке Git, Git Bash и первый проект. Сейчас просто установим его, чтобы потом не терять на это время.

Windows

  1. Скачайте установщик с официального сайта git-scm.com → Downloads → Windows.
  2. Запустите его. Почти все настройки можно оставить по умолчанию. На шаге выбора редактора можно выбрать Use Visual Studio Code as Git's default editor.
  3. На шаге про имя основной ветки выберите Override the default branch name и впишите main — это современное стандартное имя.
  4. После установки появится программа Git Bash — терминал, в котором удобно работать с Git.

macOS

Откройте приложение Терминал и выполните:

git --version

Если Git не установлен, macOS сама предложит установить инструменты командной строки (Command Line Tools) — согласитесь. Другой способ — через менеджер пакетов Homebrew: brew install git.

Проверка и первая настройка

Откройте терминал (Git Bash на Windows или Терминал на macOS; подойдёт и встроенный терминал VS Code) и выполните:

git --version

Вы должны увидеть версию, например git version 2.x.x. Теперь представьтесь Git — эти данные будут подписывать каждое ваше сохранение (коммит):

git config --global user.name "Aida Sydykova"
git config --global user.email "aida@example.com"
git config --global init.defaultBranch main
  • user.name — ваше имя латиницей;
  • user.email — почта, которую вы будете использовать на GitHub;
  • init.defaultBranch main — новые проекты будут создаваться с основной веткой main;
  • --global — настройка действует для всех проектов на этом компьютере.

Проверить настройки:

git config --list

Практика

Ментор на занятии даст дополнительные задания на переменные и медиазапросы. Для самостоятельной работы:

  1. Переменные цветов. Возьмите страницу магазина из прошлого урока и вынесите все цвета в переменные в :root. Результат: смена --color-primary меняет цвет кнопок, цен и ссылок одновременно.
  2. Набор переменных. Добавьте переменные для шрифта, трёх размеров отступов, скругления и тени, и замените ими все повторяющиеся значения. Результат: в правилах почти не осталось «голых» чисел и цветов.
  3. Кнопки-варианты. Сделайте кнопку .btn и модификаторы .btn-danger, .btn-success, которые меняют только переменную --btn-bg. Результат: три кнопки разных цветов с общими остальными стилями.
  4. Первый медиазапрос. Сделайте макет «боковая панель + контент» и медиазапрос, который при ширине ≤ 768px ставит панель над контентом и уменьшает заголовок. Результат: при сужении окна раскладка меняется.
  5. Тёмная тема и Git. Добавьте @media (prefers-color-scheme: dark) с переопределением переменных, переключите тему в системе и проверьте результат. Установите Git и выполните три команды git config. Результат: страница меняет цвета вслед за системой, git config --list показывает ваше имя и почту.

Итоги

  • CSS-переменные объявляют с -- (обычно в :root) и используют через var(--имя, запасное).
  • Переменные наследуются и переопределяются для части страницы — удобно для вариантов компонентов.
  • calc() считает значения прямо в CSS; пробелы вокруг + и - обязательны.
  • Медиазапрос @media (условие) { ... } применяет стили только при выполнении условия; пишут его после основных стилей.
  • max-width — «до», min-width — «от»; без meta viewport медиазапросы на телефонах не сработают.
  • Git установлен и настроен: user.name, user.email, init.defaultBranch main.
Отзыв