특수성

CSS 팟캐스트 - 003: 특정성

다음 HTML 및 CSS를 사용한다고 가정해 보겠습니다.

<button class="branding">Hello, Specificity!</button>
.branding {
  color: blue;
}

button {
  color: red;
}

여기에는 동일한 요소를 타겟팅하는 두 가지 규칙이 있습니다. 각 규칙에는 버튼의 색상을 설정하려는 선언이 포함되어 있습니다. 하나는 버튼을 빨간색으로 설정하려 하고 다른 하나는 파란색으로 설정하려 합니다. 요소에 적용되는 선언은 무엇인가요?

CSS 특수성 알고리즘을 이해하는 것은 CSS가 경쟁하는 선언 간에 결정하는 방식을 이해하는 데 중요합니다.

구체성은 이전 모듈의 계단식 구조에서 다룬 계단식 구조의 고유한 단계 중 하나입니다.

특이점 점수

출처 내의 각 선택기 규칙은 점수를 받습니다. 특이성은 총점으로 생각할 수 있으며 각 선택기 유형은 해당 점수에 점수를 부여합니다. 구체성이 가장 높은 규칙의 선언이 우선 적용됩니다.

실제 프로젝트의 경우 적용할 것으로 예상되는 CSS 규칙이 실제로 적용되는지 확인하는 동시에 복잡성을 방지하기 위해 일반적으로 점수를 낮게 유지하는 것이 중요합니다. 특이성은 최대한 높게 하는 것이 아니라 필요한 만큼만 높아야 합니다. 향후 더 중요한 CSS를 적용해야 할 수도 있습니다. 가장 높은 특이성을 추구하면 작업이 어려워집니다.

특이성은 소수점이 아닌 A, B, C의 세 가지 구성요소로 구성된 삼중항입니다.

  • A: ID와 유사한 특정성
  • B: 클래스와 같은 특정성
  • C: 요소와 유사한 특정성

(A,B,C) 표기법을 사용하여 표현되는 경우가 많습니다. 예를 들면 (1,0,2)입니다. 대체 A-B-C 표기법도 일반적으로 사용됩니다.

특이성의 세 가지 구성요소 (A,B,C)를 보여주는 다이어그램 다이어그램은 각 구성요소가 나타내는 항목과 구성요소에 영향을 미치는 일부 선택자 예시를 보여줍니다.
다양한 선택기가 특이성의 어떤 구성요소에 영향을 미치는지 보여주는 다이어그램입니다.

구체적인 내용 비교

특이성은 세 구성요소를 순서대로 비교하여 비교합니다. A 값이 더 큰 특이성이 더 구체적입니다. 두 A 값이 동일한 경우 B 값이 더 큰 특이성이 더 구체적입니다. 두 B 값도 동일한 경우 C 값이 더 큰 특이성이 더 구체적입니다. 모든 값이 동일한 경우 두 특이성은 같습니다.

예를 들어 (1,0,0)A 값 (1)이 (0,4,3)A 값 (0)보다 크기 때문에 (1,0,0)(0,4,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="myID"])가 아닌 ID 선택기 (#myID)를 사용하는 경우 C 구성요소를 1씩 증가시키는 ID와 유사한 특정성을 추가합니다.

다음 예에서 특이성은 (1,0,0)입니다.

#myID {
  color: red;
}

기타 선택기

CSS에는 여러 선택자가 있습니다. 하지만 모든 단어가 구체적인 것은 아닙니다. 예를 들어 :not() 가상 클래스 자체는 특정도 계산에 아무것도 추가하지 않습니다.

그러나 인수로 전달된 선택자는 특정도 계산에 추가됩니다.

div:not(.my-class) {
  color: red;
}

이 샘플은 유형 선택기(div) 1개와 :not() 내부에 클래스 1개가 있으므로 특이성이 (0,1,1)입니다.

이해도 확인

특이도 점수에 대한 지식 테스트

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,1)이므로 총 특이성은 (0,1,1)입니다.

특이성에 영향을 미치지 않는 요인

다음과 같은 특이성에 영향을 미치는 요소에 관해 오해가 많습니다.

본문 스타일 속성

요소의 style 속성에 직접 적용된 CSS는 특이성 전에 평가되는 캐스케이드의 다른 단계이므로 특이성에 영향을 미치지 않습니다.

<div style="color: red"></div>

스타일 시트 내에서 이 선언을 재정의하려면 캐스케이드의 이전 단계에서 선언 낙찰을 가져와야 합니다.

예를 들어 !important를 추가하여 작성된 !important 출처의 일부가 되도록 할 수 있습니다.

선언 !important

CSS 선언 끝에 있는 !important는 특이성에 영향을 미치지 않지만 선언을 다른 출처, 즉 작성된 !important에 배치합니다.

다음 예에서 .my-class의 특이성은 !important 선언이 낙찰되는 것과 관련이 없습니다.

.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
요소는 요소와 같은 특정성 (`C` 구성요소)을 추가합니다. 선택기에는 2개의 요소가 있으므로 특이성은 (0,0,2)입니다.
article.card.dark
요소는 요소와 같은 특정성을 추가하고('C' 구성요소) 클래스는 클래스와 같은 특정성을 추가합니다('B' 구성요소). 클래스 2개와 요소 1개가 있으므로 이 선택기의 특이도는 (0,2,1)입니다.
article:hover a[href]
요소는 요소와 같은 특정성 (`C` 구성요소)을 추가하고, 가상 클래스와 속성은 클래스와 같은 특정성 (`B` 구성요소)을 추가합니다. 요소 선택기 2개 (2 × (0,0,1)), 속성 선택기 (값: (0,0,1)), 클래스 선택기 (값: (0,0,1))가 있습니다. 따라서 이 선택기의 총 특이성은 (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) 1개와 (0,1,0) 속성 선택기 ([onclick]) 1개가 있기 때문입니다.

이전 규칙인 .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;
}

두 선택기의 특이도가 동일하기 때문입니다. 이 경우 계단식 적용은 출현 순서 단계로 대체됩니다.

리소스