도구
가이드

CSS 명시도 계산기

참고 자료

임의의 CSS 선택자의 명시도 (A, B, C)를 계산합니다 — ID, 클래스, 속성, 가상 클래스와 요소를 처리하고, 여러 선택자를 비교하며, 각 부분의 기여도를 분해해 보여줍니다. :is(), :not(), :where()를 지원합니다.

100% 클라이언트 백엔드 없음
ID 선택자 (A) 클래스, 속성 및 가상 클래스 (B) 요소 및 가상 요소 (C)
선택자 명시도 (A, B, C)
기여
명시도를 계산할 CSS 선택자를 하나 이상 입력하세요.
이 페이지에서

CSS 명시도란?#

두 CSS 규칙이 같은 요소의 같은 속성을 설정하려 할 때, 브라우저는 나중에 쓰인 것을 고르는 게 아니라 명시도가 더 높은 것을 고릅니다. 명시도는 캐스케이드가 버전 번호처럼 비교하는 세 부분 점수 (A, B, C)입니다.

  • A — ID 선택자(#header).
  • B — 클래스 선택자(.btn), 속성 선택자([type=email]), 가상 클래스(:hover, :focus).
  • C — 타입 선택자(div, a)와 가상 요소(::before, ::first-line).

A를 먼저 비교하고, 동점이면 B, 그 다음 C로 떨어집니다. ID 하나 (1,0,0)은 아무리 많은 클래스 (0,99,99)를 이기고, 그것은 다시 아무리 많은 타입을 이깁니다. 범용 *, 결합자(> + ~), 중첩 선택자 &는 아무것도 더하지 않습니다.

이 페이지는 붙여넣은 어떤 선택자에 대해서든 이 튜플을 계산합니다. 현대의 기능적 가상 클래스 :is(), :where(), :not(), :has():nth-child()of S 절을 포함해서요. 선택자 목록의 순위를 매기고 어느 조각이 무엇을 기여했는지 정확히 보여줍니다. 보편적인 CSS 질문 “왜 내 규칙이 지나요?”에 가장 빠르게 답하는 방법입니다.

사용 방법#

  1. 예제를 클릭해 작업된 선택자 세트를 불러오거나, 상자를 비우고 자신의 것을 붙여넣으세요. 단일 선택자(#nav .item) 또는 전체 규칙(#nav .item { color: red })을 입력할 수 있으며, 도구는 { 앞부분을 읽습니다.
  2. 선택자가 여러 개인가요? 쉼표로 구분하세요. 가장 구체적인 것에서 가장 덜 구체적인 것 순으로 순위가 매겨지고, 승자가 표시됩니다.
  3. 오른쪽 창이 각 선택자를 (A, B, C) 튜플과 기여한 모든 조각의 색상 분석과 함께 나열합니다(빨강 = ID, 파랑 = 클래스/속성/가상 클래스, 초록 = 타입/가상 요소). 점수가 왜 그런지 볼 수 있습니다.
  4. 오른쪽 위의 색상 범례가 어느 점이 A / B / C에 매핑되는지 상기시킵니다.
  5. 규칙에 !important가 있었다면 정보 메모가 나타납니다. !important는 명시도 비교 안이 아니라 그 에 있는 선언 수준의 오버라이드입니다.

주요 특징#

  • 까다로운 경우에 정확. :where()는 항상 (0,0,0)을 기여하고, :is() / :not() / :has()는 인자 중 가장 높은 명시도를 취하며, 구형 :before:nth-child()of S 절은 Selectors Level 4에 따라 처리됩니다.
  • 쉼표로 구분된 목록의 순위를 매기고 동점을 표시하여 여러 규칙 중 어느 것이 이길지 한눈에 볼 수 있습니다.
  • 조각별 분석. 모든 #id, .class, [attr], :pseudo-class, ::pseudo-element, 타입이 기여한 정확한 텍스트와 함께 항목화됩니다.
  • 전체 규칙을 관대하게. a:hover { text-decoration: underline }을 붙여넣으면 주석은 벗겨지고 선언 블록은 자동으로 무시됩니다.
  • 100% 로컬. 아무것도 페이지를 떠나지 않으며, 어떤 스타일시트도 가져오거나 평가하지 않습니다.

실제 예시#

흔한 디버깅 퍼즐: 세 규칙이 모두 같은 링크를 겨냥하고, 잘못된 색이 이깁니다. 그것들을 상자에 붙여넣으세요.

.button:hover
:is(.card, #hero) .button
a.button

출력은 순위를 매깁니다.

순위선택자튜플
1:is(.card, #hero) .button(1, 1, 0) — 승자
2.button:hover(0, 2, 0)
3a.button(0, 1, 1)

승자는 클래스가 가장 많은 것이 아닙니다. :is(.card, #hero)는 인자 중 가장 높은 명시도를 상속합니다. #hero가 ID이므로, .card(0,1,0)에 불과함에도 :is()(1,0,0)을 가집니다. 거기에 .button을 더하면 B가 하나 올라 (1,1,0)이 됩니다. A 열의 그 ID 하나가 .button:hover (0,2,0)의 클래스 두 개를 이깁니다. 이것이 프로덕션 CSS에서 :is()를 위험하게 만드는 정확한 놀라움입니다.

같은 그룹화를 명시도를 올리지 않고 하려면, :is():where()로 바꾸세요.

:where(.card, #hero) .button   →   (0, 1, 0)

이제 a.button에서 타입을 뺀 것과 동점이 되고, 소스 순서가 결정합니다. 그것이 :where()가 존재하는 전체 이유입니다.

FAQ#

왜 ID 하나가 클래스 수백 개를 이기나요?#

명시도는 합이 아니라 버전 번호처럼 왼쪽에서 오른쪽으로 열을 비교합니다. (1,0,0)은 A 열이 첫째에서 0이 아닌, 둘째에서 0이므로 (0,999,999)보다 “앞서 있습니다”. B와 C 열은 아예 참조되지 않습니다. 이것은 의도적입니다. ID는 모호하지 않은 단일 항이 되도록 설계되었습니다.

:is():where()의 차이는?#

매칭하는 것에서는 동일하지만 명시도에서는 반대입니다. :is(.a, #b)는 인자 중 가장 높은 명시도를 취합니다(#b(1,0,0)을 만들게). :where(.a, #b)는 인자와 무관하게 항상 **(0,0,0)**을 기여합니다. 쉽게 오버라이드할 수 있는 낮은 명시도의 기본값에는 :where()를, 결합된 선택자가 진짜 경쟁하기를 원할 때 :is()를 쓰세요.

인라인 style="…" 속성이 이것들을 이기나요?#

네. 인라인 스타일은 정상 캐스케이드에서 어떤 선택자 기반 규칙보다 우선합니다(더 높은 출처에 있으므로), !important 없이는 어떤 선택자 튜플도 인라인 스타일을 오버라이드하지 못합니다. 이것은 (A,B,C) 점수와는 별개의 축이며, 그래서 도구는 선택자만 평가합니다.

!important는 어디에 들어맞나요?#

!important는 선택자 속성이 아니라 선언 수준 플래그입니다. (A,B,C) 튜플을 바꾸지 않습니다. 전체 선언을 더 높은 캐스케이드 출처로 옮기므로, !important 규칙은 명시도와 무관하게 일반 규칙을 이깁니다. 도구는 그 존재를 정보적으로 알리지만 점수에는 빼놓습니다.