중첩

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
정답입니다.