CSS에는 하위 요소를 기반으로 상위 요소를 직접 선택하는 방법이 없었습니다. 이는 수년 동안 개발자들이 가장 많이 요청했던 개선사항이었습니다. 이제 모든 주요 브라우저에서 지원되는 :has() 선택자를 사용하면 이 문제를 해결할 수 있습니다. :has() 이전에는 긴 선택자를 연결하거나 스타일 지정 후크를 위한 클래스를 추가해야 했습니다. 이제 하위 요소와의 관계를 기반으로 스타일을 지정할 수 있습니다.
:has():has() 선택자에 관한 자세한 내용은
CSS Wrapped 2023 및
모든 프런트엔드 개발자가 알아야 할 5가지 CSS 스니펫을 참고하세요.
이 선택자는 작아 보이지만 다양한 사용 사례를 지원할 수 있습니다.
이 도움말에서는 전자상거래 회사에서 :has() 선택자를 사용하여 해결한 몇 가지 사용 사례를 보여줍니다.
이 도움말이 포함된 전체 시리즈를 확인하여 이커머스 회사에서 새로운 CSS 및 UI 기능을 사용하여 웹사이트를 개선한 방법을 알아보세요.
Policybazaar
:has()선택자를 사용하면 사용자의 선택에 대한 자바스크립트 기반 유효성 검사 를 삭제하고 CSS 솔루션으로 대체할 수 있었습니다. 이 솔루션은 이전과 동일한 환경에서 원활하게 작동합니다.—Aman Soni, Tech Lead, Policybazaar
Policybazaar의 투자팀은 :has() 선택자를 영리하게 적용하여 요금제를 비교하는 사용자에게 명확한 시각적 표시를 제공했습니다. 다음 이미지는 비교 UI 내에서 두 가지 유형의 요금제 (노란색 및 파란색)를 보여줍니다. 각 요금제는 자체 유형과만 비교할 수 있습니다. :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()를 사용하여 질문 체크박스 상태를 확인하여 질문에 답변했는지 확인합니다. 답변한 경우 애니메이션이 적용되어 다음 질문으로 전환됩니다.
코드
요금제 비교 예시에서는 :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() 사용 전후코드
다음 코드는
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 Wrapped 2023
- :has(): 가족 선택자
- 데모 :has()
- 버그를 신고하거나 새로운 기능을 요청하시겠어요? 여러분의 의견을 듣고 싶습니다!
스크롤 기반 애니메이션, 뷰 전환, 팝오버, 컨테이너 쿼리와 같은 새로운 CSS 및 UI 기능을 사용하여 이커머스 회사가 얻은 이점을 설명하는 이 시리즈의 다른 도움말을 살펴보세요.