css selectors has-selector is-selector web-development

현대 CSS 선택자의 위력: :has, :is 그리고 :where

차세대 CSS 선택자를 마스터하세요. :has()가 부모 선택자로 작동하는 방식과 :is(), :where()가 스타일시트를 어떻게 단순화하는지 알아봅니다.

2026-04-18

현대 CSS 선택자의 위력: :has, :is 그리고 :where

수년 동안 CSS 개발자들은 "부모 선택자", 즉 자식 요소에 따라 요소의 스타일을 지정하는 방법을 꿈꿔왔습니다. 또한 스타일시트를 비대하게 만드는 길고 반복적인 선택자 목록 때문에 어려움을 겪어왔습니다.

현대 CSS는 마침내 이러한 꿈을 실현했습니다. :has(), :is(), 그리고 :where()의 등장으로 우리가 선택자를 작성하는 방식이 근본적으로 바뀌었습니다.


1. :has(): 게임 체인저 "부모 선택자"

:has() 가상 클래스는 의심할 여지 없이 지난 10년 동안 CSS에 추가된 가장 강력한 기능입니다. 특정 자식 요소를 포함하고 있거나 특정 형제 요소가 뒤따르는지에 따라 해당 요소를 선택할 수 있게 해줍니다.

"부모"로서의 활용 사례

/* 이미지를 포함하고 있는 카드에만 스타일 적용 */
.card:has(img) {
  display: flex;
  flex-direction: column;
}

/* "추천" 태그가 있는 카드에만 스타일 적용 */
.card:has(.featured-badge) {
  border: 2px solid gold;
}

"조건부" 활용 사례

입력 요소의 상태에 따라 라벨의 스타일을 지정할 수도 있습니다:

/* 내부의 체크박스가 체크된 경우 라벨 스타일 지정 */
.form-group:has(input:checked) label {
  color: green;
  font-weight: bold;
}

2. :is(): 복잡한 선택자 단순화

이런 코드를 작성해 본 적이 있나요?

header h1, header h2, header h3, footer h1, footer h2, footer h3 {
  color: blue;
}

:is() 가상 클래스를 사용하면 선택자를 그룹화하고 반복을 줄일 수 있습니다:

:is(header, footer) :is(h1, h2, h3) {
  color: blue;
}

핵심 기능: 관용성(Forgiveness)

기존의 선택자 목록과 달리 :is()관용적입니다. 목록 중 하나의 선택자가 유효하지 않더라도 브라우저는 이를 무시하고 나머지 유효한 선택자들에 스타일을 계속 적용합니다.


3. :where(): 제로 명시도의 힘

:where() 선택자는 :is()와 똑같이 작동하지만 한 가지 결정적인 차이점이 있습니다. 바로 명시도(우선순위)가 항상 0이라는 점입니다.

명시도가 중요한 이유

CSS에서는 명시도가 가장 높은 선택자가 승리합니다. 이로 인해 스타일을 덮어쓰기 위해 !important나 긴 선택자 체인을 사용하는 "명시도 전쟁"이 자주 발생합니다.

/* 명시도에 영향을 주지 않음 */
:where(.content) p {
  color: gray;
}

/* 단순한 클래스 선택자로 쉽게 덮어쓸 수 있음 */
.special-p {
  color: red; /* :where()가 가중치를 더하지 않았으므로 승리 */
}

:where()는 사용자가 스타일을 쉽게 덮어쓸 수 있도록 기본 스타일을 제공하려는 **CSS 리셋(Resets)**이나 라이브러리 제작자에게 최적입니다.


4. 고급 :nth-childof S

:nth-child(even)은 잘 알고 계시겠지만, 이제 of 키워드를 사용하여 선택 대상을 필터링할 수 있다는 사실을 알고 계셨나요?

/* .visible 클래스를 가진 요소들 중에서 2번째 항목 선택 */
li:nth-child(2 of .visible) {
  background: yellow;
}

이는 일부 항목이 display: none으로 숨겨져 있을 수 있는 동적 목록에서 매우 유용합니다.


5. 명시도 계산기: 수학적 원리 이해하기

CSS 명시도는 세 개의 열을 사용하여 계산됩니다: (A, B, C).

  • A: ID 선택자
  • B: 클래스 선택자, 속성 선택자, 가상 클래스
  • C: 요소 선택자, 가상 요소

새로운 선택자들이 미치는 영향:

  • :is():has(): 인자 목록 중 가장 높은 명시도를 가진 선택자의 명시도를 따릅니다.
  • :where(): 명시도가 항상 **(0, 0, 0)**입니다.

FAQ: 자주 묻는 질문

Q: :has()는 모든 브라우저에서 지원되나요?

A: 네! 2023년 말 기준으로 :has()는 Chrome, Safari, Firefox, Edge의 최신 버전에서 지원됩니다. 최신 웹 프로젝트에서 안심하고 사용할 수 있습니다.

Q: :is():where() 중 언제 무엇을 사용해야 하나요?

A: 그룹화된 선택자들이 정상적인 명시도를 유지하길 원한다면 :is()를 사용하세요. 기본 스타일이나 리셋처럼 스타일을 매우 쉽게 덮어쓸 수 있게 만들고 싶다면 :where()를 사용하세요.

Q: :has()가 성능에 영향을 주나요?

A: 브라우저 제조사들이 :has()를 상당히 최적화했습니다. 한 페이지에서 수백 번 사용하면 약간의 영향이 있을 수 있지만, 대부분의 UI 패턴에서는 매우 빠르고 효율적입니다.


더 깨끗하고 선언적인 CSS 작성하기

이러한 선택자들을 마스터하면 HTML에서 "유틸리티 클래스"의 수를 크게 줄이고 로직을 원래 있어야 할 곳인 CSS 스타일시트로 옮길 수 있습니다.

선택자의 가중치가 궁금하신가요? 당사의 CSS 선택자 명시도 계산기(출시 예정)에서 CSS의 수학적 원리를 마스터해 보세요.