본문 바로가기
C.W.K.
Stream
Lesson 03 of 07 · published

CSS cascade layer로 우선순위 정하기

~12 min · css, layer, cascade, tailwind

Level 0React 입문자
0 XP0/54 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
CSS cascade layer를 사용하면 Tailwind 유틸리티와 직접 만든 스타일의 우선순위를 선택자 싸움 없이 정할 수 있어.

@layer는 cascade에 이름 있는 순서를 만들어

선택자의 구체성이 비슷할 때 어느 규칙이 이길지 파일 위치에만 맡기면 유지보수가 어려워. Layer를 사용하면 base, components, utilities처럼 규칙의 역할과 순서를 명시할 수 있어.

Tailwind의 계층에 맞춰 넣어

기본 엘리먼트 스타일은 base, 재사용하는 컴포넌트 클래스는 components, 작은 단일 목적 규칙은 utilities에 둬. 뒤쪽 utilities가 필요한 속성만 덮어쓸 수 있으므로 긴 선택자나 !important를 늘리지 않아도 돼.

컴포넌트 클래스는 묶음에 이름을 붙여

버튼의 여러 유틸리티가 자주 반복된다면 components layer에 .btn 같은 클래스를 둘 수 있어. 다만 한 번 쓰는 스타일까지 모두 추상화하지 말고, 여러 화면에서 같은 의미로 반복되는 묶음만 올려.

Layer는 구체성을 키우는 도구가 아니라 순서를 설명하는 도구야. CSS가 왜 이겼는지 선택자 계산 대신 구조로 읽히게 만들어.

Layer 순서는 선택자 구체성보다 먼저 적용돼

서로 다른 layer에 있는 두 규칙이 같은 속성을 정하면 뒤에 선언된 layer가 이겨. Components layer의 긴 선택자보다 utilities layer의 짧은 클래스가 우선할 수 있는 이유야. 같은 layer 안에서는 평소처럼 구체성과 소스 순서가 적용돼.

Tailwind의 기본 계층

Preflight와 기본 엘리먼트 규칙은 base에, 재사용할 카드와 버튼은 components에, 작은 단일 목적 클래스는 utilities에 둬. 호출자가 px-8을 추가해 컴포넌트의 기본 padding을 바꿀 수 있어야 한다면 기본 스타일을 components에 두는 편이 맞아.

외부 CSS도 layer로 위치를 정할 수 있어

서드파티 stylesheet를 낮은 layer에 import하면 직접 만든 components와 utilities가 예측 가능하게 덮어쓸 수 있어. 무작정 !important를 붙이기 전에 외부 규칙이 어느 layer에 있는지 확인해.

@layer components 안의 .btn에는 여러 화면에서 반복되는 기본 스타일만 두고, 한 화면의 특별한 배치는 JSX의 유틸리티로 남겨. 그래야 추상화가 의미를 보존해.

Code

@layer 컴포넌트 안의 커스텀 버튼 클래스·css
@import "tailwindcss";

@theme {
  --color-brand: #FF8FBE;
}

@layer components {
  /* 재사용할 기본 버튼이지만 호출자의 Tailwind utility로 바꿀 수 있어. */
  .btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    border-radius: 0.5rem;
    background: var(--color-brand);
    color: white;
    transition: opacity 0.15s;
  }
  .btn-primary:hover { opacity: 0.9; }

  /* JSX에서는 <button className="btn-primary">…</button>처럼 사용해.
     px-6를 더하면 utilities layer가 기본 padding을 덮어써. */
}
@keyframes 필요한 애니메이션·css
@layer utilities {
  /* @keyframes를 사용하는 utility class야. */
  .animate-pulse-brand {
    animation: pulse-brand 2s ease-in-out infinite;
  }
}

/* @keyframes 이름은 layer 밖에서도 공유되는 전역 식별자야. */
@keyframes pulse-brand {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.6; }
}

External links

Exercise

@layer components에 배경, 테두리, padding, 그림자를 가진 .card를 만들고 JSX에서 사용해. 같은 element에 p-8을 더해 utility가 기본 padding만 덮어쓰는지 DevTools의 cascade에서 확인해. 그다음 .card를 layer 밖으로 잠깐 옮겨 같은 utility가 더는 이기지 못하는 모습을 기록하고 원래 위치로 복원해.
Hint
Components layer는 utilities layer보다 앞에 있으므로 layer 안에서는 p-8이 이겨야 해. Layer 밖의 규칙은 layer 규칙보다 우선할 수 있다는 차이를 computed style과 선언 출처로 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.