Эта статья — перевод оригинальной статьи Ahmad Shadeed "CSS Parent Selector" Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов. Вы когда-нибудь задумывались о селекторе CSS, где вы проверяете, существует ли конкретный элемент внутри родителя? Например, если у компонента карточки есть миниатюра, нам нужно добавить к нему display: flex. Это было невозможно в CSS, но теперь у нас будет новый селектор CSS :has, который поможет нам выбрать родителя определенного элемента и многое другое. В этой статье я объясню проблему, которую решает :has, как он работает, где и как мы можем его использовать с некоторыми вариантами использования и примерами, и, самое главное, как мы можем использовать его уже сегодня. Возможность стилизовать родительский элемент отсутствует. Мы должны создавать классы CSS и переключать их в зависимости от того, что нам нужно. Рассмотрим следующий базовый пример. У нас есть компонент карточки в двух вариациях: 1) С изображением 2) Без изображения. В CSS мы могли бы сделать что-то вроде этого: Как вы видели выше, мы создали класс специально для карточки без изображения, поскольку нам не нужен display: flex на родительском элементе. Вопрос в том, можем ли мы это сделать в CSS, без второго класса? Ну, вот где CSS :has приходит на помощь. Это может помочь нам проверить, есть ли у элемента .card изображение .card__image или нет. Например, мы можем проверить, есть ли у карточки изображение, и если да, то нам нужно применить flexbox. Согласно спецификации CSS, селектор :has проверяет, содержит ли родитель хотя бы один конкретный элемент или выполняется ли условие, например, если инпут сфокусирован. Вернемся к предыдущему фрагменту кода. Мы проверяем, содержит ли родительский элемент .card дочерний элемент .card__image. Рассмотрим следующий рисунок: Проще говоря, приведенный выше CSS эквивалентен следующему: "Есть ли в карточке элемент .card__image?" Разве это не восхитительно? В CSS есть логика! Речь идет не только о проверке того, содержит ли родитель дочерний элемент, но мы также можем проверить, следует ли за элементом, например, <p>. Рассмотрим следующее: Это проверяет, следует ли <h2>  непосредственно за <p>. Или мы можем использовать его с элементом формы, например, чтобы проверить, есть ли сфокусированный инпут.  На момент написания статьи CSS :has работал в Safari 15.4 и в Chrome Canary. Следите за поддержкой на Can I use. Да, можем! Хватит теории, давайте перейдем к примерам использования! Когда я работаю над заголовком раздела, у меня в основном будет два варианта: один только с заголовком, а другой содержит и заголовок, и якорную ссылку. В зависимости от того, есть ли ссылка или нет, я хочу оформить его по-разному. Обратите внимание, что я использовал :has(> a), который выберет только прямую дочернюю ссылку. Демо Вернемся немного назад к примеру с исходной картой. У нас есть два варианта, один с изображением, а другой без него. Мы даже можем проверить, нет ли на .card изображения, и применить определенные стили. В нашем случае это border-top. Без :has нам пришлось бы иметь два класса, чтобы сделать это. Демо В этом примере у нас есть два варианта набора действий у каждой карточки: одна карточка с одним элементом (ссылка), а другая с несколькими действиями (сохранить, поделиться и т. д.). Когда действия карточки имеют две разные обёртки для действий, мы хотим активировать display: flex следующим образом (пожалуйста, не обращайте внимания на приведенную ниже разметку, она предназначена исключительно для демонстрационных целей!). Вот что нам придётся делать без :has. Демо Вам когда-нибудь приходилось сбрасывать border-radius для компонента в зависимости от того, есть ли изображение или нет? Это идеальное использование CSS :has. Рассмотрим следующий рисунок. Когда изображение удалено, border-radius верхнего левого и правого углов равен нулю, что выглядит странно. Намного лучше! Вот что нам придётся написать без использования :has. Демо В этом примере у нас есть компонент с несколькими параметрами. Когда ни один из них не отмечен, кнопки сброса нет. Однако, когда хотя бы один отмечен, нам нужно показать кнопку сброса. Мы можем легко сделать это с помощью CSS :has. Мы вообще не можем сделать это в CSS без :has. Это один из сценариев, когда мы откажемся от Javascript, если :has будет поддерживаться в современных браузерах. Демо Возможно, нам потребуется показать конкретное поле формы на основе предыдущего ответа или выбора. В этом примере нам нужно показать поле «other», если пользователь выбрал «other» в меню выбора. С помощью CSS :has мы можем проверить, выбрано ли в меню значение "other", и показать поле «other» на основе этого. Разве это не восхитительно? Нам не нужно беспокоиться об исходном порядке HTML, если поле выбора и формы находится внутри родительского элемента .box. Демо В этом примере у нас есть элемент навигации с подменю, которое появляется при наведении или фокусе. Что мы хотим сделать, так это скрыть стрелку в зависимости от того, есть ли меню или нет. Мы можем легко сделать это с помощью CSS :has. Идея состоит в том, чтобы проверить, содержится ли <li> в <ul> Без CSS :has у нас, вероятно, будет класс для <li> с подменю. Что-то вроде следующего: Демо При создании компонента заголовка мы можем быть уверены в том, хотим ли мы, чтобы заголовок занимал всю ширину страницы или был в обёртке. В любом случае нам нужно применить flexbox для распределения элементов заголовка определенным образом. Если .wrapper есть, мы применим к нему стили. Если нет, то применим их непосредственно к элементу .site-header. Демо На некоторых панелях мониторинга может быть важное предупреждение, о котором должен знать пользователь. В этом случае оповещения на странице может быть недостаточно. В таком случае мы могли бы, например, добавить красную рамку и приглушенный красный цвет фона к элементу заголовка. Это повысит вероятность того, что пользователь быстро заметит предупреждение. С помощью CSS :has мы можем проверить, есть ли предупреждение в элементе .main, и если да, мы можем добавить следующие стили в заголовок. Демо Мы можем использовать CSS :has для изменения цветовой схемы веб-сайта. Например, если у нас есть несколько тем, созданных с помощью переменных CSS, мы можем изменить их через <select> И когда мы выбираем другой вариант из списка, вот что происходит в CSS. В зависимости от выбранной опции переменные CSS будут изменены. Демо В некоторых случаях у нас нет никакого контроля над HTML. Например, в теле статьи. Система управления контентом (CMS) может генерировать элементы неожиданным образом, или автор может встроить видео или что-то в этом роде. Предположим, что мы хотим выбрать тот <h3>, за которым не следует абзац, и увеличить интервал под ним.  Или вам нужно выбрать <iframe>, за которым следует <h3> и что-то сделать. Такие ситуации не могут быть обработаны без CSS :has! В этом примере у нас есть стиль кнопки по умолчанию. Когда у нас есть иконка, мы хотим использовать flexbox для центрирования и выравнивания содержимого кнопки. Демо В дизайн-системе нам часто требуется группа кнопок. Если у нас есть более двух кнопок, последняя должна отображаться на дальней противоположной стороне. Для этого мы можем использовать количественные запросы. Следующий CSS проверит, равно ли количество кнопок трём или больше, и если да, последний элемент будет сдвинут вправо с помощью margin-left: auto. Демо Я получил этот пример из дизайна pinterest. Когда инпут имеет ошибку, мы хотим, чтобы заголовок изменился и указывал на это. С сеткой CSS мы можем использовать функцию minmax() для создания отзывчивых элементов сетки с автоматическим размером. Однако этого может быть недостаточно. Мы также хотим изменить сетку в зависимости от количества элементов. Рассмотрим следующий рисунок. Когда у нас будет 5 элементов, последний будет перенесен в новую строку. Мы можем преодолеть это, проверив, содержит ли .wrapper 5 или более элементов. Опять же, здесь используется концепция количественных запросов. В этом примере у нас есть HTML <figure>. Если есть <figcaption> стиль должен немного отличаться: Добавляем белый фон Немного паддингов Уменьшаем border-radius картинки Мне не терпится увидеть, что вы создадите с помощью CSS :has. Сценарии использования в этой статье — лишь малая часть! Я уверен, что мы обнаружим много полезных применений по пути. Как говорится, самое подходящее время для изучения CSS. Я очень, очень взволнован тем, что будет дальше. Большое спасибо за чтение!