CSS 적용 우선순위 끌어올리는 명시도, no-descending-specificity

최원빈·2022년 10월 18일
1

같은 요소에 같은 CSS속성이 여러번 중첩될 때, 우선적으로 적용되는 순서는 다음과 같다고 한다.

  • !important
  • <tag style="">
  • #id
  • .classname :pseudo-selector
  • tag { }
  • 상속된 속성

쉽게 말해서, 아래 예시와 같다.


지울때마다 바로 다음 우선순위가 적용되는 모습

모든 CSS를 해당 순서대로 적용시킨다면 좋겠지만, 사실상 저 선택자들을 전부 사용하는 것은 애플리케이션을 만들다보면 유지보수 측면에서, 팀이 맞춘 코드 컨벤션을 따라가다보면 4~6번 수준에서 관리하는 정도일것이다. (특히 React App을 만들다보면)

역시 문제는 우선순위가 같을 때인데, 같을 때는 명시도를 기준으로 우선순위를 정한다.


명시도

놀랍게도 MDN 문서에서 확인하라고 하는 링크 https://specifishity.com/

인라인 스타일과 important는 조금 예외로 두고,
나머지 사이의 관계를 잘 보자.

X - ID 선택자 (#id)
Y - Class 선택자, attribute 선택자, 가상 클래스 선택자 (.class , [type=value], :pesudo)
Z - element 선택자, 가상 요소 선택자 (::pesudo)

X - Y - Z 관계에서, Y가 아무리 많아도 X를, Z가 아무리 많아도 Y를 이길 수 없는 구조이다.
여러가지가 겹치는 Y나 Z가 어려울 수 있는데, 한번 다음 예시를 봐보자.

<div class="container">
  <div class="wrapper">
    <span>Span Text</span>
  </div>
</div>

<style>
.container .wrapper span {
  color: red;
}

.wrapper:hover {
  color: blue;
}
</style>

텍스트에 마우스를 가져갔을 때 텍스트는 파란색이 될까?


안된다.

위 사례를 들여다보면...
class는 Y, element명은 Z, 가상 선택자는 Y기 때문에 명시도 계산 결과는,
.container .wrapper span => 0-2-1
.wrapper:hover => 0-2-0
위와 같고, 명시도가 더 높은 위 CSS가 적용되게 된다.

그리고 명시도 점수가 같다면, 나중에 작성된 CSS가 적용된다.
위 예시에서 span을 제거하고, 테스트해보자.

같은 명시도는 나중에 선언된 것으로!

id나 inline-style, !important를 사용하지 않는다면, 우선순위를 끌어올리기 위해 명시도를 올릴 수 있도록 classname을 겹쳐쓰면 된다.

당연히, 위 예시의 두 CSS순서를 바꾸면 아무리 hover해도 색은 변하지 않을 것이다.


no-descending-specificity

처음엔 해당 StyleLint 오류가 왜 발생하는지 몰랐지만 이유를 알 수 있다.

겹치는 스타일은, 우선순위가 높을 때 뒤에 오게끔(재정의에 의해 덮어씌워질 때) 적어야 이해하기 쉽다.

.wrapper:hover {
  color: red;
}

/* blue -> red로 재정의되는 스타일 */
/* lint Error! */
.wrapper {
  color: blue;
}

위에서부터 읽으니, 당연히 재정의도 밑에 있는게 잘 읽히긴 한다.

명시도를 조작하다보면 해당 스타일린트 오류를 마주칠 일이 꽤 있을텐데, 잘 알아두고 명시도를 계산해서 쓰면 쉽게 해결할 수 있을 것이다.

profile
FrontEnd Developer

0개의 댓글