CSS를 오래 작성하다 보면 반드시 마주치는 문제가 있습니다. 바로 스타일 우선순위 충돌입니다. 외부 라이브러리의 스타일이 내 스타일을 덮어쓰거나, 컴포넌트 스타일이 글로벌 스타일과 충돌하는 상황 말이죠. 이를 해결하기 위해 !important를 남발하다 보면 코드는 금방 엉망이 됩니다.
CSS @layer는 이 문제를 우아하게 해결하는 현대적인 방법입니다.
CSS 캐스케이드 복습
브라우저가 어떤 스타일을 적용할지 결정하는 순서는 다음과 같습니다.
- 출처 (브라우저 기본값 < 작성자 스타일 < 사용자 스타일)
- 레이어 순서 ← @layer가 여기에 개입
- 명시도 (specificity)
- 작성 순서
@layer 기본 사용법
레이어를 선언하고 각 레이어에 스타일을 배치합니다. 나중에 선언된 레이어가 더 높은 우선순위를 갖습니다.
/* 레이어 순서 먼저 선언 (선택 사항이지만 권장) */
@layer reset, base, components, utilities;
@layer reset {
*, *::before, *::after { box-sizing: border-box; margin: 0; }
}
@layer base {
body { font-family: sans-serif; color: #333; }
a { color: blue; }
}
@layer components {
.card { border: 1px solid #e5e7eb; border-radius: 0.75rem; }
.btn { padding: 0.5rem 1rem; border-radius: 0.4rem; }
}
@layer utilities {
.text-center { text-align: center; }
.mt-4 { margin-top: 1rem; }
}
이 예시에서 우선순위는 utilities > components > base > reset 순입니다.
외부 라이브러리 다루기
@layer의 진짜 강점은 외부 CSS를 레이어에 넣는 것입니다. 레이어 안의 스타일은 레이어 밖의 스타일보다 항상 낮은 우선순위를 갖습니다.
/* Bootstrap을 레이어에 가두기 */
@import url('bootstrap.css') layer(bootstrap);
/* 이제 내 스타일이 항상 Bootstrap을 이깁니다 */
.btn {
background-color: #6891f8; /* !important 없이도 적용됨 */
}
레이어 밖의 스타일은 모든 레이어보다 높은 우선순위를 가집니다. 즉, 레이어에 넣지 않은 내 커스텀 스타일은 항상 이깁니다.
중첩 레이어
레이어 안에 레이어를 만들 수도 있습니다. 디자인 시스템 구조화에 유용합니다.
@layer components {
@layer base {
.btn { padding: 0.5rem 1rem; }
}
@layer variants {
.btn-primary { background-color: #6891f8; color: white; }
.btn-danger { background-color: #ef4444; color: white; }
}
/* variants > base */
}
실전: Tailwind + 커스텀 CSS
Tailwind CSS와 함께 사용하면 유틸리티 클래스가 컴포넌트 스타일을 덮어쓰는 문제를 깔끔하게 해결할 수 있습니다.
/* Tailwind를 레이어에 가두기 */
@import "tailwindcss" layer(tailwind);
/* 내 컴포넌트 스타일 (레이어 밖 → 항상 이김) */
.card {
border-radius: 1rem;
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
}
브라우저 지원
Chrome 99+, Firefox 97+, Safari 15.4+ 이상에서 지원합니다. 2022년부터 모든 모던 브라우저가 지원하므로 실무에서 사용해도 안전합니다.
핵심 정리
@layer는 CSS 우선순위를 명시적으로 관리하는 도구입니다. 레이어 순서를 선언부에서 한 번에 제어하고, 외부 라이브러리는 레이어 안에 가두세요.
@layer는 CSS 우선순위를 명시적으로 관리하는 도구입니다. 레이어 순서를 선언부에서 한 번에 제어하고, 외부 라이브러리는 레이어 안에 가두세요.
!important와의 이별을 선언할 시간입니다.