CSS 적용 우선순위를 결정하는 특이도(Specificity)의 이해

Specificity, 특이도는 CSS가 적용되는 우선순위를 결정하는 기준입니다.

생소한 단어지만, 표준 통계 수학 용어로 사용되는 용어이고, CSS에서도 같은 의미로 사용합니다.

CSS에서는 특이도를 가장 일치하는 요소에 적용할 속성을 결정하는 가중치 숫자를 의미합니다.

어렵게 기술적으로 설명했지만, CSS 선택자 타입(ID, 태그, 클래스, CSS 위치 등)에 따라 정해진 가중치 숫자 값이 부여되고, 같은 요소를 선택하는 CSS 선택자가 여러 개일 경우 가중치 숫자 값이 가장 높은 CSS 선택자의 속성이 최종 적용됩니다.

조금 더 쉽게 설명하면 같은 요소에 속성을 적용하는 클래스가 여러 개면, 그중 특이도 가중치 숫자가 가장 높은 클래스의 속성이 적용됩니다.

가중치 속성 값이 완전히 동일하면, 뒤에 나오는 클래스가 적용됩니다.

특이도 가중치를 매기는 방법은 A-B-C-D 4개의 가중치 종류별로 개수 합을 구해서 우선순위 숫자로 비교를 합니다.

가중치 종류는 다음과 같이 구분합니다.

A : 인라인 CSS - 1,0,0,0으로 표시.

B : ID - 0,1,0,0과 같이 표시. 나오는 개수만큼 합계를 구해 0,x,0,0으로 표기.

C : 클래스, 가상 클래스, 나머지 속성들 - 0,0,1,0과 같이 표시. 나오는 개수만큼 합계를 구해 0,0,x,0으로 표기.

D : 요소(태그), 가상 요소 - 0,0,0,1과 같이 표시. 나오는 개수만큼 합계를 구해 0,0,0,x로 표기.

그리고, 가중치 연산에 영향을 주는 CSS 선택자 요소들이 있습니다.

유니버설 선택자(*), 그외 결합 연산자들(+, ~, >) - 우선순위에 영향을 주지 않습니다. 가중치 값 합계를 구할 때 무시합니다.

!important - 가중치 값을 완전히 무시하고 최우선 순위를 가지는 속성 값 표시입니다. 가중치 합 계산에서 가장 높은 가중치를 가지는 인라인 CSS 보다 우선순위를 가집니다.

개념은 단순하지만, 처음 보면 4개의 종류별 가중치 개수 합계 표시로 우선순위를 구분하는 방식이 생소할 수 있습니다.

4가지 종류별 가중치 합을 위의 기준에 따라 구한 후 쉼표를 없애면 천 단위 숫자가 됩니다. 숫자가 가장 큰 CSS 선택자가 우선순위가 가장 높은 것이 됩니다.

위의 기준에 따라 ID로 정의한 속성은 클래스로 정의한 속성보다 우선순위가 높습니다.

그리고 태그로 정의한 속성보다는 클래스로 정의한 속성이 우선순위가 높습니다.

몇 가지 예를 들어 특이도 가중치를 구해보겠습니다.

가중치에서 쉼표를 제거한 숫자가 가중치 값이 되며, 값이 클수록 우선순위가 높아집니다.

CSS 선택자 가중치
article#content p > span 0,1,0,3
div#link a:hover 0,1,1,2
.menu ul li:first-child 0,0,2,2

좀 더 이해하기 쉽도록 다음과 같은 HTML 코드에서 같은 요소를 선택하는 다양한 CSS 선택자가 어떤 특이도 가중치를 가지게 되고 우선순위가 정해지는지 알아보겠습니다.

<div id="menu" class="topmenu">
  <ul class="items">
	  <li><a><span>메뉴항목</span></a></li>
  </ul>
</div>

다음 3가지 CSS 선택자는 모두 "메뉴항목" 텍스트를 선택합니다.

3가지 CSS 선택자는 가중치에 따라 우선순위가 적용되며, 최종적으로 가중치는 101(red) > 14(blue) > 13(green) 이 됩니다. 글자 색상은 가중치가 가장 높은 "#menu span"이 적용되어 빨간색(red)이 됩니다.

CSS 선택자 가중치
#menu span { color: red; } 0,1,0,1
.topmenu li a > span { color: green; } 0,0,1,3
div > ul.items li span { color: blue; } 0,0,1,4
가중치 순서로 CSS 선택자 적용

HTML 헤더 영역에 CSS를 표시하는 인페이지 CSS는 별도 외부 파일의 CSS와 같은 방식으로 우선 순위가 적용되며, 같은  특이도 우선순위 값을 가지는 CSS 선택자인 경우 인페이지 CSS와 외부 파일 CSS중 나중에 나오는 것이 적용됩니다.

다음과 같이 인페이지 CSS를 적용한 경우, "div > ul.items li span"과 같은 특이도 우선순위를 가진 CSS 선택자가 "index.css" 파일에 정의되어 있으면, 인페이지 HTML의 CSS로 적용됩니다.

기본적으로 인페이지 HTML은 별도 파일의 CSS를 단순히 HTML 파일 안에 옮겨놓은 것과 같습니다.

<link rel="stylesheet" href="./index.css">
<style>
	div > ul.items li span { color: black; }
</style>