CSS 팟캐스트 - 003: 구체성
다음 HTML 및 CSS를 사용하고 있다고 가정해 보겠습니다.
<button class="branding">Hello, Specificity!</button>
.branding {
color: blue;
}
button {
color: red;
}
여기서는 동일한 요소를 타겟팅하는 규칙이 두 개 있습니다. 각 규칙에는 버튼의 색상을 설정하려는 선언이 포함되어 있습니다. 하나는 버튼을 빨간색으로 색칠하려고 하고 다른 하나는 파란색으로 색칠하려고 합니다. 어떤 선언이 요소에 적용되나요?
CSS 특수성 알고리즘을 이해하는 것은 CSS가 경쟁 선언 중에서 어떻게 결정하는지 이해하는 데 핵심입니다.
명시도는 캐스케이드에 관한 이전 모듈에서 다룬 캐스케이드의 고유한 단계 중 하나입니다.
구체성 점수
출처 내의 각 선택기 규칙에는 점수가 부여됩니다. 구체성을 총 점수로 생각하고 각 선택기 유형이 해당 점수에 기여한다고 생각하면 됩니다. 구체성이 가장 높은 규칙의 선언이 우선합니다.
실제 프로젝트에서 구체성을 사용할 때는 적용되기를 바라는 CSS 규칙이 실제로 적용되도록 하면서도 복잡성을 방지하기 위해 일반적으로 점수를 낮게 유지하는 것이 균형을 맞추는 방법입니다. 구체성은 가능한 한 높게 설정하는 것이 아니라 필요한 만큼만 높게 설정해야 합니다. 향후에는 실제로 더 중요한 CSS를 적용해야 할 수도 있습니다. 가장 높은 구체성을 선택하면 작업이 어려워집니다.
특수성은 10진수가 아니라 A, B, C의 세 가지 구성요소로 구성된 3항입니다.
A: ID와 유사한 구체성B: 클래스 유사 특이성C: 요소와 유사한 명시도
(A,B,C) 표기법을 사용하여 표현되는 경우가 많습니다. 예를 들면 (1,0,2)입니다.
A-B-C 표기법도 일반적으로 사용됩니다.
구체성 비교 방법
구체성은 세 가지 구성요소를 순서대로 비교하여 비교합니다. A 값이 클수록 구체성이 높습니다. 두 A 값이 동일한 경우 B 값이 클수록 구체성이 높습니다. 두 B 값도 동일한 경우 C 값이 클수록 구체성이 높습니다. 모든 값이 동일한 경우 두 구체성은 동일합니다.
예를 들어 (1,0,0)의 A 값 (1)이 (0,4,3)의 A 값 (0)보다 크기 때문에 (1,0,0)가 (0,4,3)보다 구체성이 높은 것으로 간주됩니다.
선택기는 구체성에 영향을 미침
특이성 3요소의 각 부분은 0 값으로 시작하므로 기본 특이성은 (0,0,0)입니다.
선택자의 각 부분은 선택자 유형에 따라 A, B 또는 C 값을 증가시키는 명시도를 높입니다.
범용 선택기
유니버설 선택기 (*)는 구체성을 추가하지 않아 값이 초기 구체성인 (0,0,0)으로 유지됩니다.
* {
color: red;
}
요소 또는 의사 요소 선택기
요소 (유형) 또는 가상 요소 선택기는 요소와 유사한 구체성을 추가하여 C 구성요소를 1만큼 증가시킵니다.
다음 예시의 전체 구체성은 (0,0,1)입니다.
유형 선택기
div {
color: red;
}
의사 요소 선택기
::selection {
color: red;
}
클래스, 가상 클래스 또는 속성 선택기
클래스, 의사 클래스 또는 속성 선택기는 클래스 유사 명시도를 추가하여 B 구성요소를 1만큼 증가시킵니다.
다음 예시의 명시도는 (0,1,0)입니다.
클래스 선택기
.my-class {
color: red;
}
가상 클래스 선택기
:hover {
color: red;
}
속성 선택기
[href='#'] {
color: red;
}
ID 선택기
ID 선택기는 ID와 유사한 명시도를 추가하여 속성 선택기 ([id="myID"])가 아닌 ID 선택기 (#myID)를 사용하는 한 A 구성요소를 1만큼 증가시킵니다.
다음 예시에서 특이성은 (1,0,0)입니다.
#myID {
color: red;
}
기타 선택기
CSS에는 많은 선택자가 있습니다. 구체성을 더하지 않는 경우도 있습니다.
예를 들어 :not() 의사 클래스 자체는 구체성 계산에 아무것도 추가하지 않습니다.
:not() 의사 클래스의 명시도는 쉼표로 구분된 선택기 인수에서 가장 구체적인 선택기의 명시도로 대체됩니다. :not(:is(argument))로 작성된 것과 동일한 명시도를 제공합니다.
div:not(.my-class) {
color: red;
}
:is() 의사 클래스도 명시도 계산에 추가되지 않습니다. :not()와 마찬가지로 가장 구체적인 인수의 구체성을 취합니다.
:is(h1, h2, h3) {
color: blue;
}
이 샘플에는 선택기 (type)가 한 종류만 있으므로 명시도가 (0,0,1)입니다.
id가 추가되면 구체성이 (1,0,0)로 증가합니다.
:is(h1, h2, h3, #my-heading) {
color: blue;
}
:where() 의사 클래스는 다릅니다. 인수의 구체성과 관계없이 항상 (0,0,0)의 구체성을 갖습니다.
:where(h1, h2, h3, #my-heading) {
color: blue;
}
:where()를 사용하여 적용된 낮은 명시도 스타일을 사용하면 스타일 시트의 기본 선택기로 이러한 스타일을 나중에 재정의할 수 있습니다.
:where(#my-content) {
color: red;
}
p {
color: blue;
}
:where()의 인수 목록에 id이 있지만 여전히 (0, 0, 0)의 명시도만 있으므로 기본 p 선택기가 이를 재정의하고 텍스트는 blue이 됩니다.
이해도 테스트
특이성 점수 지정에 대한 지식 테스트
a[href="#"]의 구체성은 무엇인가요?
(0,0,1)a의 가치는 (0,0,1)이지만 [href="#"]의 가치는 (0,1,0)입니다.(0,1,0)a의 가치는 (0,0,1)이지만 [href="#"]의 가치는 (0,1,0)입니다.(0,1,1)a는 (0,0,1)의 가치가 있고 [href="#"]는 (0,1,0)의 가치가 있으므로 총 특이성은 (0,1,1)입니다.구체성에 영향을 미치지 않는 요소
구체성에 영향을 미치는 다음 요소에 관해 오해가 많은 부분이 있습니다.
본문 스타일 속성
요소의 style 속성에 직접 적용된 CSS는 특이도 전에 평가되는 캐스케이드의 다른 단계이므로 특이도에 영향을 주지 않습니다.
<div style="color: red"></div>
스타일 시트 내에서 이 선언을 재정의하려면 캐스케이드의 이전 단계에서 선언이 우선하도록 해야 합니다.
예를 들어 !important를 추가하여 제작된 !important 출처의 일부가 되도록 할 수 있습니다.
!important 선언
CSS 선언 끝에 있는 !important는 구체성에는 영향을 주지 않지만 선언을 다른 출처(작성된 !important)에 배치합니다.
다음 예시에서는 !important 선언이 우선하는 데 .my-class의 명시도가 관련이 없습니다.
.my-class {
color: red !important;
color: white;
}
두 선언이 !important인 경우 캐스케이드의 원본 단계에서 아직 승자를 결정할 수 없었으므로 다시 특이성이 적용됩니다.
.branding {
color: blue !important;
}
button {
color: red !important;
}
맥락의 구체성
복잡한 선택기나 복합 선택기를 사용하는 경우 선택기의 각 부분이 특이성에 합산됩니다. 다음 HTML을 살펴보세요.
<a class="my-class another-class" href="#">A link</a>
이 링크에는 두 개의 클래스가 있습니다.
다음 CSS의 규칙에는 특이도가 (0,0,1) 있습니다.
a {
color: red;
}
선택기에서 클래스 중 하나를 참조하는 경우 이제 구체성이 (0,1,1)입니다.
a.my-class {
color: green;
}
선택기에 다른 클래스를 추가합니다. 이제 구체성이 (0,2,1)이 됩니다.
a.my-class.another-class {
color: rebeccapurple;
}
선택기에 href 속성을 추가합니다. 이제 구체성이 (0,3,1)이 됩니다.
a.my-class.another-class[href] {
color: goldenrod;
}
마지막으로 이 모든 것에 :hover 가상 클래스를 추가하면 선택자의 구체성이 (0,4,1)이 됩니다.
a.my-class.another-class[href]:hover {
color: lightgrey;
}
이해도 테스트
특이성 점수 지정에 대한 지식 테스트
다음 중 선택기의 구체성이 (0,2,1)인 것은 무엇인가요?
article > section(0,0,2)입니다.article.card.dark(0,2,1)입니다.article:hover a[href](0,0,1)), 속성 선택기 ((0,1,0)), 클래스 선택기 ((0,1,0))가 있습니다. 따라서 이 선택기의 총 구체성은 (0,2,2)입니다.실용적으로 구체성 높이기
다음과 같은 CSS가 있다고 가정해 보겠습니다.
.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
다음과 같은 HTML을 사용합니다.
<button class="my-button" onclick="alert('hello')">Click me</button>
두 번째 선택기의 구체성이 (0,1,1)이므로 버튼의 배경이 회색입니다.
이는 (0,0,1)인 유형 선택기 (button)와 (0,1,0)인 속성 선택기 ([onclick])가 있기 때문입니다.
이전 규칙인 .my-button는 클래스 선택자가 하나이므로 (0,1,1)보다 구체성이 낮아 (0,1,0)와 같습니다.
이 규칙에 부스트를 적용하려면 다음과 같이 클래스 선택기를 반복하면 됩니다.
.my-button.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
이제 버튼의 배경이 파란색이 됩니다. 새 선택자가 (0,2,0)의 명시성을 갖기 때문입니다.
구체성에서 동점이면 캐스케이드의 다음 단계로 대체됩니다.
지금은 버튼 예시를 계속 사용하면서 CSS를 다음과 같이 전환합니다.
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
두 선택기의 특이도가 모두 (0,1,0)이므로 버튼의 배경이 회색입니다.
소스 순서에서 규칙을 전환하면 버튼이 파란색이 됩니다.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
두 선택기의 특이도가 동일하기 때문입니다. 이 경우 캐스케이드가 표시 순서 단계로 대체됩니다.