CSS 스타일 규칙을 중첩하면 스타일시트를 더 체계적으로 정리하고, 더 쉽게 읽고, 더 쉽게 유지관리할 수 있습니다.
개요
선택기에 대해 알아보았으니 스타일시트에서 선택기를 더 잘 정리하는 방법을 궁금해하실 것입니다. 사이트의 '기능' 섹션 내 항목에 스타일을 적용한다고 가정해 보겠습니다. 중첩을 사용하면 다음과 같이 .feature
규칙 내에서 이러한 스타일을 그룹화할 수 있습니다.
.feature {
button {
color: blue;
}
.link {
color: red;
}
.text {
font-size: 1.3em;
}
}
이는 각 스타일을 별도로 작성하는 것과 같습니다.
.feature button {
color: blue;
}
.feature .link {
color: red;
}
.feature .text {
font-size: 1.3em;
}
필요한 만큼 여러 계층으로 중첩할 수 있습니다.
.feature {
.heading {
color: blue;
a {
color: green;
}
}
}
그룹화 및 관계 설정
중첩을 사용하면 스타일 규칙을 더 간결하게 그룹화하고 스타일 규칙 간의 관계를 설정할 수 있습니다.
중첩된 규칙은 기본적으로 하위 요소 결합자로 외부 규칙과 관련됩니다. 중첩된 규칙에서 선택기를 사용하여 관계를 변경합니다.
/* targets headings that are siblings of the .feature element and come immediately after it */
.feature {
+ .heading {
color: blue;
}
/* targets all paragraphs that are direct children of the .feature element */
> p {
font-size: 1.3em;
}
}
&
선택기로 명시적 관계 정의
스타일 규칙을 중첩할 때 &
선택기를 사용하여 더 명시적으로 지정할 수도 있습니다. &
는 상위 선택기를 나타내는 기호라고 생각하면 됩니다.
.feature {
& button {
color: blue;
}
}
이는 다음과 같이 스타일을 작성하는 것과 같습니다.
.feature button {
color: blue;
}
&
가 필요한 경우
&
가 없으면 중첩된 선택기는 상위 선택기의 하위 선택기가 됩니다. 복합 선택기를 구성하려면 &
이 필요합니다.
.feature {
&:last-child {
/* Selects the .feature element that is the :last-child, equivalent to .feature:last-child */
}
& :last-child {
/* Selects the :last-child inside of a .feature element, equivalent to .feature :last-child */
}
&.highlight {
/* Selects .feature elements that also have a .highlight class, equivalent to .feature.highlight */
}
& .highlight {
/* Selects elements inside of the .feature element with the class .highlight, equivalent to .feature .highlight */
}
}
컨텍스트를 변경하고 &
선택기를 자녀 선택기 끝에 배치하거나 양쪽에 배치할 수도 있습니다.
/* Targets buttons with an adjacent sibling button */
button {
& + & {
/* … */
}
}
img {
.my-component & {
/* styles for images inside of `.my-component` ... */
}
}
마지막 예에서는 .my-component
클래스가 있는 요소 내 이미지의 스타일을 추가합니다. 요소에 class
또는 id
을 추가할 수 없는 프로젝트를 작업하는 경우 유용합니다.
중첩 및 구체성
:is()
와 마찬가지로 중첩 선택기는 상위 선택기 목록에서 가장 높은 구체성을 가진 선택기의 구체성을 사용합니다.
#main-header,
.intro {
& a {
color: green;
}
}
.intro a {
color: blue;
}
첫 번째 규칙은 #main-header
및 .intro
요소 내의 모든 링크를 타겟팅하여 녹색을 지정합니다.
두 번째 규칙은 .intro
요소 내의 링크를 파란색으로 만들기 위해 이를 재정의하려고 합니다.
각 규칙의 구체성을 살펴보면 작동하지 않는 이유를 알 수 있습니다.
/* equivalent to :is(#main-header, .intro) a with a specificity of (1, 0, 1) */
#main-header,
.intro {
& a {
color: green;
}
}
/* lower specificity of (0, 1, 1) */
.intro a {
color: blue;
}
첫 번째 규칙의 선택기 목록에 id
이 있고 중첩된 규칙은 선택기 중 가장 구체적인 선택기의 구체성을 취하므로 두 번째 규칙보다 구체성이 높습니다. #main-header
선택자가 있는 요소 내에 있지 않은 a
요소의 경우에도 링크가 녹색입니다.
잘못된 중첩
:is()
와 마찬가지로 중첩 선택기는 가상 요소를 나타낼 수 없습니다.
blockquote, blockquote::before, blockquote::after {
color: navy;
& {
border: 1px solid navy;
}
}
blockquote
와 그 의사 요소 모두 navy
색상의 텍스트와 테두리가 있을 것으로 예상되지만 그렇지 않습니다. &
선택기는 가상 요소를 나타낼 수 없으므로 중첩된 테두리 스타일은 인용구에만 적용됩니다.
&
및 유형 선택자를 사용하여 복합 선택자를 만들 때는 유형 선택자가 먼저 나와야 하며 그 사이에 공백이 없어야 합니다.
/* valid css nesting */
.feature {
p& {
font-weight: bold;
}
}
/* invalid css nesting */
.feature {
&p {
font-weight: bold;
}
}
이 규칙을 사용하면 CSS 중첩이 Sass와 같은 사전 처리 도구와 함께 작동할 수 있습니다. Sass에서 &p
를 작성하면 상위 선택기가 중첩된 유형 선택기에 추가되고 결과는 .featurep
가 됩니다.
at-rule 중첩
@container
, @media
, @supports
, @layer
와 같은 CSS 조건부 그룹 규칙도 중첩될 수 있습니다.
.feature {
@media (min-width: 40em) {
/* ... */
}
@container (inline-size > 900px) {
/* ... */
}
}
.feature {
@supports (display: grid) {
/* ... */
}
}
.feature {
@layer component {
h2 {
/* ... */
}
}
}
이해도 확인
CSS Nesting을 사용할 때 &
선택자는 무엇을 나타내나요?
두 단계까지만 중첩할 수 있습니다.
어떤 @규칙을 중첩할 수 있나요?
@media
@container
@import
@supports
@layer