:has() тематические исследования

Света Гопалакришнан
Swetha Gopalakrishnan
Саураб Раджпал
Saurabh Rajpal

В CSS, как известно, отсутствует способ прямого выбора родительского элемента на основе его дочерних элементов. Это был главный запрос разработчиков на протяжении многих лет. Эту проблему решает селектор :has() , который теперь поддерживается всеми основными браузерами. До :has() вам часто приходилось связывать длинные селекторы или добавлять классы для хуков стилизации. Теперь вы можете создавать стили на основе отношений элемента с его потомками. Узнайте больше о селекторе :has() в CSS Wrapped 2023 и 5 фрагментах CSS, которые должен знать каждый фронтенд-разработчик .

Хотя этот селектор кажется небольшим, он может обеспечить огромное количество вариантов использования. В этой статье показаны некоторые варианты использования, которые компании электронной коммерции разблокировали с помощью селектора :has() .

:has() является частью Baseline Newly Available .

Поддержка браузера

  • Хром: 105.
  • Край: 105.
  • Фаерфокс: 121.
  • Сафари: 15.4.

Источник

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

Политический базар

С помощью селектора :has() мы смогли исключить проверку выбора пользователя на основе JavaScript и заменить ее решением CSS, которое работает для нас без проблем с тем же опытом, что и раньше. — Аман Сони , технический руководитель, Policybazaar

Инвестиционная команда Policybazaar умело применила селектор :has() чтобы обеспечить четкую визуальную индикацию для пользователей, сравнивающих планы. На следующем изображении показаны два типа планов в пользовательском интерфейсе сравнения (желтый и синий). Каждый план можно сравнивать только со своим типом. Используя :has() , когда пользователь выбирает один тип плана, другой тип плана не может быть выбран.

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

Код

:has() дает вам доступ к родительским элементам стиля и их дочерним элементам. Следующий код проверяет, имеет ли родительский контейнер набор классов .disabled-group . Если это так, карточка становится серой, а кнопка «Добавить» не может реагировать на щелчки, установив для pointer-events none .

.plan-group-container:has(.disabled-group) {
  opacity: 0.5;
  filter: grayscale(100%);
}

.plan-group-container:has(.disabled-section) .button {
  pointer-events: none;
  border-color: #B5B5B5;
  color: var(--text-primary-38-color);
  background: var(--input-border-color);
}

Команда здравоохранения в Policybazaar реализовала немного другой вариант использования. У них есть встроенный тест для пользователя и используется :has() для проверки статуса флажка вопроса, чтобы узнать, был ли на вопрос дан ответ. Если да, применяется анимация перехода к следующему вопросу.

health.policybazaar.com/

Код

В примере сравнения планов :has() использовался для проверки наличия класса. Вы также можете проверить состояние элемента ввода, такого как флажок, используя :has(input:checked) . На визуальном изображении, показывающем тест, каждый вопрос в фиолетовом баннере представляет собой флажок. Policybazaar проверяет, был ли дан ответ на вопрос, используя :has(input:checked) , и если да, запускает анимацию с помощью animation: quesSlideOut 0.3s 0.3s linear forwards для перехода к следующему вопросу. Посмотрите, как это работает, в следующем коде.

.segment_banner__wrap__questions {
 position: relative;
 animation: quesSlideIn 0.3s linear forwards;
}

.segment_banner__wrap__questions:has(input:checked) {
 animation: quesSlideOut 0.3s 0.3s linear forwards;
}


@keyframes quesSlideIn {
 from {
   transform: translateX(50px);
   opacity: 0;
 }
 to {
   transform: translateX(0px);
   opacity: 1;
 }
}

@keyframes quesSlideOut {
 from {
   transform: translateX(0px);
   opacity: 1;
 }
 to {
   transform: translateX(-50px);
   opacity: 0;
 }
}

Токопедия

Токопедия использовала :has() для создания наложенного изображения, если миниатюра продукта содержит видео. Если миниатюра продукта содержит класс .playIcon , добавляется наложение CSS. Здесь селектор :has() используется вместе с селектором & вложенности в общем классе .thumbnailWrapper , который применяется ко всем миниатюрам. Это создает более модульный и читаемый CSS.

Скриншот страницы Токопедии до и после использования селектора has.
До и после использования :has() .

Код

Следующий код использует селекторы и комбинаторы CSS ( & и > ) и вложение с :has() для стилизации миниатюры. Для неподдерживающих браузеров в качестве запасного варианта используется обычное правило дополнительного класса CSS. Правило @supports selector(:has(*)) также используется для проверки поддержки браузера. Таким образом, общий опыт работы во всех версиях браузера одинаков.

export const thumbnailWrapper = css`
  padding: 0;
  margin-right: 7px;
  border: none;
  outline: none;
  background: transparent;

  > div {
    width: 64px;
    height: 64px;
    overflow: hidden;
    cursor: pointer;
    border-color: ;
    position: relative;
    border: 2px solid ${NN0};
    border-radius: 8px;
    transition: border-color 0.25s;

    &.active {
      border-color: ${GN500};
    }

    @supports selector(:has(*)) {
      &:has(.playIcon) {
        &::after {
          content: '';
          display: block;
          background: rgba(0, 0, 0, 0.2);
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
        }
      }
    }

    & > .playIcon {
      position: absolute;
      top: 25%;
      left: 25%;
      width: 50%;
      height: 50%;
      text-align: center;
      z-index: 1;
    }
  }
`;

Что следует учитывать при использовании :has()

Объедините :has() с другими селекторами, чтобы создать более сложное условие. Посмотрите несколько примеров в селекторе семейства has() .

Ресурсы:

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