:has() 우수사례

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

CSS에는 하위 요소를 기반으로 상위 요소를 직접 선택할 수 있는 방법이 없었습니다. 이는 수년 동안 개발자들이 가장 많이 요청했던 사항입니다. 이제 모든 주요 브라우저에서 지원되는 :has() 선택기가 이 문제를 해결합니다. :has() 전에는 긴 선택기를 체이닝하거나 후크 스타일 지정 클래스를 추가하는 경우가 많습니다. 이제 요소와 하위 요소의 관계를 기반으로 스타일을 지정할 수 있습니다. CSS 래핑 2023:has() 선택기와 모든 프런트엔드 개발자가 알아야 할 5개의 CSS 스니펫에 대해 자세히 알아보세요.

이 선택기는 작아 보일 수 있지만 수많은 사용 사례를 지원할 수 있습니다. 이 도움말에서는 전자상거래 회사에서 :has() 선택기를 사용하여 발견한 몇 가지 사용 사례를 보여줍니다.

:has()Baseline Newly Available의 일부입니다.

브라우저 지원

  • 105
  • 105
  • 121
  • 15.4

소스

이 문서가 포함된 전체 시리즈를 확인하세요. 전자상거래 회사가 새로운 CSS 및 UI 기능을 사용하여 웹사이트를 어떻게 개선했는지 설명합니다.

정책바자(Policybazaar)

:has() 선택기를 사용하여 자바스크립트 기반 사용자 선택 검증 과정을 없애고 이전과 동일한 환경에서 원활하게 작동하는 CSS 솔루션으로 대체할 수 있었습니다.—아만 소니, Policybazaar 기술 책임자

Policybazaar의 투자팀은 요금제를 비교하는 사용자에게 :has() 선택기를 영리하게 적용했습니다. 다음 이미지는 비교 UI 내에 두 가지 유형의 계획 (노란색 및 파란색)을 보여줍니다. 각 계획은 자체 유형과만 비교할 수 있습니다. :has()를 사용하면 사용자가 요금제의 한 유형을 선택할 때 다른 요금제 유형을 선택할 수 없습니다.

:has()를 구현하여 상위 요소와 그 하위 요소의 스타일을 지정하여 카테고리 한정 선택 기능을 만듭니다.

코드

:has()를 사용하면 스타일 상위 요소와 그 하위 요소에 액세스할 수 있습니다. 다음 코드는 상위 컨테이너에 .disabled-group 클래스가 설정되어 있는지 확인합니다. 포함하는 경우 카드가 비활성화되고 pointer-eventsnone로 설정하여 '추가' 버튼이 클릭에 반응하지 않습니다.

.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의 health팀은 약간 다른 사용 사례를 구현했습니다. 사용자를 위한 인라인 퀴즈가 있고 :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;
 }
}

Tokopedia

Tokopedia는 제품 썸네일에 동영상이 포함된 경우 :has()를 사용하여 오버레이 이미지를 만들었습니다. 제품 썸네일에 .playIcon 클래스가 포함되어 있으면 CSS 오버레이가 추가됩니다. 여기서 :has() 선택기는 모든 썸네일에 적용되는 전반적인 .thumbnailWrapper 클래스 내의 & 중첩 선택기와 함께 사용됩니다. 이렇게 하면 모듈화가 되어 있고 읽기 쉬운 CSS가 만들어집니다.

has 선택기 사용 전과 후의 Tokopedia 페이지 스크린샷
: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 및 UI 기능을 사용하여 어떤 이점을 얻었는지 알아보세요.