이 기능들은 cascade와 specificity에 대한 명시적 제어를 제공합니다 — 큰 코드베이스의 specificity 전쟁 문제를 정면으로 공략합니다.
@layer — 명시적 cascade 순서 지정
@layer는 당신이 순서를 제어하는 이름 붙은 레이어를 정의하게 합니다. 나중 레이어의 스타일이 specificity와 무관하게 이전 레이어를 이깁니다.
@layer reset, base, components, utilities; /* 순서 선언: 나중 = 높은 우선순위 */
@layer base {
a { color: blue; } /* 이것이 정의되었음에도... */
}
@layer components {
.link { color: green; } /* ...이것이 이김, `components` > `base`이기 때문, */
} /* .link 자체가 더 구체적이지 않더라도 */
위력: 높은 레이어의 낮은 specificity 유틸리티가 낮은 레이어의 높은 specificity 규칙을 덮어쓸 수 있습니다. 이는 더 이상 덮어쓰기 순서를 관리하기 위해 !important나 selector 편법이 필요 없다는 뜻입니다 — CSS를 레이어(reset → 프레임워크 → 컴포넌트 → 오버라이드)로 조직하면 순서가 예측 가능해집니다.
:where(.a, .b, .c) p { color: red; } /* specificity 기여: 0,0,0 */
:where()는 인자를 매칭하지만 specificity를 전혀 더하지 않습니다 — 누구나 쉽게 덮어쓸 수 있는 기본값/리셋에 완벽합니다.
:where(ul) { margin: 0; } /* 어떤 나중 규칙이든 손쉽게 이기는 리셋 */
:is(h1, h2, h3) a { } /* 같은 요소를 매칭하지만, specificity = 가장 구체적인 인자 */
:is()는 (:where()처럼) 긴 selector 목록을 축약하지만 specificity를 기여합니다(가장 구체적인 인자의 것). 그래서 일반적인 가중치를 원할 때는 그룹화에 :is()를, 덮어쓰기 가능하길 원할 때는 :where()를 쓰세요.
:is(#id, .class) p { } /* specificity: 1,0,0 (#id가 계산됨) */
:where(#id, .class) p { }/* specificity: 0,0,0 (항상 0) */
이들이 함께 CSS의 가장 어려운 유지보수 문제 — 통제되지 않는 specificity — 를 해결합니다. @layer는 덮어쓰기 순서를 명시적이고 의도적으로 만들고(!important 확전 없음), :where()는 절대 당신과 싸우지 않는 리셋/기본값을 작성하며, :is()는 복잡한 selector를 DRY하게 유지합니다.
이들은 확장 가능하고 프레임워크 친화적인 CSS 아키텍처를 위한 기초 도구입니다.
주니어부터 시니어까지 상세한 답변이 포함된 IT 면접 질문 라이브러리.
후원하기