코딩하는 김딸기
캐스케이드와 셀렉터 특정성 점수 본문
Selector Specificity
다른 이름: 선택기 특이성, 특수성, 특이도
캐스케이드는 브라우저에 내장된 체계로, 여러 곳에서 작성된 스타일 규칙이 하나의 요소에 반영될 때 어떤 스타일 규칙이 최종적으로 반영 될지를 결정합니다. 이 과정에서 셀렉터 특정성 점수, 인라인 스타일시트, !important 규칙, 코드 작성 순서등의 요소들이 고려됩니다.
셀렉터 특정성 점수는 캐스케이드 체계가 동작하는 데 있어 가장 핵심적인 구성 요소입니다. 셀렉터가 작성된 형태에 따라 우선순위가 결정되며, 높은 우선순위의 셀렉터에 작성된 스타일이 최종적으로 적용됩니다.
셀렉터의 작성 형태에 따른 특정성 점수 계산
h1 {
background-color: orange;
}
h1 {
background-color: blue;
}
위 코드에서 h1요소는 두 개의 서로 다른 스타일 규칙이 적용됩니다. 이 경우, 마지막으로 정의된 스타일이 우선합니다. 따라서 h1 요소의 background-color는 blue로 설정됩니다. 이는 매우 자연스러운 동작입니다.
나중에 작성된 CSS 규칙이 가장 나중에 반영되게 됩니다.
그러나 이러한 코드의 작성 순서만으로 대규모 스타일을 관리하는 것은 매우 어려울 것입니다. 코드의 작성 순서 이외에도 셀렉터의 작성 형태에 따른 순위 계산 알고리즘이 존재합니다.
.wow {
background-color: purple;
}
h1 {
background-color: orange;
}
h1 {
background-color: blue;
}
.wow 클래스 셀렉터는 맨 위에 작성 되었더라도 특정성 점수에 의해 하단의 h1 타입 셀렉터들 보다 우선순위가 높게 평가 됩니다. 이처럼 셀렉터의 작성 형태에 따라 셀렉터 특정성 점수가 부여됩니다. 본 글에서는 이 셀렉터에 할당된 특정성 점수를 금-은-동메달에 비유하여 설명 할 것입니다.
브라우저는 구체적으로 작성된 셀렉터일수록 높은 가치가 있다고 판단한다. 구체적인 정도를 평가하는 지표를 알자.
유니버설 셀렉터 (Universal Selector)
* { }
해당 셀렉터는 모든 태그의 타입명을 가진 요소를 한번에 선택 할 수 있는 셀렉터입니다. 제일 광범위한 선택임으로 구체성이 매우 떨어지게 됩니다. 즉, 해당 셀렉터 특정성 점수는 없습니다.
타입 셀렉터 (Type Selector)
div { }
클래스 셀렉터 (Class Selector)
.wow { }
해당 셀렉터는 클래스명으로 선택하는 셀렉터입니다. "이름"이라는 구체적인 정보를 기반으로 선택하고 있습니다. 고로 타입 셀렉터보다 셀렉터 특정성 점수가 높습니다. 은메달 1개입니다.
속성 셀렉터 (Attribute Selector)
[type="text"] { color: black; }
해당 셀렉터는 태그의 HTML Essentials/속성, 즉 어트리뷰트(Attribute)를 이용한 셀렉터 기법입니다. 은메달 1개입니다.
아이디 셀렉터 (ID Selector)
#wow { }
해당 셀렉터는 아이디명으로 선택하는 셀렉터입니다. 아이디는 여러 요소에 동일한 클래스명을 지정할 수 있는 클래스와는 달리 전체 페이지에서 단 하나의 요소에 지정할 수 있는 셀렉터 기법입니다. 즉 "주민등록번호"처럼 고유한 식별자입니다. 금메달 1개입니다.
가상 클래스 셀렉터 (Pseudo Class Selector)
가상 클래스도 결국 클래스 개념입니다. 일반적으로, 클래스 셀렉터와 마찬가지인 은메달 1점이 부여 됩니다.
하지만 모든 가상 클래스 셀렉터가 같은 셀렉터 특정성 점수를 가지는 것은 아닙니다.
가상 클래스 종류에 따라 달라지는 셀렉터 특정성 점수
:not()가상 클래스 셀렉터 자체는 셀렉터 특정성 점수가 없습니다. 다만 괄호 안에 들어가는 셀렉터의 특정성 점수로 계산 되어 집니다.
:not(#example) { color: red; } /* 아이디로 평가됨 */
:has()가상 클래스 셀렉터는 괄호안에 들어가는 셀렉터의 리스트 중 가장 높은 셀렉터 특정성 점수를 가지고 있는 것 기준으로 평가 됩니다.
:has(nav, #main-nav) { color: red; } /* 아이디로 평가됨 */
:is()가상 클래스 셀렉터는 괄호 내에 들어가는 셀렉터의 리스트 중 가장 높은 특정성 점수를 가지고 있는 것 기준으로 평가 됩니다.
:is(h1, .class, #id) { color: blue; } /* 아이디로 평가됨 */
:where()가상 클래스 셀렉터는 셀렉터 특정성 점수에 영향을 끼치지 않습니다.
:where(h1, .class, #id) { color: green; } /* 특정성 점수에 영향이 없음 */
가상 요소
가상 요소의 셀렉터 특정성 점수는 동메달 1개입니다.
콤비네이터 (Combinator)
.wow a { } /* 공백: Descendant combinator */
.wow > a { } /* >: Child combinator */
.wow + a { } /* +: Adjacent sibling combinator */
.wow ~ a { } /* ~: General sibling combinator */
테스트 해보기
위에서 설명된 다양한 셀렉터들을 조합하여 원하는 요소를 선택하게 될 것입니다.
조합을 통해 최종 셀렉터 특정성 점수가 결정이 될 것이고, 높은 점수 일 수록 우선순위가 높게 평가 될 것입니다.
body div.wow > #wow {
}
위 셀렉터의 특정성 점수는 다음과 같습니다.
금-은-동 순으로 표기하였을때 1-1-2 의 특정성 점수가 완성 됩니다.
동메달 200개는 은메달 1개를 이길 수 없습니다.
은메달 200개는 금메달 1개를 이길 수 없습니다.
만약에 모든 조건이 동일하여 같은 셀렉터 특정성 점수가 부여된다면 캐스케이드 체계에 의해, 나중에 작성된 코드의 우선순위가 높게 책정 됩니다.
h1 | 0 | 0 | 1 | 0-0-1 |
h1 + p::first-letter | 0 | 0 | 3 | 0-0-3 |
li > a[href*="en-US"] > .inline-warning | 0 | 2 | 2 | 0-2-2 |
#identifier | 1 | 0 | 0 | 1-0-0 |
button:not(#mainBtn, .cta) | 1 | 0 | 1 | 1-0-1 |
!important와 인라인 스타일의 영향
셀렉터 특정성 점수 이외에도 !important 구문이나 태그의 style속성을 통해 직접 작성하는 인라인 스타일시트도 최종 캐스케이드 결과물에 영향을 줍니다.
인라인 스타일시트
모든 셀렉터 기법 보다도 인라인 스타일시트의 우선순위가 높게 책정됩니다.
<div style="background-color: red;">
셀렉터 설정을 이기고 무조건 RED
</div>
!important 구문의 사용
특정 속성의 값 뒤에 설정함으로서 해당 속성 값을 제일 우선적으로 적용 시킬 수 있습니다. 이는 그 어떤 CSS 규칙보다도 우선시 됩니다.
div {
background-color: red !important;
}
다만 !important 구문 끼리 충돌이 발생하는 경우에는, 또다시 셀렉터 특정성 점수에 의해 결정 됩니다.
div.wow {
background-color: blue !important;
}
div {
background-color: red !important;
}
똑같은 !important 구문이지만 div.wow의 점수가 div보다 높으므로 background-color: blue가 최종 반영 됩니다.
결론
CSS 코드는 필연적으로 방대해질 수 밖에 없습니다. 여러 시각적 요소의 스타일을 관리하기 위해서는 이 셀렉터 특정성 점수 개념을 잘 알고 있어야 합니다. 내가 작성한 CSS 규칙이 잘 적용되지 않는다면 1차적으로 셀렉터의 구조를 파악하여 셀렉터 특정성 점수가 어떻게 책정 되는지 파악하고 내가 의도한 결과물이 나올 수 있도록 셀렉터 특정성 점수를 잘 관리 해야만 할 것입니다.
셀렉터 특정성 점수 이외에도 태그의 속성으로 입력되는 스타일인 인라인 스타일시트, 각 속성의 값에 직접 적용되는 !important, 코드 작성 순서가 캐스케이드에 영향을 끼치는 요소이니 면밀히 파악해야 할 것입니다.
정리하자면, 셀렉터 특정성 점수는 셀렉터의 구체성을 측정하여 스타일 적용 우선순위를 결정하는 개념이고, 캐스케이드는 최종 스타일을 결정하는 포괄적인 체계 전체를 의미합니다. 캐스케이드 체계내에 셀렉터 특정성 점수 시스템이 포함된다고 볼 수 있습니다. 모든 CSS 결과물은 결국 캐스케이드 체계의 종합적인 결과물입니다.