Надежный, мощный и стабильный CSS-код, который вы можете использовать уже сегодня.
Я считаю, что каждый фронтенд-разработчик должен знать :has() — это больше, чем просто «селектор родительского элемента», как и зачем использовать subgrid , как вкладывать элементы с помощью встроенного синтаксиса CSS, как обеспечить балансировку переноса текста заголовка в браузере и как использовать контейнерные единицы запроса.
Этот пост является продолжением прошлогодней статьи «6 CSS-фрагментов, которые должен знать каждый фронтенд-разработчик в 2023 году» .
CSS:has(.potential-beyond-being-a-parent-selector)
:has()Селектор :has() появился во всех основных браузерах в конце 2023 года! Этот новый селектор кажется небольшим и безобидным, но вы будете удивлены всем возможностям его применения: игры, реактивность, контекстная верстка, интеллектуальные компоненты и многое другое, что подробно рассмотрено в этой статье от Jhey .

Вот пара примеров использования :has() в качестве родительского селектора. Он получил такое название, потому что обычно объект селектора находится в конце, например, ul li , где li является объектом и получает стили. С помощью :has() объектом может стать элемент в начале селектора. В следующем примере кнопка имеет зазор, если внутри находится элемент с классом .icon . Карточка меняет ориентацию, если внутри находится изображение.
button:has(.icon) {
gap: 1ch;
}
.card:has(img) {
grid-auto-flow: row;
}
Давно востребованный селектор позволял изменять макет в зависимости от количества элементов в нем. Теперь это возможно с помощью :has() поскольку он может сохранять контейнер в качестве параметра, одновременно запрашивая количество дочерних элементов.
main:has(> :nth-child(5)) {…}
Ещё один пример более высокого уровня: изменение стилей, заданных для всего документа, при включении определённого флажка на странице:
html:has(#dark-mode:checked) {…}
Это простые примеры использования, которые не меняют суть селектора. Если вы посмотрите только на такие примеры, вы можете подумать :has() ограничивается только селектором родительского элемента. Однако рассмотрите следующие примеры. В них проверяется наличие общего предка, а затем тема селектора изменяется на дочерний элемент, расположенный глубже на странице.
В этом случае отображается сообщение об ошибке формы, если какой-либо из ее элементов ввода недействителен:
form:has(:user-invalid) .error {
display: block;
}
Этот элемент выдвигает основную область контента, когда боковое меню имеет класс .--is-open :
html:has(#sidenav.--is-open) main {
translate: -320px;
}
Вот интересная демонстрация, в которой используется :has() в качестве селектора родительского элемента, :has() с запросами количества и запросами контейнера для создания сетки, способной элегантно отображать от 1 до 12 элементов в портретной или альбомной ориентации:
Создайте подсетку
subgridВ течение многих лет сообщество веб-разработчиков просило добавить Subgrid, чтобы доработать и завершить создание невероятно популярного и мощного механизма компоновки CSS-сеток. Теперь он доступен во всех трех основных движках.
Подробнее о подсетке можно узнать здесь , если вам нужен общий обзор.
body {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(30ch, 1fr));
> article {
display: grid;
grid-row: span 4;
grid-template-rows: subgrid;
}
}
Вложенный способ CSS
nestingВстроенная функция вложенности CSS стала доступна во всех основных браузерах в 2023 году. Я даже обновил свой сайт, удалив процесс сборки, который компилировал вложенность, и теперь выпускаю уменьшенные по размеру таблицы стилей! Да, таблицы стилей с вложенностью стали меньше, и все инструменты разработчика браузера готовы их отображать.
Здесь вы найдете обзор синтаксиса вложенности CSS, а здесь — подробную информацию. Следующий пример кода демонстрирует пример синтаксиса.
.you {
.can-totally-ship-this {
&.if-you-wanted {
/* it's VERY MUCH like SCSS */
&:is(:hover, :focus-visible) {
/* put a bird on it */
}
}
}
}
.for-theming {
@media (prefers-color-scheme: dark) {
/* you can nest media queries */
}
}
/* or for theming with [data-theme="dark"] */
.button {
background: black;
color: white;
/* nest and do more than just append, flip it and reverse it */
[data-theme="dark"] & {
background: white;
color: black;
}
}
Пусть браузер уравновесит заголовки.
balanceprettyБез text-wrap: balance разработчикам и копирайтерам приходится полагаться на подсказки переноса строк, такие как элементы <wbr> или ­ В большинстве случаев это проигрышная ситуация, потому что как только контент будет переведен, увеличен или изменен каким-либо образом, нет никакой гарантии, что эти подсказки переноса строк окажутся в нужном месте для нового представления контента.
При сбалансированном переносе текста эту работу можно оставить браузеру. Сравнение можно увидеть в следующем примере на Codepen.
Используйте единицы запроса контейнера
cqwВ прошлогодней публикации предлагалось, чтобы каждый фронтенд-разработчик умел писать контейнерные запросы. Если вы еще этого не освоили, сделайте 2024 год годом, когда стоит попробовать, и обязательно изучите контейнерные запросы. В качестве обзора, Ахмад Шадид написал отличную статью о контейнерных запросах в 2021 году.
Добавлено шесть новых модулей для обработки запросов к контейнерам :
- Встроенный вариант
cqi. - Вариант ширины
cqw. - Вариант блока
cqb. - Вариант роста
cqh. - Вариант для меньшей длины
cqmin. - Вариант для большей длины
cqmax.
Рассмотрим сценарий с относительной и внутренней анимацией контейнера. Дочерний элемент полностью выдвигается из своего контейнера с помощью 100cqi — это 100% от размера контейнера внутри элемента.
@keyframes slide-out-of-container {
to {
translate: -100cqi;
}
}
Вот карточка с адаптивной типографикой, которая подстраивается под ориентацию контейнера, уменьшаясь вдвое при альбомной ориентации.
.card {
:is(h2,h3) {
font-size: clamp(1.5rem, 5cqi, 4rem);
}
img {
inline-size: 100cqi;
@container (orientation: landscape) {
inline-size: 50cqi;
}
}
}
Если эти модели для вас в новинку, вероятно, стоит ознакомиться со всеми моделями, доступными вам в 2024 году .