고급 CSS 선택자: :has(), :is(), :where() 및 명시도 마스터하기
CSS는 더 이상 단순한 스타일의 집합이 아닙니다. 현대적인 선택자를 사용하면 JavaScript 한 줄 없이도 요소 간에 복잡하고 반응형인 관계를 구축할 수 있는 강력한 로직 엔진이 됩니다.
이 가이드에서는 CSS 선택자의 "초능력"과 이것이 캐스케이드(cascade)에 대한 우리의 사고방식을 어떻게 바꾸고 있는지 살펴보겠습니다.
2. :is()와 :where()로 더 깔끔한 CSS 작성하기
이러한 "로직" 선택자를 사용하면 여러 선택자를 하나로 묶을 수 있어 코드가 훨씬 더 깔끔해지고 가독성이 높아집니다.
:is() 의사 클래스
여러 선택자를 그룹화하며, 인자 중 가장 높은 명시도를 채택합니다.
/* 이전 */
header h1, header h2, header h3 { margin-bottom: 20px; }
/* 이후 */
header :is(h1, h2, h3) { margin-bottom: 20px; }
:where() 의사 클래스
:is()와 유사하지만 명시도가 항상 0입니다. 이는 나중에 쉽게 재정의하려는 기준 스타일(예: "리셋" 또는 "기본" 레이어)에 적합합니다.
3. 고급 :nth-child()를 이용한 정밀한 스타일링
:nth-child() 선택자가 대폭 업그레이드되었습니다. 이제 "of S" 구문을 사용하여 특정 하위 집합 내에서의 위치를 기준으로 요소를 선택할 수 있습니다.
/* 필터링된 목록에서 두 번째로 보이는 항목 선택 */
li:nth-child(2 of .visible) {
background-color: yellow;
}
이는 일부 항목이 display: none으로 숨겨져 있을 수 있는 동적 목록에서 매우 유용합니다.
4. 명시도(Specificity) 마스터하기
CSS에서 가장 큰 고충 중 하나는 "명시도 전쟁"입니다. 다른 선택자가 더 "강하기" 때문에 스타일이 적용되지 않는 상황을 말합니다.
명시도 공식:
- 인라인 스타일: (예:
style="...") - 가장 높은 우선순위. - ID:
#my-element(점수: 1, 0, 0). - 클래스, 속성, 의사 클래스:
.my-class,[type="text"],:hover(점수: 0, 1, 0). - 요소 및 의사 요소:
div,h1,::before(점수: 0, 0, 1).
현대적인 팁: 프로젝트 전체의 명시도를 관리하려면 @layer(캐스케이드 레이어)를 사용하세요.
5. 명시도 시각화
스타일이 왜 적용되지 않는지 확실하지 않다면 명시도 계산기를 사용하는 것이 좋습니다. 이 도구는 선택자를 분석하여 숫자 점수를 부여하므로 충돌을 즉시 식별할 수 있습니다.
고급 선택자 요약
| 선택자 | 최적 용도 | 명시도 | 지원 현황 |
|---|---|---|---|
| :has() | 자식/상태 기반 스타일링 | 일반 | 광범위하게 지원 |
| :is() | 그룹화, 깔끔한 코드 | 인자 중 최고값 | 광범위하게 지원 |
| :where() | 명시도 0인 기본 스타일 | 항상 0 | 광범위하게 지원 |
| :nth-child | 동적 목록 스타일링 | 일반 | 광범위하게 지원 |
결론
현대적인 CSS 선택자는 네이티브 CSS의 성능을 유지하면서 프로그래밍 언어의 "로직"을 제공합니다. **:has()**를 마스터하고 명시도를 이해하면 더욱 견고하고 버그가 적은 UI 관계를 구축할 수 있습니다.
선택자를 테스트해보고 싶으신가요? 당사의 CSS 선택자 테스터를 확인해 보시고 곧 출시될 CSS 명시도 계산기도 기대해 주세요!