WeniVooks

검색

HTML/CSS 에센셜

선택자 우선순위

CSS는 여러 선택자를 사용하기 때문에 한 개의 요소를 다양하게 표현할 수 있고, 여러 스타일이 적용될 수 있습니다. 이 때, 동일한 속성을 작성하면 스타일이 충돌할 수 있는데 어떤 스타일을 적용할지 결정하는 규칙이 존재합니다. 어떤 스타일을 적용할지를 정하는 우선순위 체계가 있으며, 이를 선택자 우선 순위라고 합니다.

CSS 선택자 우선순위는 크게 세 가지 원칙을 따릅니다.

  1. 후자 우선의 원칙
  2. 구체성(명시도)의 원칙
  3. 중요성의 원칙

1. 후자 우선의 원칙

CSS에서는 동일한 선택자에 동일한 속성이 여러 번 정의될 경우, 가장 마지막에 정의된 스타일이 적용됩니다. 이를 '후자 우선의 원칙' 이라고 합니다.

위 코드에서 color: blue; 보다 color: red;가 나중에 작성되었기 때문에, 모든 <p> 요소의 텍스트 색상은 가장 마지막에 정의된 스타일인 빨간색이 됩니다.

2. 구체성(명시도, Specificity)의 원칙

구체성, 또는 명시도는 선택자가 얼마나 구체적으로 요소를 지정하는지를 나타냅니다. 더 구체적인 선택자가 덜 구체적인 선택자보다 우선순위가 높습니다.

2.1 가중치 계산 방법

구체성은 다음과 같은 가중치로 계산됩니다.

선택자가중치 점수
inline-style1000점
id #100점
class ., 속성 선택자, 가상 클래스10점
타입 선택자, 가상요소 선택자1점
전체 선택자 *0점

이 경우, #container p가 가장 구체적이므로, 텍스트 색상은 파란색이 됩니다.

2.2 구체성 계산 예시
* { }                   /* 구체성: 0 */
li { }                  /* 구체성: 1 (요소 선택자) */
li:first-child { }      /* 구체성: 11 (1 + 10) */
ul li { }               /* 구체성: 2 (1 + 1) */
ul ol+li { }            /* 구체성: 3 (1 + 1 + 1) */
h1 + *[rel=up] { }      /* 구체성: 11 (1 + 10) */
ul ol li.red { }        /* 구체성: 13 (1 + 1 + 1 + 10) */
li.red.level { }        /* 구체성: 21 (1 + 10 + 10) */
#x34y { }               /* 구체성: 100 (ID 선택자) */
style=""                /* 구체성: 1000 (인라인 스타일) */
* { }                   /* 구체성: 0 */
li { }                  /* 구체성: 1 (요소 선택자) */
li:first-child { }      /* 구체성: 11 (1 + 10) */
ul li { }               /* 구체성: 2 (1 + 1) */
ul ol+li { }            /* 구체성: 3 (1 + 1 + 1) */
h1 + *[rel=up] { }      /* 구체성: 11 (1 + 10) */
ul ol li.red { }        /* 구체성: 13 (1 + 1 + 1 + 10) */
li.red.level { }        /* 구체성: 21 (1 + 10 + 10) */
#x34y { }               /* 구체성: 100 (ID 선택자) */
style=""                /* 구체성: 1000 (인라인 스타일) */

글자와 배경색은 어떻게 나타낼까요?

<main>
  <section>
    <article>
      <div>
        <ul class="ul">
          <li>
            <p>
              <strong>
                <span>
                  <a href="#" class="click">
                    1. 이 글자는 어떤 색일까요? 2. 배경색은 어떤 색일까요?
                  </a>
                </span>
              </strong>
            </p>
          </li>
        </ul>
      </div>
    </article>
  </section>
</main>
<main>
  <section>
    <article>
      <div>
        <ul class="ul">
          <li>
            <p>
              <strong>
                <span>
                  <a href="#" class="click">
                    1. 이 글자는 어떤 색일까요? 2. 배경색은 어떤 색일까요?
                  </a>
                </span>
              </strong>
            </p>
          </li>
        </ul>
      </div>
    </article>
  </section>
</main>
/* 클래스 + 유형 선택자 */
.ul a {
  color: yellow;
}
 
/* 클래스 선택자 */
.click {
  color: green;
  background: black;
}
 
/* 유형 선택자 */
html body main section article div ul li p strong span a {
  background: purple;
  color: blue;
}
/* 클래스 + 유형 선택자 */
.ul a {
  color: yellow;
}
 
/* 클래스 선택자 */
.click {
  color: green;
  background: black;
}
 
/* 유형 선택자 */
html body main section article div ul li p strong span a {
  background: purple;
  color: blue;
}

글자는 노란색, 배경은 검은색이 적용된 것을 확인할 수 있습니다. 클래스 + 유형은 (10 + 1), 클래스는 (10), 유형은 (1+1+1+1+1+1+1+1+1+1)이기 때문에 유형 선택자가 클래스 선택자보다 커보이지만, 유형 선택자의 가중치는 클래스 선택자보다 우선될 수 없습니다. 클래스의 가중치를 먼저 비교하고, 다음으로 유형 선택자의 가중치를 비교합니다. 마치 은메달이 아무리 많아도 금메달 1개를 이길 수 없는 것과 같죠. 다음 명시도 계산기와 그림을 확인해서 우선순위가 어떻게 계산되는지 확인해보세요.

명시도 계산기 사이트그림으로 알아보는 명시도

3. 중요성의 원칙

!important 선언은 다른 모든 선언보다 우선합니다. 이는 매우 강력한 도구이지만, 남용하면 CSS의 예측 가능성과 유지보수성을 해칠 수 있습니다. !important 는 선택자 우선순위에 직접적인 영향을 미칩니다.

!important 사용은 좋지 못한 습관입니다.

!important는 CSS의 자연스러운 상속을 깨트리기 때문에 오류/버그 발생 시 수정을 어렵게 만듭니다. 다음과 같은 상황에 제한적으로 사용하는 것을 권장합니다.

  1. 외부 라이브러리의 CSS를 재정의해야 할 때
  2. 유틸리티 클래스가 항상 적용되도록 보장해야 할 때 (예: .hidden { display: none !important; })

일반적인 스타일링에서는 우선순위가 높은 선택자를 사용하는 것이 바람직합니다.

4. 스타일의 우선순위는?

CSS에서 스타일이 충돌할때는 이 3가지 규칙이 다음과 같은 순서로 적용됩니다.

  1. 중요성의 원칙: !important가 있는 선언 우선 (!important)
  2. 구체성의 원칙: 더 구체적인 선택자가 우선
  3. 후자 우선의 원칙: 같은 구체성을 가진 경우 나중에 선언된 스타일이 우선
10.2 복합 선택자10.4 네이밍 규칙