🐨CoalaCoding
DocsExamplesTry itBoardB반
🐨CoalaCoding

개발자를 위한 한국어 웹 기술 문서

문서

  • JavaScript
  • Web Publishing
  • React
  • Python

커뮤니티

  • 게시판
  • 예제 모음
  • Try it 에디터

기타

  • GitHub
  • 관리자
© 2026 CoalaCoding. All rights reserved.
  • 01_Tailwind CSS
  • 02_ 레이아웃과 구조
  • 03_ 타이포그래피와 디자인
  • 04_ 컴포넌트와 UI 요소
  • 06_Tailwind at rule
  1. 홈
  2. 문서
  3. HTML & CSS
  4. Tailwind CSS
  5. 06_Tailwind at rule

06_Tailwind at rule

코드 블록의 Try it Yourself 버튼으로 직접 실행할 수 있다.

구문

1. 설명

Tailwind v4는 별도의 JS 설정 파일 없이 CSS 파일 하나로 모든 설정을 관리한다. 핵심 수단이 @ 지시어(at-rule)이다.


2. @import

Tailwind의 모든 기능을 불러오는 진입점이다. 반드시 CSS 파일의 최상단에 위치해야 한다.

@import "tailwindcss";

전체를 불러오지 않고 필요한 레이어만 선택적으로 불러올 수도 있다.

@import "tailwindcss/preflight";   /* 브라우저 기본 스타일 초기화 */
@import "tailwindcss/utilities";   /* 유틸리티 클래스만 */

파일 구조 권장 순서 @import → @plugin → @source → @theme → @utility → @variant → 컴포넌트


3. @theme

프로젝트 전체에서 사용할 디자인 토큰을 정의한다. CSS 변수 형태로 선언하면 Tailwind가 자동으로 유틸리티 클래스를 생성한다.

3.1. 기본 문법

@theme {
  --{카테고리}-{이름}: {값};
}

카테고리가 클래스 이름을 결정한다. 예를 들어 --color-*는 text-*, bg-*, border-* 등에 모두 적용된다.

3.2. 색상

@theme {
  --color-primary:      #f97316;
  --color-secondary:    #6366f1;
  --color-brand-light:  #fff7ed;
  --color-brand-dark:   #431407;
}
<style type="text/tailwindcss">
  @theme {
    --color-primary: #f97316;
    --color-secondary: #6366f1;
    --color-brand-light: #fff7ed;
    --color-brand-dark: #431407;
  }
</style>
<div class="bg-primary text-secondary border-brand-light"></div>

3.3. 폰트

@theme {
  --font-sans: "Pretendard", sans-serif;
  --font-mono: "JetBrains Mono", monospace;
}
<p class="font-sans">본문 텍스트</p>
<code class="font-mono">코드 블록</code>

3.4. 간격 (spacing)

@theme {
  --spacing-18:  4.5rem;  /* 72px  */
  --spacing-22:  5.5rem;  /* 88px  */
  --spacing-128: 32rem;   /* 512px */
}
<div class="mt-18 px-22 w-128"></div>

3.5. 브레이크포인트

@theme {
  --breakpoint-xs:  480px;
  --breakpoint-3xl: 1920px;
}
<div class="xs:flex 3xl:grid"></div>

3.6. 기타 토큰

@theme {
  --shadow-card:      0 4px 24px rgba(0,0,0,0.08);
  --radius-card:      1.25rem;
  --animate-spin-slow: spin 3s linear infinite;
}
<div class="shadow-card rounded-card animate-spin-slow"></div>

3.7. inline 키워드

일반 @theme은 빌드 시 값을 고정한다. inline을 붙이면 CSS 변수 참조를 런타임까지 유지한다. JS로 테마를 동적으로 변경해야 할 때 사용한다.

/* 빌드 시 #f97316으로 고정 */
@theme {
  --color-primary: #f97316;
}

/* 런타임에 --brand 값을 참조 */
@theme inline {
  --color-primary: var(--brand);
}
// 런타임에서 동적 변경 가능
document.documentElement.style.setProperty('--brand', '#6366f1');

3.8. 토큰 초기화

기본 제공 토큰을 전부 제거하고 처음부터 정의할 때 *: initial을 사용한다.

@theme {
  --color-*: initial;   /* 기본 색상 전체 제거 */
  --color-primary: #f97316;
  --color-gray:    #6b7280;
}

4. @source

Tailwind가 클래스를 스캔할 경로를 추가 지정한다.

@source "./src/**/*.{html,js,ts,jsx,tsx,vue,svelte}";
@source "../node_modules/@mylib/ui/src";

4.1. 언제 필요한가

  • 외부 패키지(node_modules)에 Tailwind 클래스가 있을 때
  • 모노레포 구조에서 다른 패키지 파일을 참조할 때
  • 자동 감지 범위 밖의 경로를 사용할 때

4.2. 동적 클래스 처리

JS에서 동적으로 생성되는 클래스명은 스캔되지 않는다. inline으로 안전 목록을 직접 명시한다.

@source inline("bg-red-500 bg-green-500 bg-blue-500");

5. @utility

Tailwind에 없는 유틸리티 클래스를 직접 만든다. 만든 클래스는 hover:, md:, dark: 등 모든 variant와 조합 가능하다.

5.1. 기본 예시

@utility scrollbar-hide {
  scrollbar-width: none;
  &::-webkit-scrollbar {
    display: none;
  }
}

@utility center {
  display: flex;
  align-items: center;
  justify-content: center;
}

@utility text-balance {
  text-wrap: balance;
}
<ul class="scrollbar-hide overflow-x-auto flex gap-4">...</ul>
<div class="center w-full h-screen">...</div>
<h1 class="text-balance text-4xl font-bold">...</h1>

5.2. variant와 조합

<div class="center md:block"></div>
<div class="dark:text-balance"></div>
<div class="hover:scrollbar-hide"></div>

5.3. 동적 값 수신

--value() 함수를 사용하면 클래스에서 값을 받을 수 있다.

@utility tab-* {
  tab-size: --value(--tab-size, integer);
}
<pre class="tab-2">...</pre>
<pre class="tab-4">...</pre>

6. @variant

Tailwind에 없는 커스텀 variant를 만든다. @slot은 실제 클래스 내용이 삽입되는 자리를 나타낸다.

6.1. 복합 상태

@variant hocus {
  &:hover,
  &:focus {
    @slot;
  }
}

@variant group-hocus {
  .group:hover &,
  .group:focus & {
    @slot;
  }
}
<button class="hocus:bg-primary hocus:text-white transition">
  버튼
</button>

<div class="group">
  <span class="group-hocus:underline">텍스트</span>
</div>

6.2. 미디어쿼리

@variant print {
  @media print { @slot; }
}

@variant landscape {
  @media (orientation: landscape) { @slot; }
}

@variant retina {
  @media (-webkit-min-device-pixel-ratio: 2) { @slot; }
}
<img class="w-full retina:w-1/2" src="...">
<nav class="hidden print:block">목차</nav>

6.3. 속성 기반

@variant selected {
  &[data-selected="true"] { @slot; }
}

@variant aria-expanded {
  &[aria-expanded="true"] { @slot; }
}
<li class="selected:bg-primary" data-selected="true">항목</li>
<button class="aria-expanded:rotate-180" aria-expanded="true">▼</button>

7. @plugin

외부 Tailwind 플러그인 또는 직접 만든 JS 플러그인을 불러온다.

@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";
@plugin "./plugins/my-plugin.js";

7.1. 공식 플러그인 사용 예시

<article class="prose prose-lg">
  <h1>제목</h1>
  <p>본문 내용...</p>
</article>

7.2. 커스텀 플러그인 작성

/* plugins/custom.js */
export default function({ addUtilities, addVariant }) {
  addUtilities({
    '.flex-center': {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
    }
  });

  addVariant('not-last', '&:not(:last-child)');
}
@plugin "./plugins/custom.js";
<div class="flex-center not-last:border-b">...</div>

8. @config

기존 tailwind.config.js를 CSS에서 참조한다. v4로 점진적으로 마이그레이션할 때 사용하며, 전환이 완료되면 제거한다.

@import "tailwindcss";
@config "../../tailwind.config.js";

@config와 @theme이 충돌하면 @theme이 우선한다.


9. @apply

CSS 규칙 안에서 Tailwind 유틸리티 클래스를 직접 적용한다.

.btn {
  @apply inline-flex items-center justify-center;
  @apply px-4 py-2 rounded-lg font-semibold transition-colors;
}

.btn-primary {
  @apply btn bg-primary text-white hover:bg-orange-600;
}

.btn-outline {
  @apply btn border border-primary text-primary;
  @apply hover:bg-primary hover:text-white;
}

.card {
  @apply bg-white rounded-card shadow-card p-6 space-y-4;
}

.input {
  @apply w-full px-3 py-2 rounded-lg border border-gray-300;
  @apply focus:outline-none focus:ring-2 focus:ring-primary;
  @apply placeholder:text-gray-400;
}
<button class="btn-primary">확인</button>
<button class="btn-outline">취소</button>

<div class="card">
  <input class="input" placeholder="이름을 입력하세요">
</div>

남용 주의 — @apply를 과도하게 사용하면 클래스만 보고 스타일을 파악하는 Tailwind의 장점이 사라진다. 반복적으로 조합되는 공통 컴포넌트에만 제한적으로 사용하는 것이 권장된다.


10. 전체 구조 예시

실제 프로젝트에서 CSS 파일을 구성하는 전형적인 형태이다.

/* src/styles/global.css */

/* 1. 진입점 */
@import "tailwindcss";

/* 2. 플러그인 */
@plugin "@tailwindcss/typography";

/* 3. 스캔 경로 */
@source "./src/**/*.{astro,html,js,ts,jsx,tsx}";

/* 4. 디자인 토큰 */
@theme {
  --color-primary:   #f97316;
  --color-secondary: #6366f1;
  --font-sans:       "Pretendard", sans-serif;
  --spacing-18:      4.5rem;
  --radius-card:     1.25rem;
  --shadow-card:     0 4px 24px rgba(0,0,0,0.08);
  --breakpoint-xs:   480px;
}

/* 5. 커스텀 유틸리티 */
@utility scrollbar-hide {
  scrollbar-width: none;
  &::-webkit-scrollbar { display: none; }
}

@utility center {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 6. 커스텀 variant */
@variant hocus {
  &:hover, &:focus { @slot; }
}

@variant print {
  @media print { @slot; }
}

/* 7. 컴포넌트 */
.btn {
  @apply inline-flex items-center justify-center;
  @apply px-4 py-2 rounded-lg font-semibold transition-colors;
}

목차

  • 구문