WeniVooks

검색

HTML/CSS 에센셜

선택자 우선순위

CSS 언어에는 충돌 시 어떤 규칙이 우선하는지 규칙이 있습니다. 이러한 규칙을 선택자 우선 순위라고 합니다.

CSS 선택자 우선순위는 크게 세 가지 원칙을 따릅니다.

  1. 후자 우선의 원칙
  2. 구체성(명시도)의 원칙
  3. 중요성의 원칙

1. 후자 우선의 원칙

CSS에서는 동일한 선택자에 동일한 속성이 여러 번 정의될 경우, 가장 마지막에 정의된 스타일이 적용됩니다. 이를 '후자 우선의 원칙'이라고 합니다.

이 경우, 모든 <p> 요소의 텍스트 색상은 가장 마지막에 정의된 스타일인 빨간색이 됩니다.

2. 구체성(명시도, Specificity)의 원칙

구체성, 또는 명시도는 선택자가 얼마나 구체적으로 요소를 지정하는지를 나타냅니다. 더 구체적인 선택자가 덜 구체적인 선택자보다 우선순위가 높습니다.

2.1 구체성 계산 방법

구체성은 다음과 같은 가중치로 계산됩니다.

  1. 인라인 스타일: 1000점
  2. ID 선택자: 100점
  3. 클래스 선택자, 가상 클래스, 속성 선택자: 10점
  4. 요소(타입) 선택자, 가상 요소 선택자: 1점
  5. 전체 선택자: 0점

위 순서대로 가중치가 높습니다.

구체성 계산 유의사항

  • :not():is()는 자체적으로 가중치를 가지지 않습니다. 대신 내부에 작성된 선택자의 가중치가 전체 선택자의 가중치 계산에 포함됩니다.
  • :where()는 내부 선택자와 관계없이 항상 0점의 가중치를 가집니다.
  • 가상 클래스(:hover)와 가상 요소(::before)를 구분하는 것이 중요합니다. 가상 클래스는 10점, 가상 요소는 1점입니다.

이 경우, #container p가 가장 구체적이므로, 텍스트 색상은 파란색이 됩니다.

2.2 구체성 계산 예시
* { }                   /* 구체성: 0 */
li { }                  /* 구체성: 1 (요소 선택자) */
li:first-child { }      /* 구체성: 11 (1 + 10) */
ul li { }               /* 구체성: 2 (1 + 1) */
ul ol+li { }            /* 구체성: 3 (1 + 1 + 1) */
h1 + *[rel=up] { }      /* 구체성: 11 (1 + 10) */
ul ol li.red { }        /* 구체성: 13 (1 + 1 + 1 + 10) */
li.red.level { }        /* 구체성: 21 (1 + 10 + 10) */
#x34y { }               /* 구체성: 100 (ID 선택자) */
style=""                /* 구체성: 1000 (인라인 스타일) */
* { }                   /* 구체성: 0 */
li { }                  /* 구체성: 1 (요소 선택자) */
li:first-child { }      /* 구체성: 11 (1 + 10) */
ul li { }               /* 구체성: 2 (1 + 1) */
ul ol+li { }            /* 구체성: 3 (1 + 1 + 1) */
h1 + *[rel=up] { }      /* 구체성: 11 (1 + 10) */
ul ol li.red { }        /* 구체성: 13 (1 + 1 + 1 + 10) */
li.red.level { }        /* 구체성: 21 (1 + 10 + 10) */
#x34y { }               /* 구체성: 100 (ID 선택자) */
style=""                /* 구체성: 1000 (인라인 스타일) */

[추천사이트: 명시도 계산기 사이트]

Specificity Calculator

3. 중요성의 원칙

!important 선언은 다른 모든 선언보다 우선합니다. 이는 매우 강력한 도구이지만, 남용하면 CSS의 예측 가능성과 유지보수성을 해칠 수 있습니다. !important 는 선택자 우선순위에 직접적인 영향을 미칩니다.

important 사용은 좋지 못한 습관입니다.

!important는 CSS의 자연스러운 상속을 깨트리기 때문에 오류/버그 발생 시 수정을 어렵게 만듭니다. 하지만 다음과 같은 제한적인 상황에서는 사용이 정당화될 수 있습니다.

  1. 외부 라이브러리의 CSS를 재정의해야 할 때
  2. 접근성 향상을 위한 사용자 정의 스타일에서
  3. 유틸리티 클래스가 항상 적용되도록 보장해야 할 때 (예: .hidden { display: none !important; })

일반적인 스타일링에서는 더 구체적인 선택자를 사용하는 것이 바람직합니다.

CSS에서 스타일이 충돌할 때는 다음과 같은 순서로 규칙이 적용됩니다.

  1. 먼저 중요성의 원칙이 최우선 적용됩니다. (!important가 있는 선언이 항상 우선)
  2. 그 다음 구체성의 원칙이 적용됩니다. (더 구체적인 선택자가 우선)
  3. 마지막으로 후자 우선의 원칙이 적용됩니다. (같은 구체성을 가진 경우 나중에 선언된 스타일이 우선)

위 예제에서 color: green !important!important 때문에 최우선 적용됩니다. 만약 !important가 없었다면, #examplecolor: purple이 적용됐을 것입니다. #example 선택자(100점)가 .text 선택자(10점)보다 구체성이 높고 같은 구체성의 #example { color: blue; }보다 나중에 선언되었기 때문입니다.

이처럼 CSS 우선순위 규칙은 중요성 → 구체성 → 선언 순서의 계단식으로 적용됩니다.

4. 상속과 우선순위 (새로 추가)

CSS에서 일부 속성은 부모 요소에서 자식 요소로 상속됩니다. 그러나 상속된 속성은 요소에 직접 적용된 속성보다 우선순위가 낮습니다.

상속된 속성은 구체성 점수가 0점으로 취급되므로, 직접 적용된 스타일이 항상 상속된 스타일보다 우선합니다.


명시도의 개념을 재미난 그림으로 나타낸 사이트

CSS Specifishity
10.4 가상 클래스 심화10.6 네이밍 규칙