Что нового в современном CSS
hard

Что нового в современном CSS

Модно, удобно и красиво

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

Пока эти свойства поддерживаются не всеми браузерами. Прежде чем использовать что-то в своём проекте, проверьте поддержку свойства на сайте Can I Use.

Селектор :has()

Псевдокласс :has() — это одна из самых долгожданных возможностей CSS. 

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

Теперь это можно сделать через псевдокласс :has(). С его помощью мы выбираем какой-то элемент, за которым идёт другой, и стилизуем элемент, расположенный выше.

Допустим, есть страница с длинной статьёй и множеством заголовков. Если после заголовка идёт текст, обёрнутый в тег <p>, то тогда у заголовка не должно быть нижнего отступа.

Что нового в современном CSS

Нам важны только заголовки <h2>, после которых идёт абзац <p>. Другие <h2> мы не трогаем.

Чтобы добиться такой выборочности, мы указываем основной элемент, задаём псевдокласс :has() и в скобках прописываем условие — дополнительный элемент, по которому выбираем основной:

h2:has(+ p) {
margin-bottom: 0;
}

Буквально мы сказали: «Выбери элемент h2, за которым следует p, и примени вот такой стиль».

Что нового в современном CSS

Отступ убрался. 

На странице есть и другой заголовок h2, но за ним идёт заголовок h3. Здесь отступ сохранился, потому что на него новый стиль не распространяется:

Что нового в современном CSS

Псевдокласс :has() помогает стилизовать разные комбинации элементов. Например, он подойдёт для стилизации страниц, созданных при помощи генераторов сайтов. В такой сгенерированный код нельзя добавить классы или идентификаторы — и тогда подобраться к нужному элементу поможет :has().

Полноценная поддержка вложенности без препроцессоров

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

Теперь это можно реализовать в обычном CSS. Например, у родительского элемента .card есть дочерние элементы .title и .content. Мы можем поместить стили дочерних элементов прямо внутрь стилей .card:

.card {
    /* основные стили карточки */
    &:hover,
    &:focus {
        /* стили ховера и состояния фокуса */
    }
    .title {
        /* стили для заголовка внутри карточки */
    }
    .content {
        /* стили для контента внутри карточки */
    }
}

В таком коде легче искать нужный селектор — всё сгруппировано в одном месте.

Также можно размещать внутри родительского элемента и медиазапросы, чтобы не создавать для них отдельный файл и всё было под рукой:

.card {
 /* основные стили карточки */
  &:hover,
 &:focus {
   /* стили ховера и состояния фокуса */
 }

 @media (max-width: 760px) {
   /* стили для медиазапроса*/
 }
}

Собственные каскадные слои

Чтобы понять, какой стиль применить к элементу, браузер использует принцип каскада. Когда специфичность (вес селектора) равна, то используется последнее правило:

.card {
 background-color: rgb(175, 238, 238);
}
.card {
 background-color: rgb(52, 0, 148);
}

В этом коде к карточке будет применён цвет фона rgb(52, 0, 148), поскольку он последний:

Что нового в современном CSS

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

Например:

.card {
 background-color: rgb(175, 238, 238) !important;
}
.card {
 background-color: rgb(52, 0, 148);
}
Что нового в современном CSS

!important — мощное средство, и используют его в крайних случаях. Например, при поддержке легаси-кода, когда править какой-то стиль может быть опасно.

Теперь же порядок каскада можно определить через правило @layer. И разработчик в коде может контролировать приоритет стиля. В этом случае пишем ключевое слово @layer, указываем имена каскадных слоёв, которые хотим определить, и пишем правило в {}.

@layer имя-слоя {правило}

Порядок написания слоёв в заголовке запроса определяет их приоритет. В имя слоя мы оборачиваем нужные стили.

Вот как будет выглядеть пример выше, если мы используем правило @layer

@layer dark, light;

@layer light {
  .card {
    width: 500px;
    height: 150px;
    background-color: paleturquoise;
    text-wrap: balance;
  }
}
@layer dark {
  .card {
    background-color: rgb(148, 59, 0);
  }
}

Что произошло:

  • Мы вызвали правило @layer.
  • Прописали названия слоёв и порядок их следования. Последний слой — приоритетный.
  • Обернули в слои правила для стилей.

В реальной разработке @layer может использоваться при работе с легаси-проектами, когда есть доступ к CSS. Можно оборачивать старые стили в слой legacy, а новые в new и явно задавать порядок приоритета.

Запросы к контейнерам (Container Queries)

Запросы к контейнерам (Container Queries) позволяют компонентам адаптировать компоновку на основе доступного пространства их родительского контейнера.

Это чем-то похоже на медиазапросы, но только не на уровне макета, а на уровне элемента.

Допустим, у нас есть вот такая разметка:

 <div class="container">
   <div class="card">
     <div class="visual">📦</div>
     <div class="meta">
       <h1>Container Queries</h1>
       <p class="desc">Позволяют компонентам адаптировать компоновку на основе доступного
         пространства их родительского контейнера.</p>
     </div>
   </div>
 </div>

В контейнере есть карточка, внутри которой два дочерних блока. 

Мы хотим, чтобы блоки в карточке размещались в две колонки и занимали равную долю доступной ширины блока:

.card {
 display: grid;
 grid-template-columns: 1fr 1fr;
}
Что нового в современном CSS

При изменении ширины экрана, например меньше 400px, макет уже выглядит некрасиво:

Что нового в современном CSS

Чтобы это поправить, делаем контейнерный запрос, где указываем, что при ширине менее 400px колонки в карточке должна быть одна колонка на всю доступную ширину:

@container (max-width: 400px) {
 .card {
   grid-template-columns: 1fr;
 }
}
Что нового в современном CSS

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

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

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

По умолчанию длинный заголовок в браузере переносится как есть — сколько поместилось на строке, столько и поместилось, остальное переходит на новую строку. Из-за этого часто получаются одиноко повисшие слова, которые профессиональные верстальщики назвали бы «сиротой»:

Что нового в современном CSS

Равномерно распределить слова из заголовка по контейнеру поможет свойство text-wrap:balance. Оно даёт браузеру указание распределить текст внутри контейнера, избегая неравномерных промежутков между строками и добиваясь более сбалансированного внешнего вида.

Добавляем свойство text-wrap:balance и смотрим на результат:

Что нового в современном CSS

Но text-wrap:balance работает только при объёме до 6 строк текста. Он хорошо подходит для заголовков, модальных окон, узких столбцов и подсказок, но не подойдёт для основного контента. Ещё это свойство не отменяет и использование неразрывных пробелов и дефисов в вёрстке. 

color-mix

color-mix() — это интересная функция, которая смешивает два цвета в указанном цветовом пространстве (sRGB, XYZ или OKLCH). Тут можно указать процент смешивания и этим добиться тонких цветовых сочетаний и градиентов. До появления color-mix() для этих целей использовали препроцессоры и функцию calc(), теперь можно обойтись без этого.

Создадим блок .card, и зададим ему размер и цвет:

.card {
 width: 300px;
 height: 150px;
 background-color: color-mix(in srgb, rgb(255, 0, 0), rgb(0, 0, 255));
}

Что произошло: 

  • В свойстве background-color мы вызвали функцию color-mix.
  • Обозначили нужное цветовое пространство: in srgb.
  • Прописали первый цвет rgb(255, 0, 0).
  • Указали второй цвет rgb(0, 0, 255).

Мы выбрали синий и красный цвета. Если их смешать, то должен получиться фиолетовый. Проверяем:

Что нового в современном CSS

По умолчанию браузер смешивает цвета в равной пропорции. Если нужно добиться определённого оттенка и выбрать доминирующий цвет, тогда после цвета указываем нужный процент смешивания. Например:

color-mix(in srgb, rgb(255, 0, 0) 25%, rgb(0, 0, 255));

Здесь мы сообщаем, что красного цвета должно быть только 25%.

Что нового в современном CSS

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

Что дальше

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

Текст:

Кристина Тульцева

Редактор:

Михаил Полянин

Обложка:

Алексей Сухов

Корректор:

Ирина Михеева

Вёрстка:

Мария Дронова

Соцсети:

Юлия Зубарева

Фронтенд-разработка — востребованная профессия
На новом курсе «Практикума» о фронтенде вас обучат самым востребованным технологиям: JS и TypeScript, Flexbox и Grid, React, Git, Bash и др. Это то, что нужно работодателям сегодня. Старт — бесплатно.
Попробовать бесплатно
Фронтенд-разработка — востребованная профессия Фронтенд-разработка — востребованная профессия Фронтенд-разработка — востребованная профессия Фронтенд-разработка — востребованная профессия
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
hard