안녕하세요! 프론트엔드 강사입니다. 오늘은 CSS의 최신 기능 중 하나인 '중첩(Nesting)'을 사용할 때, 그 악명 높은 '명시도(Specificity)'가 대체 어떻게 계산되는지에 대해 공식 문서를 통해 꼼꼼히 살펴볼게요.
실무에서 CSS를 작성하다 보면 "어? 왜 내가 방금 쓴 스타일이 안 먹히지?" 하는 경우가 많은데, 십중팔구는 이 명시도 점수 싸움에서 밀렸기 때문이거든요. 공식 문서의 내용을 있는 그대로 번역하면서, 중간중간 제가 겪었던 경험과 꿀팁들을 더해서 아주 쉽게 이해할 수 있도록 도와드릴게요! 자, 시작하겠습니다.
& 중첩 선택자(nesting selector)의 명시도(specificity)는 이와 연결된 선택자 목록 내에서 가장 높은(큰) 명시도를 사용하여 계산됩니다. 이것은 :is() 함수를 사용할 때 명시도가 계산되는 방식과 완전히 똑같습니다.
👨🏫 강사님의 꿀팁 & 보충설명:
'명시도(Specificity)'란 브라우저가 어떤 스타일을 우선적으로 적용할지 결정하는 '점수'라고 생각하시면 편해요! ID 선택자는 100점(1-0-0), 클래스는 10점(0-1-0), 태그는 1점(0-0-1) 같은 식으로 점수를 매기죠.
여기서 문서가 말하는 핵심은 이겁니다.&기호를 사용해서 선택자들을 묶었을 때,&는 자기가 대신하고 있는 부모 선택자들 중에서 '가장 점수가 높은 녀석의 점수'를 자기 점수로 그대로 가져온다는 거예요!
<b class="foo">
<i>Blue text</i>
</b>
& 중첩 구문 (& nesting syntax)#a, b {
& i {
color: blue;
}
}
.foo i {
color: red;
}
👨🏫 강사님의 꿀팁 & 보충설명:
코드를 잠깐 볼까요? HTML을 보면<b class="foo">태그 안에<i>태그가 있습니다.
CSS 첫 번째 블록을 보면,#a와b를 쉼표로 묶어놓고 그 안에& i로 파란색을 줬네요.
두 번째 블록은.foo i에 빨간색을 줬습니다.
둘 다 똑같이 저<i>태그를 가리키는데, 과연 글자는 무슨 색이 될까요? 다음 섹션에서 정답과 이유를 알아봅시다!
:is() 구문 (:is() syntax):is(#a, b) {
& i {
color: blue;
}
}
.foo i {
color: red;
}
이 예제에서, id 선택자(#a)는 1-0-0의 명시도를 가지고 있고, 반면에 타입 선택자(b)는 0-0-1의 명시도를 가집니다. & 중첩 선택자와 :is() 가상 클래스(pseudo-class) 둘 다, 비록 실제 요소에는 #a라는 id 선택자가 사용되지 않았음에도 불구하고, 1-0-0이라는 (가장 높은) 명시도를 가져가게 됩니다.
.foo 클래스 선택자는 0-1-0의 명시도를 가집니다. 이것은 전체 명시도를 더해봤을 때 & i의 경우는 1-0-1 (id 명시도 1 + 태그 명시도 1)이 되고, .foo i의 경우는 0-1-1 (클래스 명시도 1 + 태그 명시도 1)이 된다는 것을 의미합니다. 즉, 점수가 더 높은 color: blue;가 승리하게 됩니다.
👨🏫 강사님의 꿀팁 & 보충설명:
정답은 '파란색'이었습니다! 이 부분이 실무에서 개발자들이 진짜 많이 당황하는 포인트예요.
보통 우리는 속으로 "어? 내 HTML 요소에는#a라는 ID가 없잖아? 그냥b태그일 뿐이지. 그러면#a, b중에서 매칭되는 건b니까 태그 점수 1점(0-0-1)만 가져가겠네?" 라고 착각하기 아주 쉽습니다.하지만 브라우저 엔진은 그렇게 계산하지 않아요! 쉼표로 묶인 선택자(
#a,b) 중에서 실제로 HTML에 그 속성이 있든 없든 상관없이, 무조건 제일 힘이 센 녀석의 점수(#a의 1-0-0)를 대표 명시도로 쓱 가져와 버립니다.
그래서 우리가 의도치 않게 명시도가 엄청나게 높아져(뻥튀기되어) 버리는 현상이 발생하죠. 나중에 코드를 유지보수할 때.foo i같은 클래스로 스타일을 덮어씌우려고 해도 덮어씌워지지 않는 지옥(?)을 맛볼 수 있습니다.
Sass나 SCSS를 사용하다가 최근 도입된 네이티브 CSS Nesting으로 넘어오시는 분들이라면 이:is()기반의 점수 계산법을 꼭 명심하셔야 합니다!
조금 더 깊게 공부하고 싶으시다면 아래 링크들을 꼭 확인해 보세요!
& 중첩 선택자 (& nesting selector)이 페이지가 도움이 되었나요? (Was this page helpful to you?)
[예 (Yes)]
[아니요 (No)]
이 페이지는 MDN 기여자들에 의해 2025년 11월 7일에 마지막으로 수정되었습니다.
오늘 학습은 여기까지입니다! CSS 중첩을 다루실 때 명시도가 꼬이지 않도록 항상 주의하시고, 더 궁금한 점이 생기면 언제든지 강사에게 물어봐주세요. 파이팅!