노트

CSS @layer

Cascade Layers

프론트엔드#css · 연결된 개념 4개

쉽게 말하면

CSS @layer는 스타일 규칙을 리그처럼 나누고 리그끼리 순위를 먼저 정해 두는 기능이에요. 상위 리그 규칙은 하위 리그 규칙이 아무리 구체적이어도 이기니까 명시도 싸움을 할 필요가 없죠.

비유의 한계 직관과 다른 점이 둘 있어요. 어느 레이어에도 안 넣은 규칙이 모든 레이어보다 강하고, !important가 붙으면 순서가 뒤집혀 먼저 선언된 레이어가 이겨요.

CSS 규칙을 이름 붙인 묶음(레이어)으로 나누고, 묶음 사이의 우선순위를 명시적으로 정하는 기능. CSS Cascade Level 5 명세에서 캐스케이드에 새 단계로 들어왔고, 명시도보다 먼저 평가된다.

@layer base, components, utilities; /* 뒤에 선언할수록 강함 */
 
@layer base {
  #app .box { color: red; }  /* 명시도가 훨씬 높아도 */
}
@layer utilities {
  .box { color: blue; }      /* 레이어가 뒤라서 이김 */
}

핵심 규칙

  • 레이어 순서는 처음 선언된 순서로 정해진다. 맨 위에 @layer a, b, c;처럼 순서만 먼저 적어 두는 것이 관례다
  • 레이어에 속하지 않은 규칙(unlayered)은 모든 레이어보다 강하다. "레이어에 넣을수록 약해진다"고 기억하면 된다
  • !important가 붙으면 순서가 뒤집힌다. 먼저 선언된 레이어가 이기고, 레이어 안의 !important가 레이어 밖의 !important보다 강하다
비교일반 선언!important
레이어 vs 레이어 밖레이어 밖 승레이어 승
앞 레이어 vs 뒤 레이어뒤 레이어 승앞 레이어 승

쓰는 곳

  • 오래된 전역 리셋이나 서드파티 CSS처럼 명시도가 높은 규칙을 약한 레이어에 가두면, 유틸리티 클래스(Utility Class)가 명시도 싸움 없이 이긴다. 이때 가둔 규칙에 !important가 남아 있으면 위 표대로 오히려 이겨 버리니 함께 정리해야 한다
  • Tailwind v4는 출력 CSS를 theme, base, components, utilities 레이어로 나눈다(2026 기준). 직접 만든 컴포넌트 클래스를 @layer components에 넣으면 유틸리티로 덮어쓸 수 있고, 레이어 밖에 두면 유틸리티보다 강해진다
  • 리셋을 가장 앞 레이어에 두는 것도 흔한 구성이다

Tailwind v4와 직접 만든 레이어

@import "tailwindcss";는 맨 앞에 @layer theme, base, components, utilities;를 선언하고 유틸리티를 utilities 레이어에 넣는다(2026 기준). 유틸리티는 레이어 밖(unlayered)이 아니다. 그래서 직접 만든 레이어가 유틸리티보다 약한지 강한지는 그 레이어가 처음 선언된 위치로 정해진다.

  • Tailwind import 뒤에서 @layer legacy { … }를 처음 쓰면 legacy는 utilities 뒤에 붙는다. 그러면 유틸리티를 이긴다
  • 유틸리티보다 약하게 가두려면 import보다 먼저 전체 순서를 적는다. @layer 선언문(블록이 아닌 것)은 @import보다 앞에 올 수 있다
  • 같은 이름을 다시 선언해도 순서는 바뀌지 않으므로, Tailwind가 뒤에서 같은 순서를 다시 선언해도 괜찮다
@layer theme, base, legacy, components, utilities; /* 순서를 먼저 정한다 */
@import "tailwindcss";
 
@layer legacy {
  .promo p { font-family: serif; } /* 명시도 (0,1,1) */
}
<div class="promo">
  <!-- font-sans: Tailwind가 만든 유틸리티 클래스. utilities 레이어에 있고 명시도 (0,1,0) -->
  <p class="font-sans">…</p>
</div>

.promo p는 명시도가 더 높지만 legacy가 utilities보다 앞 레이어라 진다. 문단은 font-sans 글꼴로 나온다.

명세: CSS Cascade 5 §6.4.3 — Layer Ordering · CSS Cascade 5 §6.4.4.2 — Declaring Without Styles: the @layer statement 출처: MDN — Cascade layers: Cascade layer precedence order · MDN — @layer · Tailwind CSS — Preflight · Tailwind CSS — font-family · Tailwind CSS — Adding custom styles: Simple utilities

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • Sass와 PostCSS

    둘 다 CSS를 변환하는 빌드 도구지만 출발점이 다르다. Sass(Syntactically Awesome Style Sheets)는 자기 언어(SCSS, Sassy CSS)를 CSS로 번역하는 전처리기(Preprocessor)이고, PostCSS는 표준 CSS를 받아 플러그인 체인으로 변환하는 도구다.

  • CSS-in-JS와 빌드 타임 CSS

    JS(JavaScript) 안에서 스타일을 정의하고, 렌더링할 때 라이브러리가 클래스를 만들어 style 태그로 주입하는 방식. styled-components와 Emotion이 대표다. React 18 이후 서버 컴포넌트(React Server Components)·스트리밍 SSR(Streaming Server-Side Rendering)이 자리 잡으면서 런타임에 CSS를 만드는 방식은 줄고, 빌드할 때 CSS를 뽑는 방식이 늘었다(2026 기준).

  • tailwind-merge와 cn()

    같은 CSS 속성을 건드리는 Tailwind 클래스가 여러 개 붙었을 때, 뒤에 온 것만 남기고 앞의 것을 지워 주는 라이브러리. 컴포넌트의 기본 클래스를 사용처에서 덮어쓰는 패턴을 안전하게 만든다.

  • 쌓임 순서와 z-index

    요소가 겹칠 때 무엇이 위에 보일지 정하는 규칙. z-index가 없을 때도 정해진 기본 순서가 있고, z-index는 같은 쌓임 맥락(Stacking Context) 안에서만 비교된다.

  • cn 유틸리티(clsx·tailwind-merge·cva)

    cn()은 shadcn/ui 등에서 쓰는 클래스 이름 조합 함수로, clsx와 tailwind-merge를 합친 한 줄짜리 유틸리티다. 여기에 cva로 컴포넌트 변형(Variant)을 정의하면 Tailwind 기반 컴포넌트 API(Application Programming Interface)가 완성된다.

보기 옵션