CSS 선택자의 구체성 값(Specificity)
스타일이 적용되는 선택자가 얼마나 구체적으로 선언되어 있냐는 것을 숫자로 나타낸 값입니다.
서로 다른 선택자를 사용하는 두 개 이상의 규칙이 동일한 요소를 선택할 때 구체성 값이 높은 선택자의 스타일이 적용됩니다.
이것이 CSS에서 스타일 규칙의 우선 순위를 결정하는 핵심 원칙 중 하나입니다.
CSS 선택자의 구체성 값은 '명시도'라고도 부르며, 이 규칙을 이해하고 적절하게 활용하면 웹 페이지의 스타일링을 더욱 정확하게 제어할 수 있습니다. 구체성 값은 선택자의 요소, 클래스, 아이디 등의 조합에 따라 계산되며, 높은 구체성 값일수록 우선순위가 높아집니다. 이 핵심 개념을 숙지하고 적절히 활용하여 웹 개발에서 성공적인 스타일링을 구현할 수 있습니다.
CSS 선택자의 역할과 중요성
CSS 선택자의 기본 개념과 이를 이해하는 것은 매우 중요합니다.
CSS 선택자는 웹 페이지에서 HTML 요소를 선택하여 스타일을 적용하는 역할을 하고, 웹 페이지의 디자인과 레이아웃을 제어하기 위한 필수 도구입니다. 선택자를 통해 원하는 요소를 정확하게 선택하여 스타일을 적용할 수 있어야 합니다. 선택자를 적절히 사용할 수 있어야 유지보수 용이성을 향상시키고 코드의 재사용성을 높일 수 있습니다.
선택자의 효율적인 사용은 페이지의 스타일링 작업을 더욱 효율적으로 수행할 수 있고 웹사이트 성능을 향상시키는데 도움이 됩니다.
CSS 선택자의 구체성 값(Specificity)이란?
CSS로 스타일을 위해 HTML 요소를 선택할 때 실제로 서로 다른 선택자를 사용하는 두 개 이상의 규칙이 동일한 요소를 선택할 때가 있습니다.
그렇다면 어떤 규칙이 우선인지 어떻게 알 수 있을까요? 예제로 살펴 보겠습니다.
<p id="my-id" class="a b">
문단 요소입니다.
</p>
* {
color: red;
}
p {
color: blue;
}
#my-id {
color: green;
}
.a {
color: olive;
}
.b {
color: pink;
}
#my-id
선택자로 스타일한 값인 green이 적용되었습니다.
문단 요소입니다.
위 예제는 여러 개의 CSS 선택자를 사용해서 동일한 요소를 선택할 때 스타일이 적용되는 사례에 대해 살펴 본 것입니다. 여러 개의 CSS 선택자를 사용했지만 #my-id
선택자의 스타일이 적용되었습니다. 왜 #my-id
선택자의 스타일이 적용되었을까요?
#id
선택자의 스타일이 적용된 이유는 여러 개의 CSS 선택자를 사용해서 동일한 요소를 선택할 때 우선적으로 적용되는 CSS 선택자의 규칙이 있기 때문입니다. 그럼 어떤 규칙이 있다는 것인지 알아보겠습니다.
얼마나 구체적인(구체성이 있는) CSS 선택자를 사용하느냐가 기준이 됩니다!
이렇듯이 CSS에서는 '얼마나 구체적으로 CSS 선택자를 사용하느냐'를 기준으로 여러 개의 CSS 선택자를 사용해서 동일한 요소를 선택할 때 우선적으로 적용하는 규칙이 있는데, 이 규칙을 CSS 선택자의 구체성 값(Specificity) 혹은 '명시도'라고도 부릅니다.
CSS 선택자의 구체성 값은 스타일 규칙이 적용되는 우선 순위를 결정하는 수치입니다.
구체성 값은 선택자에 사용된 요소, 클래스, 아이디 등의 조합에 따라 계산되며, 값이 높을수록 우선순위가 높아집니다. 구체성 값은 스타일 규칙 충돌 시 어떤 규칙이 우선적으로 적용되는지를 정의하며, 스타일링을 더욱 정확하게 제어할 수 있게 해줍니다.
CSS 선택자의 구체성 값의 규칙
- 구체성의 값은 0,0,0,0 처럼 4개의 부분 값으로 표현되어 다음과 같이 계산됩니다.
- 선택자에 있는 모든
#id
선택자에 0,1,0,0 값이 추가됩니다. - 선택자에 있는 모든
.class
선택자, 가상클래스(:first-child
,:last-child
,:focus
,:active
,:visited
,:hover
,::selection
등) 선택자, 기타 속성 선택자에 0,0,1,0 값이 추가됩니다. - 선택자에 있는 요소 이름 선택자와 가상요소(
::before
,::after
) 선택자에 0,0,0,1 값이 추가됩니다. - 모든 요소 선택자(
*
)는 값도 없고 아무런 영향을 주지 않습니다. :is()
및:not()
은 값도 없고 아무런 영향을 주지 않습니다. (:is()
및:not()
내부에 선언한 선택자는 영향을 끼칩니다.)- 선택자의 계층이나 구조의 조합은 아무런 영향을 주지 않습니다.
CSS 선택자의 구체성 값 예제
CSS 선택자의 구체성 값의 규칙으로 CSS 선택자의 구체성 값을 예제에서 계산해 보겠습니다.
h2 {color: red;} /* 구체성 값 = 0,0,0,1 */
p em {color: purple;} /* 구체성 값 = 0,0,0,2 */
.grape {color: purple;} /* 구체성 값 = 0,0,1,0 */
* .bright {color: yellow;} /* 구체성 값 = 0,0,1,0 */
p.bright em.dark {color: maroon;} /* 구체성 값 = 0,0,2,2 */
#id216 {color: blue;} /* 구체성 값 = 0,1,0,0 */
p#addr [href] {color: gray;} /* 구체성 값 = 0,1,1,1 */
그럼 구체성이 무엇인지 알아보기 위해 살펴 보았던 예제로 구체성 값을 적용해 보겠습니다.
<p id="my-id" class="a b">
문단 요소입니다.
</p>
* { /* 구체성 값 = 0,0,0,0 */
color: red;
}
p { /* 구체성 값 = 0,0,0,1 */
color: blue;
}
#my-id { /* 구체성 값 = 0,1,0,0 */
color: green;
}
.a { /* 구체성 값 = 0,0,1,0 */
color: olive;
}
.b { /* 구체성 값 = 0,0,1,0 */
color: pink;
}
#id
선택자의 값인 green이 적용되었습니다.
문단 요소입니다.
인라인 스타일의 구체성 값
지금까지 살펴 본 구체성 값은 0으로 시작되는 규칙의 값입니다. 그래서 왜 맨 앞의 0이 존재하는지에 대해 궁금하셨을 것입니다. 맨 앞의 0은 style
속성으로 인라인 스타일 선택이 있을 경우에 매겨지는 값입니다.
선택자로 HTML 요소를 선택하는 것이 아닌, 직접 스타일하는 것이니 당연히 구체성이 가장 크다는 의미입니다.
<h1 id="green-color" style="color:red;">id로 선택된 제목글입니다.</h1> <!-- 구체성 값 = 1,0,0,0 -->
!important
선언
CSS 스타일을 지정할 때 가끔 어떤 속성(Property)은 아주 중요해서 다른 속성보다 우선시해야 할 때가 있습니다.
이럴 경우 !important
를 사용하면 내부의 구체성 규칙을 변경하여 우선적으로 선택됩니다.
구체성 값을 적용해 보았던 예제에 !important
를 사용해 보겠습니다.
<p id="my-id" class="a b">
문단 요소입니다.
</p>
* { /* 구체성 값 = 0,0,0,0 */
color: red;
}
p { /* 구체성 값 = 0,0,0,1 */
color: blue;
}
#my-id { /* 구체성 값 = 0,1,0,0 */
color: green;
}
.a { /* 구체성 값 = 0,0,1,0 */
color: olive !important; /* !important 사용 */
}
.b { /* 구체성 값 = 0,0,1,0 */
color: pink;
}
!important
를 사용한 요소 선택자의 스타일이 적용되었습니다.
문단 요소입니다.
일반선언과 !important
로 표시된 선언들은 특별한 구체성을 갖지 않지만, 이 표시가 없은 선언들과는 별개로 다루어집니다. 실제로 !important
선언은 !important
선언들끼리, 이 표시가 없는 일반 선언은 일반 선언들기리 구체성이 결정됩니다. 따라서, !important
선언과 일반적인 선언이 충돌할 때에는 !important
선언이 우선권을 갖습니다.
!important
선언은 언제 하는 것이 좋을까요?
- 인라인 스타일을 재정의할 때 유용합니다.
- 특히, 자바스크립트로 CSS를
style
속성으로 정의 할 때는 인라인 스타일로 적용되는데, 이럴 경우 자바스크립트로도 스타일을 정의하지 못하게 할 때 유용합니다. - 구체성이 높은 규칙을 무시하고 재정의하고 싶을 때 유용합니다.
구체성 값이 동일한 여러 선택자가 동일한 요소를 선택한다면
여러 개의 CSS 선택자를 사용해서 동일한 요소를 선택할 때 스타일이 적용되는 구체성 값에 대해 알아보았습니다. 만약에 동일한 요소를 선택한 여러 개의 CSS 선택자가 구체성 값이 같다면 어떻게 될까요?
이럴 경우 나중에 스타일을 정의한 선택자의 스타일이 지정됩니다. 덮어쓰기(Override)를 하는 것입니다. 예제로 살펴 보겠습니다.
<p class="a b">
p 문단 요소입니다.
</p>
.a { /* 구체성 값 = 0,0,1,0 */
color: olive;
}
.b { /* 구체성 값 = 0,0,1,0 */
color: pink;
}
p 문단 요소입니다.
이 예제에서 볼 수 있듯이 나중에 스타일을 정의한 선택자의 스타일이 지정됩니다.
동일한 선택자의 같은 속성을 여러 번 지정했을 경우
동일한 선택자의 같은 속성을 여러 번 지정했을 경우에도 나중에 지정한 속성의 값이 지정됩니다.
<p class="a b">
p 문단 요소입니다.
</p>
.a {
color: olive; /* 같은 속성을 여러 번 지정했습니다. */
color: red; /* 같은 속성을 여러 번 지정했습니다. */
}
p 문단 요소입니다.
!important
선언을 동일한 요소에 여러 번 지정했을 경우
<p class="a b">
p 문단 요소입니다.
</p>
.a { /* 구체성 값 = 0,0,1,0 */
color: olive !important;
}
.b { /* 구체성 값 = 0,0,1,0 */
color: blue !important;
}
!important
선언을 한 선택자의 스타일이 지정됩니다. 덮어쓰기(Override)를 하는 것입니다.
p 문단 요소입니다.
!important
선언이 여러 번 있을 경우 위 예제들과 같이 구체성의 값을 기준으로 같을 경우 나중에 선언한 선택자의 스타일이 지정됩니다. 물론, 동일한 선택자에 같은 속성을 여러 번 지정했을 경우에도 같은 규칙으로 적용됩니다.
주의해야 할 구체성 값의 함정과 실수
구체성 값은 개발자들이 CSS 스타일 우선순위를 이해하고 적용할 때 주의해야 할 함정과 실수를 가지고 있습니다.
#id
선택자의 높은 구체성:#id
선택자는 구체성 값이 매우 높습니다. 따라서#id
선택자를 남용하면 다른 선택자들과 충돌할 가능성이 높아집니다.#id
선택자는 고유한 식별자로 사용되어야 하며, 스타일링의 목적이 아닌 경우에는.class
선택자를 사용하는 것이 좋습니다.- 모든 요소 선택자의 낮은 구체성: 모든 요소 선택자인
*
선택자는 구체성 값이 없습니다. 따라서 선택자를 너무 많이 사용하면 다른 선택자들과 구체성 충돌이 발생할 수 있습니다. 가능한한 구체적인 선택자를 사용하여 스타일 규칙을 정의하는 것이 좋습니다. - 불필요한 계층 구조: 선택자의 계층 구조가 복잡하고 중첩된 경우 구체성 값이 높아집니다. 불필요한 계층 구조는 구체성 충돌을 야기할 수 있으며, 스타일 규칙의 유지보수와 가독성을 어렵게 만들 수 있습니다. 가능한한 간결하고 직접적인 선택자를 사용하여 구체성 값을 낮추는 것이 좋습니다.
- 인라인 스타일의 우선순위: 인라인 스타일은 다른 선택자들보다 구체성 값이 가장 높습니다. 그러므로 인라인 스타일을 남용하면 다른 스타일 규칙을 덮어쓰게 될 수 있습니다. 인라인 스타일은 최소한으로 사용하고, CSS 파일에 스타일을 정의하여 일관성과 유지보수성을 유지하는 것이 좋습니다.
이러한 함정과 실수를 피하려면 구체성 값의 개념을 이해하고, 선택자를 적절하게 사용하여 스타일 규칙을 작성해야 합니다. 구체성 값을 적절히 이해하고 활용하면 예기치 않은 스타일 충돌을 방지하고, 웹 페이지 스타일의 일관성과 유지보수성을 높일 수 있습니다.
선택자의 효율적인 사용을 위한 성능 고려 사항
선택자의 효율적인 사용을 위해 성능을 고려해야 합니다. 다음은 선택자의 효율성과 성능을 개선하기 위한 몇 가지 사항입니다.
- 구체성을 낮추기: 구체성이 높은 선택자보다 구체성이 낮은 선택자를 사용하는 것이 일반적으로 성능에 이점을 줍니다. 너무 많은 요소나
.class
,#id
선택자를 사용하는 것은 선택자의 복잡성과 매칭 과정을 증가시킬 수 있으므로 피하는 것이 좋습니다. - 최소한의 선택자 사용: 필요한 스타일을 적용하는 데 필요한 최소한의 선택자를 사용하는 것이 좋습니다. 불필요한 부모/자식 선택자를 사용하지 않고 직접적인 선택자를 활용하여 스타일 규칙을 정의하는 것이 성능에 도움이 됩니다.
- 모든 요소 선택자(
*
) 사용 줄이기: 범용 선택자인*
는 모든 요소에 일치하므로 매칭 과정에서 비효율적일 수 있습니다. 가능한 경우 구체적인 요소 이름 선택자를 사용하여 모든 요소 선택자의 사용을 줄이는 것이 좋습니다. - 선택자의 범위 제한: 선택자의 범위를 가능한한 제한하여 매칭 과정을 최적화할 수 있습니다. 특정 부모 요소 내에서만 스타일을 적용해야 한다면 해당 부모 요소를 포함한 선택자를 사용하는 것이 좋습니다.
- 스타일 규칙의 수 줄이기: 페이지에 적용되는 스타일 규칙의 수를 최소화하는 것도 성능에 도움이 됩니다. 불필요한 스타일 규칙을 제거하고 가능한 한 적은 스타일 규칙을 사용하여 성능을 향상시키는 것이 좋습니다.
이러한 성능 고려 사항을 염두에 두고 선택자를 사용하면 웹 페이지의 스타일링 작업을 더욱 효율적으로 수행할 수 있습니다.
명세서
명세서 사양 | |
---|---|
CSS 선택자 구체성 값 |
Selectors Level 4 #specificity-rules |