2022-й год обещает быть отличным годом для CSS, т.к. на горизонте появляется множество новых свойств. Некоторые из них уже поддерживаются современными браузерами, другие, вероятней всего, вскоре получат широкую поддержку браузерами, и лишь для некоторых этот процесс займет немного больше времени. Давайте же рассмотрим их.

Контейнерные запросы

Контейнерные запросы позволяют нам стилизовать элемент в зависимости от размера его родителя, что существенно отличает их от медиа-запросов, которые позволяют менять стили в зависимости от области экрана. Сама проблема адаптивного дизайна существует давно, так как зачастую нам необходимо, чтобы компонент адаптировался именно относительно своего контекста.

Как использовать контейнерные запросы

Для контейнерного запроса нам нужно указать элемент в качестве нашего контейнера, используя свойство container. В качестве значения container-type может быть width, height, inline-size, block-size.

main {
  container: inline-size;
}

Затем мы можем использовать правило @container аналогично медиа-запросу. Однако обратите внимание на способ выражения правила (inline-size > 30em, а не min-width: 30em). Эта запись означает - когда контейнер шире 30em, мы изменим размер шрифта для указанного элемента:

@container (inline-size > 30em) {
  .box {
    font-size: 24px;
  }
}

Спецификация CSS Containment Level 3 в настоящее время находится в стадии разработки, что означает, что синтаксис может измениться в любой момент.

Можем ли мы сейчас использовать контейнерные запросы в своих проектах? Нет. Однако за этим новшеством стоит огромная поддержка, так что нам стоит немного подождать.

Псевдокласс :has()

Этот псевдокласс позволяет нам выбирать элемент в зависимости от его дочерних элементов и у него есть несколько довольно интересных вариантов использования. Например, мы могли бы по-разному стилизовать изображение в <figure> в зависимости от того, есть ли внутри <figcaption> или нет:

figure:has(figcaption) {
  background: lightgray;
}

А чтобы застилить картинку для случая, если у ее родителя есть h2, нужно прописать:

section:has(h2) img {
  border: 1px solid gray;
}

Поиграться с данным свойством на данный момент можно только в последних версиях Safari.

Условное выражение @when/@else

Данное правило предназначено для условий в CSS, аналогичное операторам if/else в других языках программирования. Оно помогает создавать сложные медиа-запросы с более правильной логикой. @when был выбран вместо @if, чтобы избежать конфликта с Sass. Например:

@when media(min-width: 1025px) and supports(display: subgrid) {
  /* Стили при ширине экрана более 1025px и при поддержке свойства subgrid */
} @else {
  /* Стили при несоответствии указанному условию */
}

Свойство еще не поддерживается браузерами и на стадии обсуждения. Однако, на него однозначно стоит обратить внимание.

Свойство accent-color

Свойство позволяет быстро и легко обозначить цвета нашего бренда для полей ввода данных в формах. Вспомните о всех тех чекбоксах, радио-кнопках и прочих элементах, которые сложно стилизовать, да и все браузеры отображают их по-разному. В качестве выхода обычно скрывали дефолтное поле и создавали новое кастомное с помощью псевдоэлементов. Свойство accent-color позволяет нам сохранить вид элементов форм браузера по умолчанию, но применить к ним цвет, соответствующий цветовой гамме нашего сайта.

Поскольку свойство наследуемое, его можно применить на корневом уровне:

:root {
  accent-color: chocolate;
}

Также можно применить его индивидуально к элементу:

.submit-form {
  accent-color: purple;
}
input[type="checkbox"] {
  accent-color: #6ad3ff;
}
Поддержка браузерами
chrome
Chrome
93
firefox
Firefox
92
internet explorer
IE
 
edge
Edge
93
safari
Safari
15.4
opera
Opera
79

Браузеры, не поддерживающие свойство, будут применять дефолтные стили.

Новые функции CSS для цвета

Наверняка вы знакомы с такими цветовыми форматами, как HEX, RGB и HSL. Последние уровни модуля CSS Color Module включают в себя целый ряд новых функций, которые позволяют задавать и управлять цветами в CSS с более широкими возможностями. Среди них:

  • hwb(): Hue - оттенок, Whiteness - белизна, Blackness - чернота
  • lab(): Lightness - яркость вместе со значениями a и b, которые определяют оттенок
  • lch(): Lightness - яркость, Chroma - цветность, Hue - оттенок
  • color-mix(): смешивает два цвета вместе
  • color-contrast(): из списка цветов выбирает тот, у которого самый высокий контраст по сравнению с первым
  • color(): указывает цвет в другом цветовом пространстве (например, display-p3)
  • синтаксис относительного цвета, который позволяет нам взять цвет и преобразовать так, чтобы получить другой

hwb(), lab() и lch() используются почти так же, как привычные нам функции rgb() и hsl(), с необязательным параметром alpha-канала:

.box {
  background-color: lch(80% 100 50);  // непрозрачный цвет
}
.box {
  background-color: lch(80% 100 50 / 0.5);  // полупрозрачный цвет
}

color-mix() выводит цвет в результате смешивания двух других. В качестве первого аргумента указывается метод интерполяции:

.box {
  background-color: color-mix(in lch, blue, yellow);
}

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

/* Отобразит цвет с высшей контрастностью */
.box {
  color: white;
  background-color: color-contrast(white vs, cyan, lightskyblue, blue);
}

/* Отобразит первый цвет с коэффициентом контрастности AA */
.box {
  color: white;
  background-color: color-contrast(white vs, cyan, lightskyblue, blue to AA);
}

Это новшество отлично подходит для цветовых схем. Например, мы можем позволить нашему CSS выбирать, черный или белый текст является наиболее подходящим (т.е. обеспечивает наибольшую контрастность) для кнопки с заданным цветом фона.

Поддержка браузерами данных возможностей предельно слабая. Это либо последние версии Safari, либо Firefox. Однако это не мешает вам уже использовать эти свойства в стилях наряду с поддерживаемыми. Если браузер еще не сможет прочитать новое свойство, он просто использует то, которое знает:

.box {
  background-color: rgb(80% 0% 75%);
  background-color: lch(50% 100 300);
}

Каскадные слои

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

Принцип работы аналогичен работе z-индекса: необходимо будет создавать отдельные слои в соответствии с методологией ITCSS.

/* Создаем слои в нужном порядке */
@layer reset, base, theme;

/* Прописываем CSS для каждого слоя */
@layer reset {
  /* Стили для слоя 'reset' */
}

@layer base {
  /* Стили для слоя 'base' */
  h1.title {
    font-size: 5rem;
  }
}

@layer theme {
  /* Стили для слоя 'theme' */
  h1 {
    font-size: 3rem;
  }
}

Таким образом, размера шрифта для h1 в слое 'theme' будет применен с более высоким приоритетом, чем в слое 'base', несмотря на то, что в 'base' селектор имеет больший вес.

Поддержка браузерами
chrome
Chrome
99
firefox
Firefox
97
internet explorer
IE
 
edge
Edge
99
safari
Safari
15.4
opera
Opera
86

Сабгриды

Сабгриды позволяют элементу наследовать сетку своего родителя либо на оси рядов, либо столбцов. Для этого используйте ключевое слово subgrid для свойства grid-template-columns или grid-template-rows вложенного элемента, которому нужно задать наследование родительской сетки:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, auto);
}
.grid > figure {
  display: grid;
  grid-template-rows: subgrid;
}
.grid figcaption {
  grid-row: 2;
}

Примечательно, что сабгриды поддерживаются в Firefox с 2019 года, но ни один другой браузер пока не последовал этому примеру почти три года спустя. Есть признаки того, что команда Chromium наконец-то приступила к его реализации, так что нам, возможно, посчастливится увидеть его в Chrome и Edge в этом году.

Прокрутка с хронологией (timeline)

Наверняка вы видели много классных веб-сайтов, на которых реализована причудливая анимация, связанная с прокруткой страницы. Существует множество библиотек JS, которые помогают реализовывать такие вещи. Скоро это возможно будет сделать средствами CSS с помощью свойства @scroll-timeline.

Для этого нам понадобятся:

  • keyframe-анимации
  • само правило @scroll-timeline
  • свойство animation-timeline, которое можно включить в сокращенном свойстве animation
/* Задаем keyframe-анимацию */
@keyframes slide {
  to { transform: translateX(50%); }
}

/* Настраиваем timeline и задаем имя свойству, напр. 'slide-timeline' */
@scroll-timeline slide-timeline {
  source: auto;  /* прокручиваемый элемент, который запускает подвязанную анимацию (по-умолчанию - document) */
  orientation: vertical;  /* ориентация скролла (по-умолчанию - вертикальная) */
  scroll-offsets: 0%, 100%;  /* массив интервалов прогресса скролла, в которых активируется timeline */
}

/* Указываем анимацию и timeline */
.animated-element {
  animation: 1s ease forwards slide slide-timeline;
}

Мы также можем запускать timeline, когда при прокрутке страницы в поле зрения находится конкретный элемент:

@scroll-timeline slide-timeline {
  scroll-offsets: selector(#element) end 0, selector(#element) start 1;
}

Вероятно, для сложных анимаций все-таки потребуется обратиться к библиотеке JS, но для относительно простых случаев данное свойство сэкономит на подключении лишних скриптов.

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

Вложенность

Если вы знакомы с Sass, вы знаете об удобстве возможности вкладывать селекторы - то есть, писать дочернее правило внутри родительского. Вложенность помогает нам поддерживать порядок в нашем коде, хотя чрезмерное его использование иногда может быть лишним. Среди новых возможностей CSS - нативная вложенность.

Синтаксически она похожа на Sass. В примере вложенное правило задано для заголовка h2 внутри элемента .box:

.box {
  color: red;
  & h2 {
    color: blue;
  }
}

Подобным образом данный синтаксис можно использовать для псевдоселекторов:

.button {
  color: red;
  &:hover,
  &:focus {
    color: blue;
  }
}

Эквивалентом данной записи в сегодняшнем CSS будет:

.button {
  color: red;
}
.button:hover,
.button:focus {
  color: blue;
}

К сожалению, поддержки у свойства пока нет ни в одном браузере. Но если вы используете PostCSS, со свойством можно поэкспериментировать, подключив плагин postcss-preset-env.