Свойства CSS: что это, группы, каскад, наследование и переменные

Свойства CSS: что это, группы, каскад, наследование и переменные Полезное

CSS (Cascading Style Sheets, каскадные таблицы стилей) — язык описания внешнего вида документа: цвета, шрифты, отступы, размеры и расположение элементов HTML-страницы. К свойствам языка CSS относится то, что он отделяет оформление от содержимого и структуры документа (их задает HTML) и что одно описание стилей можно применить сразу к множеству элементов и страниц; в части тестов верным считают и вариант «CSS не чувствителен к регистру, пробелам и табуляции» (с оговоркой: имена классов, id и переменных регистр различают). При этом CSS — не язык программирования и не язык разметки: он не создает элементы и не хранит текст страницы.

У словосочетания «свойства CSS» два смысла, и их полезно развести сразу:

  • свойства языка — его особенности: каскадность, наследование, отделение стилей от HTML;
  • CSS-свойства — конкретные параметры оформления вроде color, margin, display, которые пишут в коде.

Примеры ниже проверены в Chromium 152, значения взяты из getComputedStyle.

Ответ на тест «к свойствам языка CSS относится то, что»

В школьных и вузовских тестах вариантов обычно 4-5, верных — два. Формулировки в разных тестах отличаются, поэтому ниже — типичные утверждения с разбором.

Утверждение Верно? Почему
CSS позволяет отделить оформление страницы от ее содержимого (структуры) да структура и текст — в HTML, внешний вид — в CSS
Один файл стилей может оформлять много страниц сайта сразу да файл подключают через <link rel="stylesheet"> к каждой странице
CSS не чувствителен к регистру, пробелам и табуляции да, с оговоркой P { COLOR: RED } сработает, переносы и отступы между объявлениями ни на что не влияют; но имена классов и id чувствительны к регистру (.Note не найдет class="note"), как и имена CSS-переменных
Стили каскадируются и частично наследуются да при конфликте правил побеждает одно по правилам каскада, часть свойств передается потомкам
CSS — язык программирования нет это декларативный язык стилей: он описывает, как элементы должны выглядеть, а не последовательность действий
CSS задает структуру и содержимое страницы нет это роль HTML
CSS работает только в одном браузере нет CSS — стандарт W3C, его поддерживают все современные браузеры

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

Мини-словарь: правило, селектор, свойство, значение

Код CSS состоит из правил. Правило — это селектор и блок объявлений в фигурных скобках:

p {
  color: #1a5fb4;
  font-size: 18px;
}
  • селектор (p) — к каким элементам применяется правило;
  • объявление (color: #1a5fb4;) — пара «свойство: значение», заканчивается точкой с запятой;
  • свойство (color) — что меняем;
  • значение (#1a5fb4) — на что меняем; у каждого свойства свой набор допустимых значений.

Если значение не подходит свойству (color: 18px), браузер игнорирует только это объявление, остальные правила продолжают работать. Chrome об этом в консоль не пишет, Firefox выводит предупреждение вида «Error in parsing value for ‘color’. Declaration dropped.»; в любом браузере отброшенное объявление видно в DevTools на панели стилей.

Минимальный рабочий пример

Сохраните файл как index.html и откройте в браузере:

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <title>Свойства CSS</title>
  <style>
    p {
      color: #1a5fb4;
      font-size: 18px;
      margin: 0 0 12px;
    }
    .note {
      color: #c01c28;
    }
  </style>
</head>
<body>
  <p>Обычный абзац - синий текст 18px.</p>
  <p class="note">Абзац с классом note - красный текст 18px.</p>
</body>
</html>

Первый абзац будет синим, второй — красным, оба с размером шрифта 18px. getComputedStyle возвращает для них rgb(26, 95, 180) и rgb(192, 28, 40). Второй абзац подходит под оба правила: font-size он берет из правила p (конфликта нет), а по color правила спорят — и побеждает .note, потому что селектор класса специфичнее селектора тега. Это и есть каскад в миниатюре.

Основные группы CSS-свойств

Свойств в CSS несколько сотен. Деление на группы ниже условное: в спецификациях свойства разложены по модулям.

Группа Примеры свойств Что задают
Текст и шрифт color, font-family, font-size, font-weight, line-height, text-align вид текста
Фон background-color, background-image заливку и картинку под элементом
Блочная модель width, height, padding, border, margin, box-sizing размеры и отступы блока
Раскладка display, flex, grid-template-columns, gap, position, float расположение элементов
Видимость и слои visibility, opacity, z-index, overflow что видно и что поверх чего
Анимация transition, animation, transform движение и плавные переходы

Как размеры блока складываются из width, padding и border, подробно разобрано в статье CSS и задание размера блоков, а старый способ раскладки через обтекание — в статье float в CSS. Сегодня для раскладки обычно берут flexbox (одномерный ряд или колонка) и grid (двумерная сетка), а float оставляют для обтекания картинки текстом.

Каскад: какое правило победит

Когда несколько объявлений задают одно и то же свойство одному элементу, браузер выбирает одно. Упрощенный порядок проверки такой:

  1. Важность и источник: !important сильнее обычных объявлений; стили автора сайта сильнее стилей браузера по умолчанию.
  2. Каскадные слои (@layer): объявления вне слоев сильнее объявлений в слоях.
  3. Специфичность селектора: id (1-0-0) сильнее класса, атрибута и псевдокласса (0-1-0), те сильнее тега (0-0-1).
  4. Порядок в коде: при равной специфичности побеждает объявление, которое стоит ниже.

Это упрощение: в полном алгоритме есть еще контекст (Shadow DOM), встроенные стили атрибута style и обратный порядок для !important-объявлений. Для обычной страницы четырех шагов достаточно.

<style>
  h1     { color: red; }     /* 0-0-1 */
  .title { color: blue; }    /* 0-1-0 */
  #main  { color: green; }   /* 1-0-0 */
  .title { color: orange; }  /* 0-1-0, стоит ниже первого .title */
</style>
<h1 id="main" class="title">Заголовок A</h1>
<h1 class="title">Заголовок B</h1>
<h1>Заголовок C</h1>

Результат: A — зеленый (id сильнее любого класса), B — оранжевый (два правила .title равны по специфичности, побеждает нижнее), C — красный (под него подходит только h1).

Наследование: какие свойства передаются потомкам

Часть свойств наследуется: если у элемента значение не задано, он берет его у родителя. В основном это свойства текста: color, font-*, line-height, text-align, visibility, а также пользовательские свойства (у зарегистрированных через @property это задает inherits). Свойства блока — margin, padding, border, background, width — не наследуются: иначе рамка родителя повторялась бы у каждого вложенного элемента.

<style>
  .card {
    color: #333333;
    font-family: Arial, sans-serif;
    border: 2px solid #999999;
    padding: 16px;
  }
</style>
<div class="card">
  Текст карточки
  <p>Абзац внутри</p>
  <button>Кнопка</button>
</div>

У абзаца цвет rgb(51, 51, 51) и шрифт Arial, sans-serif взяты у карточки, а рамка и отступ — нулевые (0px). Кнопка же осталась черной и с размером шрифта 13.3333px (значение Chromium, в других браузерах может отличаться): у элементов форм свой стиль браузера, он задает color и font явно и перекрывает наследование. Поэтому в сбросе стилей часто пишут:

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

После этого кнопка в той же карточке получает rgb(51, 51, 51), Arial, sans-serif и 16px. Управлять наследованием помогают ключевые слова: inherit (взять значение родителя), initial (начальное значение из спецификации), unset (наследуемые свойства ведут себя как inherit, остальные — как initial) и revert (вернуть стиль браузера).

Пользовательские свойства (CSS-переменные)

Пользовательское свойство — свойство, имя которого начинается с двух дефисов (--brand), а значение задает автор. Читают его функцией var(). Такие свойства часто называют CSS-переменными, но это обычные свойства: они подчиняются каскаду и наследуются.

:root {
  --brand: #1a5fb4;
  --gap: 16px;
}

.button {
  background: var(--brand);
  padding: var(--gap) calc(var(--gap) * 2);
  color: var(--button-text, white);
  border: none;
}

.button--danger {
  --brand: #c01c28;
}
<button class="button">Сохранить</button>
<button class="button button--danger">Удалить</button>

Первая кнопка синяя (rgb(26, 95, 180)) с отступами 16px 32px и белым текстом: --button-text нигде не объявлено, поэтому сработало запасное значение из второго аргумента var(). Вторая кнопка красная (rgb(192, 28, 40)): она переопределила --brand у себя, а правило .button не менялось.

Что важно помнить:

  • Область действия — это элемент, где свойство объявлено, и его потомки. Объявление в :root видно всей странице; объявление в классе — только внутри элементов с этим классом.
  • Имена чувствительны к регистру: --Brand и --brand — два разных свойства.
  • var() работает только в значениях свойств. Имя свойства, селектор и условие @media (min-width: var(--bp)) через переменную не задать.
  • Поддержка: пользовательские свойства работают во всех современных браузерах (Chrome с 49, Firefox с 31, Safari с 9.1); Internet Explorer их не поддерживает.

Частая ошибка: значение не подходит свойству

Неверно — в переменной оказалось значение не того типа:

.box {
  --gap: red;
  padding: 20px;
  padding: var(--gap);
}

Можно ожидать, что браузер откатится к padding: 20px. Фактически padding становится 0px. Браузер проверяет подставленное значение уже после каскада: объявление с var() победило, а red оказалось недопустимым для padding. Тогда свойство ведет себя как unset: padding не наследуется и получает начальное значение 0.

Исправление — зарегистрировать тип переменной через @property:

@property --space {
  syntax: "<length>";
  inherits: true;
  initial-value: 8px;
}

.box {
  --space: red;
  padding: var(--space);
}

Теперь --space: red не проходит проверку типа <length> и ведет себя как unset: при inherits: true переменная берет значение у родителя, а если выше по дереву ее никто не задал — initial-value. Здесь предка с --space нет, поэтому padding равен 8px; внутри блока с --space: 30px тот же .box получил бы 30px. Главное отличие от незарегистрированной переменной: вместо нуля получается осмысленная длина. @property поддерживается в актуальных Chrome, Safari и Firefox; в старых браузерах это правило игнорируется.

Изменение переменной из JavaScript

const root = document.documentElement;
root.style.setProperty('--brand', '#26a269');
console.log(getComputedStyle(root).getPropertyValue('--brand')); // #26a269

Элементы, которые берут цвет из var(--brand) и не переопределяют его у себя, сразу перекрашиваются — так делают переключение темы.

Если стиль не применился

  • Одинарный дефис (-brand) — это не пользовательское свойство, браузер пропустит объявление.
  • Разный регистр в объявлении и в var() — значение не найдется, сработает запасное или начальное.
  • Переменная объявлена в соседнем блоке, а не у предка — наследованием она туда не дойдет; перенесите объявление в :root или в общий родительский элемент.
  • Правило проиграло каскад — в DevTools (вкладка Elements, панель Styles) зачеркнутое объявление показывает, кто его перекрыл.

Выводы

  • К свойствам языка CSS относят отделение оформления от содержимого (HTML) и возможность оформить одним описанием много элементов и страниц; CSS — язык стилей, а не программирования или разметки.
  • Правило CSS = селектор + объявления «свойство: значение»; объявление с неподходящим значением браузер отбрасывает, остальные работают.
  • При конфликте работает каскад: важность и источник, слои, специфичность, порядок в коде.
  • Текстовые свойства и все пользовательские свойства наследуются, свойства блока — нет; у элементов форм наследование перекрыто стилями браузера.
  • CSS-переменные (--x и var()) подчиняются каскаду; тип значения можно зафиксировать через @property.

Где применяется / связь с практикой

Освойте тему на практике

Каскад, наследование и переменные нужны в любой верстке: на них строятся дизайн-системы, темная тема и компоненты, которые меняют вид одной переменной. Системно пройти HTML, CSS, адаптивную верстку и сборку макета можно на курсе HTML/CSS, а посмотреть формат занятий бесплатно — на открытых уроках Otus.

FAQ

Чем пользовательское свойство отличается от переменной в Sass?
Переменная Sass подставляется при компиляции и в браузер не попадает. Пользовательское свойство живет в браузере: его можно переопределить в классе, в медиазапросе или из JavaScript, и страница сразу перерисуется.

Можно ли использовать !important для CSS-переменной?
Можно: !important влияет на то, какое объявление --x победит в каскаде. В само значение переменной он не попадает, поэтому var(--x) в другом правиле важным не становится.

OTUS Журнал
Скидка 5% 14-20 сентября на курсы (popup)