CSS를 오래 작성하다 보면 반드시 마주치는 문제가 있습니다. 바로 스타일 우선순위 충돌입니다. 외부 라이브러리의 스타일이 내 스타일을 덮어쓰거나, 컴포넌트 스타일이 글로벌 스타일과 충돌하는 상황 말이죠. 이를 해결하기 위해 !important를 남발하다 보면 코드는 금방 엉망이 됩니다.

CSS @layer는 이 문제를 우아하게 해결하는 현대적인 방법입니다.

CSS 캐스케이드 복습

브라우저가 어떤 스타일을 적용할지 결정하는 순서는 다음과 같습니다.

  1. 출처 (브라우저 기본값 < 작성자 스타일 < 사용자 스타일)
  2. 레이어 순서 ← @layer가 여기에 개입
  3. 명시도 (specificity)
  4. 작성 순서

@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 우선순위를 명시적으로 관리하는 도구입니다. 레이어 순서를 선언부에서 한 번에 제어하고, 외부 라이브러리는 레이어 안에 가두세요. !important와의 이별을 선언할 시간입니다.