긴 알파 기간을 거쳐 마침내 Tailwind CSS v4.0을 베타 버전으로 출시하게 되어 기쁩니다!

아직 개선해야 할 부분이 있고 다듬어야 할 부분도 있지만, 이제부터 안정 버전 출시까지는 더 이상의 호환성 문제를 일으키는 변경은 없을 것이라고 확신합니다.

이 문서는 아직 작업 중이며, 베타 기간 동안 계속해서 개선할 예정입니다. 하지만 여러분이 시작하는 데에는 충분한 내용을 담고 있습니다.

문제가 발생하면 GitHub에서 알려주세요. 몇 달 후 안정 버전 출시를 위해 철저히 검토하겠습니다.


시작하기

Vite로 설치하기

Vite나 SvelteKit, Remix 같은 Vite 기반 프레임워크를 사용 중이라면, Tailwind와 함께 새로운 Vite 전용 플러그인을 설치하세요.

Terminal
$ npm install tailwindcss@next @tailwindcss/vite@next

그 다음, vite.config.ts 파일에 Vite 플러그인을 추가하세요.

vite.config.ts
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [
    tailwindcss()
  ],
});

마지막으로, 메인 CSS 파일에 Tailwind를 불러오세요.

src/index.css
@import "tailwindcss";

PostCSS와 함께 설치하기

여러분의 프로젝트가 PostCSS를 사용하거나 Next.js와 같은 PostCSS 플러그인을 지원하는 프레임워크를 사용 중이라면, 새로운 전용 PostCSS 플러그인과 함께 Tailwind를 설치할 수 있습니다.

Terminal
$ npm install tailwindcss@next @tailwindcss/postcss@next

다음으로, postcss.config.mjs 파일에 PostCSS 플러그인을 추가합니다.

postcss.config.mjs
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};

마지막으로, 메인 CSS 파일에 Tailwind를 임포트합니다.

app.css
@import "tailwindcss";

CLI 설치하기

전용 CLI 도구를 사용하려면 Tailwind와 새로운 전용 CLI 패키지를 함께 설치하세요:

Terminal
$ npm install tailwindcss@next @tailwindcss/cli@next

다음으로, 메인 CSS 파일에 Tailwind를 임포트하세요:

app.css
@import "tailwindcss";

그런 다음 CLI 도구를 사용해 CSS를 컴파일하세요:

Terminal
$ npx @tailwindcss/cli -i input.css -o output.css

Node.js 생태계에 의존하지 않는 프로젝트를 위해 GitHub에서 새로운 CLI 도구의 독립 실행형 빌드를 다운로드할 수도 있습니다.

v3에서 v4로 업그레이드하기

v3에서 v4 베타 버전으로 프로젝트를 업그레이드하고 싶다면, 업그레이드 도구를 사용해 대부분의 작업을 자동화할 수 있습니다:

Terminal
$ npx @tailwindcss/upgrade@next

대부분의 프로젝트에서 이 도구는 의존성 업데이트, 설정 파일을 CSS로 마이그레이션, 템플릿 파일 변경 사항 처리 등 전체 마이그레이션 과정을 자동으로 수행합니다.

업그레이드 도구는 Node.js 20 이상이 필요하므로, 실행 전에 환경이 업데이트되었는지 확인하세요.

업그레이드 도구를 새로운 브랜치에서 실행하는 것을 권장합니다. 그런 다음 변경 사항을 꼼꼼히 검토하고 브라우저에서 프로젝트를 테스트하여 모든 변경 사항이 올바르게 적용되었는지 확인하세요. 복잡한 프로젝트에서는 몇 가지를 수동으로 조정해야 할 수도 있지만, 어느 쪽이든 이 도구는 많은 시간을 절약해 줄 것입니다.

또한 v4.0의 주요 변경 사항을 모두 검토하고 변경된 내용을 잘 이해하는 것도 좋은 생각입니다. 업그레이드 도구가 잡아내지 못한 다른 사항이 있을 수 있으므로, 프로젝트에서 추가로 업데이트해야 할 부분이 있는지 확인하세요.

What’s new in v4.0

새로운 고성능 엔진

Tailwind CSS v4.0은 프레임워크를 처음부터 다시 작성한 버전입니다. 지난 몇 년간 아키텍처에 대해 배운 모든 것을 바탕으로 최대한 빠르게 최적화했습니다.

우리 프로젝트에서 벤치마킹을 해본 결과, 전체 빌드 시간이 3.5배 이상 빨라졌고, 증분 빌드(incremental build)는 8배 이상 빨라졌습니다.

아래는 Tailwind CSS v4.0을 Catalyst와 비교했을 때의 중간값 빌드 시간입니다:

v3.4v4.0 Beta개선
전체 빌드378ms100ms3.78배
새로운 CSS가 포함된 증분 빌드44ms5ms8.8배
새로운 CSS가 없는 증분 빌드35ms192µs182배

가장 인상적인 개선은 새로운 CSS를 컴파일할 필요가 없는 증분 빌드에서 나타났습니다. 이러한 빌드는 100배 이상 빨라졌으며, 마이크로초 단위로 완료됩니다. 프로젝트를 오래 작업할수록, flex, col-span-2, font-bold와 같이 이미 사용한 클래스를 다시 사용하는 경우가 많아지기 때문에 이러한 빌드가 더 자주 발생합니다.

CSS 우선 설정

Tailwind CSS v4.0의 가장 큰 변화 중 하나는 프로젝트 설정을 JavaScript에서 CSS로 옮긴 것입니다.

이제 tailwind.config.js 파일 대신, Tailwind를 임포트하는 CSS 파일에서 직접 모든 커스텀 설정을 할 수 있습니다. 이를 통해 프로젝트에서 신경 써야 할 파일이 하나 줄어듭니다:

app.css
@import "tailwindcss";

@theme {
  --font-display: "Satoshi", "sans-serif";

  --breakpoint-3xl: 1920px;

  --color-avocado-100: oklch(0.99 0 0);
  --color-avocado-200: oklch(0.98 0.04 113.22);
  --color-avocado-300: oklch(0.94 0.11 115.03);
  --color-avocado-400: oklch(0.92 0.19 114.08);
  --color-avocado-500: oklch(0.84 0.18 117.33);
  --color-avocado-600: oklch(0.53 0.12 118.34);

  --ease-fluid: cubic-bezier(0.3, 0, 0, 1);
  --ease-snappy: cubic-bezier(0.2, 0, 0, 1);

  /* ... */
}

새로운 CSS 우선 설정은 tailwind.config.js 파일에서 할 수 있었던 거의 모든 작업을 가능하게 합니다. 여기에는 디자인 토큰 설정, 콘텐츠 소스 설정, 커스텀 유틸리티 및 변형 정의, 플러그인 설치 등이 포함됩니다.

더 자세한 내용은 CSS 설정 심화 문서를 참고하세요.

CSS 테마 변수

Tailwind CSS v4.0은 모든 디자인 토큰을 기본적으로 CSS 변수로 제공합니다. 이를 통해 런타임에 필요한 값을 CSS만으로 참조할 수 있습니다.

앞서 살펴본 @theme 예제를 사용하면, 모든 값이 일반적인 커스텀 속성으로 CSS에 추가됩니다:

dist.css
:root {
  --font-display: "Satoshi", "sans-serif";

  --breakpoint-3xl: 1920px;

  --color-avocado-100: oklch(0.99 0 0);
  --color-avocado-200: oklch(0.98 0.04 113.22);
  --color-avocado-300: oklch(0.94 0.11 115.03);
  --color-avocado-400: oklch(0.92 0.19 114.08);
  --color-avocado-500: oklch(0.84 0.18 117.33);
  --color-avocado-600: oklch(0.53 0.12 118.34);

  --ease-fluid: cubic-bezier(0.3, 0, 0, 1);
  --ease-snappy: cubic-bezier(0.2, 0, 0, 1);

  /* ... */
}

이렇게 하면 이러한 값을 인라인 스타일로 재사용하거나 Motion과 같은 라이브러리에 전달하여 애니메이션을 적용하기가 쉬워집니다.

네이티브 CSS 캐스케이드 레이어

v4.0에서는 실제 CSS 캐스케이드 레이어를 사용합니다. 이를 통해 스타일의 우선순위와 상호작용을 더 쉽게 제어할 수 있습니다.

v4.0으로 CSS를 빌드할 때의 출력 결과는 다음과 같습니다:

dist.css
@layer theme, base, components, utilities;

@layer theme {
  :root {
    --font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
    'Segoe UI Symbol', 'Noto Color Emoji';
    --font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
      'Courier New', monospace;

    /* ... */
  }
}

@layer base {
  *,
  ::after,
  ::before,
  ::backdrop,
  ::file-selector-button {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0 solid;
  }

  /* ... */
}

@layer utilities {
  .pointer-events-none {
    pointer-events: none;
  }
  .visibility-hidden {
    visibility: hidden;
  }

  /* ... */

  .focus\:outline:focus {
    outline-width: 1px;
  }

  @media (width >= 40rem) {
    @media (hover: hover) {
      .sm\:hover\:opacity-100:hover {
        opacity: 100%;
      }
    }
  }
}

Tailwind에서는 수년 동안 레이어 개념을 사용해 왔지만, 네이티브 캐스케이드 레이어는 빌드 타임에 쉽게 구현할 수 없었던 기능을 제공합니다. 예를 들어, 한 레이어 내의 스타일이 다른 레이어의 스타일보다 높은 우선순위 점수를 가지더라도 스타일을 격리할 수 있습니다. 또한 유지보수해야 할 코드도 줄어듭니다!

자동 소스 탐지

Tailwind CSS v3에서 항상 귀찮게 설정해야 했던 content 배열 기억하시나요? v4.0에서는 이 모든 것을 자동으로 탐지하는 휴리스틱을 도입해 더 이상 설정할 필요가 없게 되었습니다.

예를 들어, 버전 관리되지 않은 의존성이나 생성된 파일을 스캔하지 않도록 .gitignore 파일에 있는 모든 것을 자동으로 무시합니다:

.gitignore
# dependencies
/node_modules

# testing
/coverage

# caches
/.next/

# production
/build

또한 이미지, 비디오, .zip 파일 등 모든 바이너리 확장자도 자동으로 무시합니다.

만약 기본적으로 제외된 소스를 명시적으로 추가해야 한다면, CSS 파일 안에서 @source 지시자를 사용해 추가할 수 있습니다:

app.css
@import "tailwindcss";
@source "../node_modules/@my-company/ui-lib";

@source 지시자는 내부적으로 동일한 휴리스틱을 사용하므로, 스캔할 확장자를 일일이 지정하지 않아도 바이너리 파일 타입을 자동으로 제외합니다.

내장된 import 지원

v4.0 이전에는 @import를 사용해 다른 CSS 파일을 인라인으로 불러오려면 postcss-import와 같은 플러그인을 추가로 설정해야 했습니다.

이제는 이 기능이 기본적으로 지원되기 때문에 다른 도구가 필요 없습니다:

postcss.config.mjs
export default {
  plugins: {
    'postcss-import': {},
    '@tailwindcss/postcss': {},
  },
};

우리의 import 시스템은 Tailwind CSS를 위해 특별히 설계되었기 때문에, 엔진과 긴밀하게 통합해 더 빠르게 동작하도록 만들었습니다.

내장 CSS 트랜스파일레이션

프로덕션 빌드 시 Tailwind CSS v4.0은 Lightning CSS를 통해 CSS를 자동으로 처리합니다. 이는 벤더 프리픽스, 모던 기능 트랜스파일레이션, 코드 최소화 등을 포함합니다.

이 기능 덕분에 autoprefixerpostcss-preset-env 같은 도구를 프로젝트에서 제거할 수 있습니다:

postcss.config.mjs
export default {
  plugins: {
    '@tailwindcss/postcss': {},
    'postcss-preset-env': {},
    'autoprefixer': {},
  },
};

v4.0에서는 Tailwind CSS만 설정하면 전체 CSS 파이프라인을 처리할 수 있습니다. 다른 도구는 필요하지 않습니다.

간소화된 테마 설정

v4.0에서는 디자인 토큰과 관련 없는 설정을 크게 줄였습니다. 이제 grid-cols-12, z-40, opacity-70 같은 유틸리티들은 테마 설정에 의존하지 않고 바로 사용할 수 있습니다. 5열 그리드든 73열 그리드든, 별도의 설정 없이도 바로 적용할 수 있습니다.

<div class="grid grid-cols-73">
  <div>1</div>
  <!-- ... -->
  <div>73</div>
</div>

data-*와 같은 변형(variants)도 동일하게 간소화했습니다. 이제 간단한 불리언 속성에 대해 설정을 추가하거나 임의의 값을 사용할 필요가 없습니다.

<div class="opacity-50 data-[selected]:opacity-100" data-selected>
<div class="opacity-50 data-selected:opacity-100" data-selected>
  <!-- ... -->
</div>

이러한 변경으로 인해 테마 설정을 훨씬 덜 건드리게 되며, 타이포그래피, 색상 팔레트, 브레이크포인트와 같은 중요한 디자인 토큰에 집중할 수 있습니다.

동적 간격 스케일

px-*, mt-*, w-*, h-*와 같은 간격 유틸리티가 작동하는 방식을 단순화했습니다. 이제 모든 유틸리티는 기본 테마에서 0.25rem로 정의된 단일 간격 스케일 값에서 파생됩니다:

@theme {
  --spacing: 0.25rem;
}

이렇게 간격 스케일을 정의하면, 0.25rem의 배수마다 간격 스케일이 제공됩니다. 따라서 mt-21과 같은 유틸리티도 추가 설정 없이 작동합니다. 이는 v3에서 mt-20mt-24 사이에서 선택하거나 임의의 값을 사용해야 했던 것과는 다릅니다.

더 많은 제약을 원한다면, --spacing 변수를 비활성화하고 명시적인 스케일을 직접 제공할 수도 있습니다:

@theme {
  --spacing: initial
  --spacing-1: 0.25rem
  --spacing-2: 0.5rem
  --spacing-4: 1rem
  --spacing-8: 2rem
  --spacing-12: 3rem
}

현대화된 P3 색상 팔레트

기본 색상 팔레트 전체를 rgb에서 oklch로 업그레이드했습니다. 더 넓은 색 영역을 활용하여 이전에 sRGB 색 공간에 제한되었던 부분에서 색상을 더 선명하게 만들었습니다.

v3에서의 색상 간 균형을 유지하려고 노력했기 때문에, 전반적으로 색상을 새롭게 바꾸었더라도 기존 프로젝트를 업그레이드할 때 큰 변화를 느끼지 않을 것입니다.

간소화된 변수 색상

v3에서 색상 팔레트에 CSS 변수를 사용했다면, rgb(…) 함수 없이 숫자 목록으로 색상을 정의하거나 불투명도 수정자가 작동하도록 <alpha-value> 자리 표시자를 사용해야 했던 이상한 작업을 기억할 것입니다.

새로운 CSS color-mix(…) 함수 덕분에, v4.0에서는 더 이상 그런 작업이 필요하지 않습니다. 단순히 색상을 변수로 정의하면 모든 불투명도 수정자 기능이 자동으로 작동합니다:

app.css
@import "tailwindcss";

@theme {
  --color-primary: var(--color-blue-500);
  --color-error: var(--color-red-500);

  /* ... */
}

이제 bg-primary/50와 같은 유틸리티를 사용할 때, 별도의 복잡한 해결책 없이 바로 작동합니다:

<div class="bg-primary/50">
  <!-- ... -->
</div>

컨테이너 쿼리 지원

v4.0부터 코어에 컨테이너 쿼리 지원을 추가했기 때문에 더 이상 @tailwindcss/container-queries 플러그인이 필요하지 않습니다:

HTML
<div class="@container">
  <div class="grid grid-cols-1 @sm:grid-cols-3 @lg:grid-cols-4">
    <!-- ... -->
  </div>
</div>

또한 새로운 @max-* 변형을 사용하여 최대 너비 컨테이너 쿼리도 지원합니다:

<div class="@container">
  <div class="grid grid-cols-3 @max-md:grid-cols-1">
    <!-- ... -->
  </div>
</div>

일반적인 브레이크포인트 변형과 마찬가지로 @min-*@max-* 변형을 함께 사용하여 컨테이너 쿼리 범위를 정의할 수도 있습니다:

<div class="@container">
  <div class="flex @min-md:@max-xl:hidden">
    <!-- ... -->
  </div>
</div>

컨테이너 쿼리에 대한 브라우저 지원은 매우 훌륭하며, v4.0에서 여러분의 프로젝트에서 이를 더 쉽게 사용할 수 있게 되어 기쁩니다.

3D 변환

드디어 rotate-x-*, rotate-y-*, scale-z-*, translate-z-*와 같은 3D 변환을 위한 API를 추가했습니다. 이 외에도 다양한 기능이 제공됩니다.

Michael Foster

Boost your conversion rate

<div class="perspective-distant">
  <article class="... transform-3d rotate-x-51 rotate-z-43 shadow-xl transition-all duration-500 hover:-translate-y-4 hover:rotate-x-49 hover:rotate-z-38 hover:shadow-2xl">
    <!-- ... -->
  </article>
</div>

transform-3d 유틸리티를 사용하여 적절한 transform-style을 설정해 3D 변환을 활성화할 수 있습니다.

Rotate

rotate-x-*, rotate-y-*, rotate-z-* 유틸리티를 사용해 3D 공간에서 엘리먼트를 회전시킬 수 있습니다.

이 유틸리티들은 기본적으로 모든 숫자 값을 지원하지만, 참고를 위해 몇 가지 예제를 제공합니다:

Class
Properties
rotate-x-0transform: rotateX(0deg) var(--tw-rotate-y) var(--tw-rotate-z);
rotate-x-3transform: rotateX(3deg) var(--tw-rotate-y) var(--tw-rotate-z);
rotate-x-45transform: rotateX(45deg) var(--tw-rotate-y) var(--tw-rotate-z);
rotate-x-180transform: rotateX(180deg) var(--tw-rotate-y) var(--tw-rotate-z);
rotate-y-0transform: var(--tw-rotate-x) rotateY(0deg) var(--tw-rotate-z);
rotate-y-3transform: var(--tw-rotate-x) rotateY(3deg) var(--tw-rotate-z);
rotate-y-45transform: var(--tw-rotate-x) rotateY(45deg) var(--tw-rotate-z);
rotate-y-180transform: var(--tw-rotate-x) rotateY(180deg) var(--tw-rotate-z);
rotate-z-0transform: var(--tw-rotate-x) var(--tw-rotate-y) rotateZ(0deg);
rotate-z-3transform: var(--tw-rotate-x) var(--tw-rotate-y) rotateZ(3deg);
rotate-z-45transform: var(--tw-rotate-x) var(--tw-rotate-y) rotateZ(45deg);
rotate-z-180transform: var(--tw-rotate-x) var(--tw-rotate-y) rotateZ(180deg);

Scale

새로운 scale-z-* 유틸리티를 사용해 z축에서 엘리먼트를 확대/축소할 수 있습니다.

원하는 숫자 값을 자유롭게 사용할 수 있지만, 참고용으로 몇 가지 예제를 제공합니다:

Class
Properties
scale-z-0scale: var(--tw-scale-x) var(--tw-scale-y) 0%;
scale-z-50scale: var(--tw-scale-x) var(--tw-scale-y) 50%;
scale-z-75scale: var(--tw-scale-x) var(--tw-scale-y) 75%;
scale-z-100scale: var(--tw-scale-x) var(--tw-scale-y) 100%;
scale-z-125scale: var(--tw-scale-x) var(--tw-scale-y) 125%;
scale-z-150scale: var(--tw-scale-x) var(--tw-scale-y) 150%;
scale-z-200scale: var(--tw-scale-x) var(--tw-scale-y) 200%;

번역

새로운 translate-z-* 유틸리티를 사용해 엘리먼트를 가깝게 또는 멀리 이동시킬 수 있습니다:

이 유틸리티는 기본적으로 간격 스케일을 사용하며, 모든 값을 바로 지원합니다. 참고용으로 몇 가지 예제를 살펴보세요:

Class
Properties
translate-z-0translate: var(--tw-translate-x) var(--tw-translate-y) calc(var(--spacing) * 0;
translate-z-0.5translate: var(--tw-translate-x) var(--tw-translate-y) calc(var(--spacing) * 0.5;
translate-z-1translate: var(--tw-translate-x) var(--tw-translate-y) calc(var(--spacing) * 1;
translate-z-2translate: var(--tw-translate-x) var(--tw-translate-y) calc(var(--spacing) * 2;
translate-z-4translate: var(--tw-translate-x) var(--tw-translate-y) calc(var(--spacing) * 4;
translate-z-pxtranslate: var(--tw-translate-x) var(--tw-translate-y) 1px;

Perspective

3D 변환에 사용되는 원근감을 조절하려면 perspective-near, perspective-normal, perspective-distant와 같은 유틸리티와 새로운 perspective-origin-* 유틸리티를 사용하세요:

Class
Properties
perspective-dramaticperspective: 100px;
perspective-nearperspective: 300px;
perspective-normalperspective: 500px;
perspective-midrangeperspective: 800px;
perspective-distantperspective: 1200px;
perspective-[760px]perspective: 760px;
perspective-origin-bottomperspective-origin: bottom;
perspective-origin-bottom-leftperspective-origin: bottom-left;
perspective-origin-bottom-rightperspective-origin: bottom-right;
perspective-origin-centerperspective-origin: center;
perspective-origin-leftperspective-origin: left;
perspective-origin-rightperspective-origin: right;
perspective-origin-topperspective-origin: top;
perspective-origin-top-rightperspective-origin: top-right;
perspective-origin-top-leftperspective-origin: top-left;

perspective-* 유틸리티는 테마에서 --perspective-* 네임스페이스를 사용해 커스터마이징할 수 있습니다.

Backface visibility

3D 공간에서 변형된 엘리먼트의 뒷면이 보이는지 여부를 제어하기 위해 새로운 backface-visiblebackface-hidden 유틸리티를 사용하세요.

Class
Properties
backface-visiblebackface-visibility: visible;
backface-hiddenbackface-visibility: hidden;

선형 그라데이션 각도

이제 선형 그라데이션은 각도를 값으로 지원합니다. 따라서 bg-linear-45와 같은 유틸리티를 사용해 45도 각도의 그라데이션을 만들 수 있습니다:

<div class="bg-linear-45 from-indigo-500 via-purple-500 to-pink-500"></div>

bg-gradient-*bg-linear-*로 이름을 변경한 것을 눈치챘을 겁니다. 곧 그 이유를 알게 될 것입니다!

그라데이션 보간 조정자

그라데이션의 색상 보간 모드를 조정할 수 있는 기능을 추가했습니다. 이제 bg-linear-to-r/srgb와 같은 클래스는 sRGB를 사용하여 보간하고, bg-linear-to-r/oklch는 OKLCH를 사용하여 보간합니다:

  <div class="bg-linear-to-r/srgb from-indigo-500 to-teal-400"></div>
  <div class="bg-linear-to-r/oklch from-indigo-500 to-teal-400"></div>

OKLCH나 HSL과 같은 극좌표 색 공간을 사용하면 from-*to-* 색상이 색상환에서 멀리 떨어져 있을 때 훨씬 더 선명한 그라데이션을 얻을 수 있습니다. v4.0에서는 기본적으로 OKLAB을 사용하지만, 이러한 조정자를 추가하여 다른 색 공간을 사용해 보간할 수도 있습니다.

원뿔형 및 방사형 그라데이션

원뿔형(conic) 및 방사형(radial) 그라데이션을 생성하기 위한 새로운 bg-conic-*bg-radial-* 유틸리티를 추가했습니다:

<div class="bg-conic/[in_hsl_longer_hue] from-red-600 to-red-600 size-24 rounded-full"></div>
<div class="bg-radial-[at_25%_25%] from-white to-zinc-900 to-75% size-24 rounded-full"></div>

이 새로운 유틸리티는 기존의 from-*, via-*, to-* 유틸리티와 함께 작동하여 선형 그라데이션을 만드는 것과 같은 방식으로 원뿔형 및 방사형 그라데이션을 생성할 수 있게 해줍니다. 또한, 색상 보간 방법을 설정하거나 그라데이션 위치와 같은 세부 사항을 제어하기 위한 임의 값 지원을 포함합니다.

안쪽 그림자와 안쪽 링

v4.0에서 기존의 shadow-*ring-* 유틸리티와 조합할 수 있는 전용 inset-shadow-*inset-ring-* 유틸리티를 추가했습니다. 이를 통해 프로젝트에 필요한 효과를 만들기 위해 네 가지 레이어의 그림자를 쌓을 수 있습니다.

Send

Send

<button class="shadow-md inset-shadow-sm inset-shadow-white/20 ring ring-blue-600 inset-ring inset-ring-white/15 ...">
  <!-- ... -->
</button>

inset-ring-* 유틸리티는 ring-* 유틸리티와 마찬가지로 모든 너비 값을 지원하며, inset-shadow-* 유틸리티는 기본적으로 2xs, xs, sm 크기를 제공합니다. 추후 더 많은 크기를 추가할 수도 있지만, 현재는 이 세 가지가 가장 유용하다고 판단했습니다.

@theme {
  --inset-shadow-2xs: inset 0 1px rgb(0 0 0 / 0.05);
  --inset-shadow-xs: inset 0 1px 1px rgb(0 0 0 / 0.05);
  --inset-shadow-sm: inset 0 2px 4px rgb(0 0 0 / 0.05);
}

일반적인 shadow-*ring-* 유틸리티와 마찬가지로, inset-shadow-black/25inset-ring-white/50과 같은 클래스를 사용하여 색상도 지원합니다.

field-sizing 유틸리티

CSS만으로 자동 크기 조정이 가능한 텍스트 영역을 만들 수 있는 새로운 field-sizing 속성을 위한 유틸리티를 추가했습니다:

텍스트 영역에 입력해 보세요. 효과를 확인할 수 있습니다.

<label class="block">
  <span class="block text-sm/6 font-medium text-gray-900 dark:text-white">댓글 추가</span>
  <textarea class="field-sizing-content ..."></textarea>
</label>

field-sizing-content를 사용하면 컨트롤이 내용에 맞게 크기가 조정되고, field-sizing-fixed를 사용하면 컨트롤의 크기를 고정할 수 있습니다.

color-scheme 유틸리티

다크 모드에서 앱이 밝은 스크롤바를 보여주는 것이 불편했던 적이 있나요? 이 새로운 color-scheme 유틸리티가 필요할 때입니다.

콘텐츠를 스크롤하여 스크롤바 테마를 확인하세요

라이트 모드

It's a Mammal

Right now there are six-hundred Titleists that I got from the driving range in the trunk of my car. Why don't we drive out to Rock-a-Way… and hit `em into the ocean! Now picture this. we find a nice sweet spot between the dunes, we take out our drivers, we tee up and, that ball goes sailing up into the sky holds there for a moment and then.. gulp!

다크 모드

It's a Mammal

Right now there are six-hundred Titleists that I got from the driving range in the trunk of my car. Why don't we drive out to Rock-a-Way… and hit `em into the ocean! Now picture this. we find a nice sweet spot between the dunes, we take out our drivers, we tee up and, that ball goes sailing up into the sky holds there for a moment and then.. gulp!

<div class="grid grid-cols-2">
  <div class="bg-white overflow-y-scroll scheme-light">
     ...
  </div>
  <div class="bg-slate-800 overflow-y-scroll scheme-dark">
     ...
  </div>
</div>

다음은 새로운 API의 전체 목록입니다:

Class
Properties
scheme-normalcolor-scheme: normal;
scheme-darkcolor-scheme: dark;
scheme-lightcolor-scheme: light;
scheme-light-darkcolor-scheme: light dark;
scheme-only-darkcolor-scheme: only dark;
scheme-only-lightcolor-scheme: only light;

html 또는 body 엘리먼트에 scheme-light dark:scheme-dark를 추가하면, 어떤 다크 모드 전략을 사용하더라도 스크롤바가 항상 잘 보이게 됩니다.

font-stretch 유틸리티

다양한 너비를 지원하는 가변 폰트를 스타일링할 수 있는 새로운 font-stretch 속성을 위한 유틸리티를 추가했습니다:

font-stretch-extra-condensed

The quick brown fox jumps over the lazy dog.

font-stretch-condensed

The quick brown fox jumps over the lazy dog.

font-stretch-normal

The quick brown fox jumps over the lazy dog.

font-stretch-expanded

The quick brown fox jumps over the lazy dog.

font-stretch-extra-expanded

The quick brown fox jumps over the lazy dog.

이 속성의 이름이 언젠가 font-width로 변경될 예정이지만, 아직 어떤 브라우저도 이를 지원하지 않습니다. 이 문제를 해결할 날이 기대됩니다.

Class
Properties
font-stretch-normalfont-stretch: normal;
font-stretch-ultra-condensedfont-stretch: ultra-condensed;
font-stretch-extra-condensedfont-stretch: extra-condensed;
font-stretch-condensedfont-stretch: condensed;
font-stretch-semi-condensedfont-stretch: semi-condensed;
font-stretch-semi-expandedfont-stretch: semi-expanded;
font-stretch-expandedfont-stretch: expanded;
font-stretch-extra-expandedfont-stretch: extra-expanded;
font-stretch-ultra-expandedfont-stretch: ultra-expanded;
font-stretch-0%font-stretch: 0%;
font-stretch-50%font-stretch: 50%;
font-stretch-75%font-stretch: 75%;
font-stretch-90%font-stretch: 90%;
font-stretch-95%font-stretch: 95%;
font-stretch-100%font-stretch: 100%;
font-stretch-105%font-stretch: 105%;
font-stretch-110%font-stretch: 110%;
font-stretch-125%font-stretch: 125%;
font-stretch-150%font-stretch: 150%;
font-stretch-200%font-stretch: 200%;

조합 가능한 변형

새로운 v4.0 엔진에서는 특정 변형을 다른 변형과 연결할 수 있습니다. 이를 통해 v3에서 복잡한 임의의 변형이 필요했던 부분을 간단한 이름의 API로 사용할 수 있습니다:

<div class="group">
  <div class="group-has-[&[data-potato]]:opacity-100">
  <div class="group-has-data-potato:opacity-100">
    <!-- ... -->
  </div>
  <div data-potato>
    <!-- ... -->
  </div>
</div>

이 기능은 group-*, peer-*, has-*와 새로운 not-*, in-* 변형을 포함해 의미가 있는 모든 변형에서 작동합니다. 원하는 만큼 여러 변형을 연결할 수 있으므로, group-not-has-peer-not-data-active:underline과 같이 완전히 쓸모없는 클래스도 실제 CSS를 생성합니다.

`@starting-style` 변형

새로운 starting 변형은 CSS의 @starting-style 기능을 지원하여 엘리먼트가 처음 표시될 때 속성을 트랜지션할 수 있게 해줍니다:

버튼을 클릭하면 팝오버가 애니메이션과 함께 나타납니다

<div>
  <button popovertarget="my-popover">업데이트 확인</button>
  <div popover id="my-popover" class="opacity-0 transition-all duration-500 transition-discrete open:opacity-100 starting:open:opacity-0">
    <!-- ... -->
  </div>
</div>

not-* 변형

새로운 not-* 변형은 :not(…) 의사 클래스를 지원하여 특정 조건이 참이 아닐 때 스타일을 적용할 수 있게 해줍니다.

예를 들어, 버튼이 포커스되지 않았을 때만 호버 스타일을 추가할 수 있습니다:

<button class="bg-indigo-600 hover:not-focus:bg-indigo-700">
  <!-- ... -->
</button>

또한 not-* 변형을 forced-colors와 같은 미디어 쿼리 변형과 결합하여 강제 색상 모드가 활성화되지 않았을 때만 엘리먼트에 스타일을 적용할 수 있습니다:

<input type="radio" class="not-forced-colors:appearance-none" />

supports-* 변형과도 함께 사용할 수 있어, 특정 CSS 기능에 대한 브라우저 지원이 없을 때 엘리먼트에 스타일을 적용할 수 있습니다:

<div class="not-supports-[display:grid]:flex">
  <!-- ... -->
</div>

inert 변형

새로운 inert 변형을 사용하면 inert 속성이 지정된 엘리먼트에 스타일을 적용할 수 있습니다:

<main inert class="inert:opacity-50 inert:blur">
  <!-- ... -->
</main>

이 기능은 엘리먼트가 상호작용할 수 없음을 명확히 보여주는 시각적 단서를 추가할 때 유용합니다.

nth-* 변형

:nth-child(…), :nth-last-child(…), :nth-of-type(…), :nth-last-of-type(…) 의사 클래스에 대해 네 가지 새로운 변형을 추가했습니다:

<div class="nth-3:underline"></div>
<div class="nth-last-5:underline"></div>
<div class="nth-of-type-4:underline"></div>
<div class="nth-last-of-type-6:underline"></div>

기본적으로 원하는 숫자를 전달할 수 있으며, nth-[2n+1_of_li]와 같은 더 복잡한 표현을 위해 임의의 값을 사용할 수 있습니다.

in-* 변형

group-focus와 같은 group-* 변형을 알고 계실 겁니다. 새로운 in-* 변형은 부모 엘리먼트에 group을 추가할 필요가 없다는 점을 제외하면 이와 비슷합니다:

<div tabindex="0" class="group">
  <div class="opacity-50 group-focus:opacity-100">
<div tabindex="0">
  <div class="opacity-50 in-focus:opacity-100">
    <!-- ... -->
  </div>
</div>

세밀한 제어가 필요할 때는 여전히 group-*을 사용해야 하지만, 그 외의 경우에는 이 방법이 더 간결합니다.

:popover-open 지원

기존의 open 변형을 업데이트하여 :popover-open 의사 클래스와 [open] 속성을 모두 대상으로 하도록 했습니다:

<div>
  <button popovertarget="my-popover">팝오버 열기</button>
  <div popover id="my-popover" class="opacity-0 open:opacity-100 ...">
    <!-- ... -->
  </div>
</div>

이걸 별도의 popover-open 변형으로 만들지 않은 걸 나중에 후회할 거라고 확신하지만, 정말 깊이 고민해봤을 때 [open]:popover-open을 모두 사용하면서 각 조건에 대해 다른 스타일을 적용해야 하는 상황을 상상할 수 없었습니다. 하지만 누군가가 스펙을 업데이트해서 나중에 이 부분에서 문제를 일으킬 거라는 건 확실합니다.

하위 요소 선택자

얼마 전에 직접적인 자식 요소를 타겟팅하기 위해 * 선택자를 추가했던 것을 기억하시나요?

<ul class="*:p-4">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

v4.0에서는 모든 하위 요소를 타겟팅할 수 있는 새로운 ** 선택자를 추가했습니다. 이 선택자는 다른 선택자와 조합하여 특정 요소를 좁혀 선택할 때 가장 유용합니다.

<div class="**:data-avatar:rounded-full">
  <div>
    <img src="" data-avatar /> <!-- 이 요소는 둥글게 표시됩니다 -->
  </div>
  <p></p>
</div>

재미있는 사실 — 이 구문은 글로브(globs)에서 영감을 받았습니다. 좋든 나쁘든 말이죠.


CSS configuration in-depth

테마 커스터마이징

Tailwind CSS v4.0에서 테마를 커스터마이징하려면 CSS 파일에서 새로운 @theme 지시어를 직접 사용하세요:

@import "tailwindcss";

@theme {
  --font-display: "Satoshi", "sans-serif";

  --breakpoint-3xl: 1920px;

  --color-avocado-100: oklch(0.99 0 0);
  --color-avocado-200: oklch(0.98 0.04 113.22);
  --color-avocado-300: oklch(0.94 0.11 115.03);
  --color-avocado-400: oklch(0.92 0.19 114.08);
  --color-avocado-500: oklch(0.84 0.18 117.33);
  --color-avocado-600: oklch(0.53 0.12 118.34);

  --ease-fluid: cubic-bezier(0.3, 0, 0, 1);
  --ease-snappy: cubic-bezier(0.2, 0, 0, 1);

  /* ... */
}

여기서 정의한 각 CSS 변수는 Tailwind에게 해당 값을 기반으로 새로운 유틸리티와 변형을 제공하도록 지시합니다. 이를 통해 font-display, 3xl:max-w-xl, text-avocado-400, hover:ease-fluid와 같은 클래스를 마크업에서 사용할 수 있습니다:

<div class="max-w-lg 3xl:max-w-xl">
  <h1 class="font-display text-4xl">
    Data to <span class="text-avocado-400">enrich</span> your online business
  </h1>
</div>

각 변수 세트는 해당 유틸리티와 연결된 네임스페이스의 일부입니다. 예를 들어, 폰트 크기 유틸리티는 --font-* 네임스페이스를 참조하고, 모든 색상 유틸리티는 --color-* 네임스페이스를 참조하며, 트랜지션 타이밍 함수 유틸리티는 --ease-* 네임스페이스를 참조합니다.

전체 목록은 테마 네임스페이스 참조를 확인하세요.

기본 테마 덮어쓰기

기본적으로 새로운 CSS 변수를 추가하면 Tailwind CSS v3의 extend와 같은 방식으로 동작합니다:

@import "tailwindcss";

@theme {
  /* 기본값에 추가되는 값들 */
  --font-display: "Satoshi", "sans-serif";
  --breakpoint-3xl: 1920px;
}

전체 네임스페이스를 덮어쓰려면 --font-*: initial과 같은 구문을 사용해 네임스페이스를 초기화합니다:

@import "tailwindcss";

@theme {
  --font-*: initial;
  --font-display: "Satoshi", "sans-serif";
}

이제 기본 font-sans, font-serif, font-mono 유틸리티는 프로젝트에 존재하지 않으며, font-display만 사용 가능한 폰트 패밀리 유틸리티가 됩니다.

또한, 완전히 처음부터 시작하고 싶다면 --*: initial을 사용해 전체 기본 테마를 초기화할 수 있습니다:

@import "tailwindcss";

@theme {
  --*: initial;
}

이렇게 하면 모든 기본 폰트, 타이포그래피 스케일, 색상 팔레트 등을 포함한 모든 기본 디자인 토큰이 제거됩니다.

폰트 크기 유틸리티에 기본 줄 간격 설정하기

커스텀 폰트 크기에 기본 줄 간격, 폰트 두께, 또는 글자 간격을 설정하려면 --text-big--line-height와 같이 더블 대시를 사용하여 지원 변수를 추가하세요:

@theme {
  --text-big: 16rem;
  --text-big--line-height: 18rem;
  --text-big--font-weight: 550;
  --text-big--letter-spacing: -0.025em;
}

애니메이션과 키프레임 설정하기

기본적으로 Tailwind CSS v4.0은 프로젝트에서 해당 애니메이션 유틸리티를 사용하지 않더라도, CSS에 추가한 커스텀 @keyframes 규칙을 그대로 유지합니다.

사용하지 않는 @keyframes 규칙이 제거되도록 하려면, CSS 루트가 아닌 @theme 아래에 설정해야 합니다:

@theme {
  --animate-marquee: marquee 3s linear infinite;

  @keyframes marquee {
    to {
      transform: translateY(-50%);
    }
  }
}

네임스페이스 참조

Tailwind CSS v4.0에서 테마 설정을 크게 간소화했기 때문에, 일반적으로 다음과 같은 네임스페이스만 다루게 됩니다:

네임스페이스유틸리티
--color-*bg-white, text-black, fill-blue-500와 같은 색상 유틸리티
--font-*font-sans와 같은 폰트 패밀리 유틸리티
--text-*text-sm와 같은 폰트 크기 유틸리티
--font-weight-*font-bold와 같은 폰트 두께 유틸리티
--tracking-*tracking-tight와 같은 글자 간격 유틸리티
--leading-*leading-relaxed와 같은 줄 간격 유틸리티
--spacing-*pt-5, mr-2, h-8와 같은 간격 및 크기 유틸리티
--breakpoint-*md:* , lg:*와 같은 반응형 브레이크포인트 변형
--container-*@md:*와 같은 컨테이너 쿼리 변형 및 w-sm, max-w-lg와 같은 너비 유틸리티
--radius-*rounded-md와 같은 테두리 반경 유틸리티
--shadow-*shadow-lg와 같은 박스 그림자 유틸리티
--inset-shadow-*inset-shadow-sm와 같은 내부 박스 그림자 유틸리티
--drop-shadow-*drop-shadow-xl와 같은 드롭 그림자 유틸리티
--ease-*ease-out와 같은 트랜지션 타이밍 함수 유틸리티
--animate-*animate-spin와 같은 애니메이션 유틸리티

더 세밀한 제어가 필요한 경우, 대부분의 유틸리티는 CSS 속성 이름과 일치하는 네임스페이스 아래에서 설정할 수 있습니다. 예를 들어, bg-grid-pattern과 같은 커스텀 background-image 유틸리티는 --background-image-grid-pattern: url(…)을 사용하여 설정할 수 있습니다.

다크 모드 설정하기

기본적으로 Tailwind CSS v4.0의 dark 변형은 prefers-color-scheme 미디어 쿼리를 사용합니다.

프로젝트에서 다크 모드를 위해 선택자 기반 전략을 사용하고 싶다면, 원하는 선택자로 dark 변형을 재정의하면 됩니다:

@import "tailwindcss";
@variant dark (&:where(.dark, .dark *));

소스 탐지 설정

Tailwind CSS v4.0의 자동 소스 탐지가 너무 광범위해서 원하지 않는 파일까지 포함하는 경우(예: 대규모 모노레포에서 작업 중일 때), Tailwind를 임포트할 때 source(…) 함수를 사용하여 자동 소스 탐지의 기본 경로를 지정할 수 있습니다.

@import "tailwindcss" source("../src");

이 경로는 해당 CSS 파일이 위치한 곳을 기준으로 상대 경로로 지정해야 합니다.

콘텐츠 소스 추가하기

기본적으로 인식되지 않는 추가 콘텐츠 소스(예: .gitignore 파일에 포함된 것)를 추가해야 한다면, @source를 사용하여 추가할 수 있습니다:

@import "tailwindcss";
@source "../node_modules/@my-company/ui-lib/src/components";

이런 경우에는 라이브러리에서 CSS 파일을 내보내고, @source 지시자를 해당 CSS 파일로 옮겨서 단순히 CSS 파일을 임포트하는 방식도 유용할 수 있습니다:

/node_modules/@my-company/ui-lib/index.css
@source "./src/components";
app.css
@import "tailwindcss";
@import "@my-company/ui-lib";

@source 지시자는 Vite 플러그인을 사용하면서도 모듈 그래프에 자연스럽게 포함되지 않는 콘텐츠 소스(예: Laravel 프로젝트의 PHP 템플릿)를 포함해야 할 때도 유용합니다:

@import "tailwindcss";
@source "../../resources/views";
@source "../../app";

소스 감지 비활성화

어떤 이유로든 자동 소스 감지를 비활성화해야 한다면, Tailwind를 불러올 때 source(none)을 사용하세요:

@import "tailwindcss" source(none);

소스 감지를 비활성화한 후에는 @source를 사용해 모든 콘텐츠 소스를 명시적으로 설정할 수 있습니다.

Preflight 비활성화

Tailwind의 기본 스타일을 비활성화해야 한다면, 필요한 부분만 따로 가져올 수 있습니다:

@layer theme, base, components, utilities;
@import "tailwindcss/theme" layer(theme);
@import "tailwindcss/utilities" layer(utilities);

접두사 사용하기

기존 CSS와의 충돌을 피하기 위해 유틸리티와 테마 변수에 접두사를 붙이려면, Tailwind를 임포트할 때 prefix(…) 함수를 사용하세요:

@import "tailwindcss" prefix(tw);

접두사는 v3와 조금 다르게 동작합니다. 이제는 접두사가 변형자처럼 보이며, 항상 클래스 이름의 맨 앞에 위치합니다:

<div class="tw:flex tw:bg-red-500 tw:hover:bg-red-600">
  <!-- ... -->
</div>

접두사를 사용할 때도, 접두사를 사용하지 않는 것처럼 테마 변수를 설정해야 합니다:

app.css
@import "tailwindcss" prefix(tw);

@theme {
  --font-display: "Satoshi", "sans-serif";

  --breakpoint-3xl: 1920px;

  --color-avocado-100: oklch(0.99 0 0);
  --color-avocado-200: oklch(0.98 0.04 113.22);
  --color-avocado-300: oklch(0.94 0.11 115.03);

  /* ... */
}

생성된 CSS 변수는 프로젝트 내 기존 변수와의 충돌을 피하기 위해 접두사가 포함됩니다:

dist.css
:root {
  --tw-font-display: "Satoshi", "sans-serif";

  --tw-breakpoint-3xl: 1920px;

  --tw-color-avocado-100: oklch(0.99 0 0);
  --tw-color-avocado-200: oklch(0.98 0.04 113.22);
  --tw-color-avocado-300: oklch(0.94 0.11 115.03);

  /* ... */
}

커스텀 유틸리티 추가하기

v4.0에서 커스텀 유틸리티를 추가하려면 새로운 @utility 지시자를 사용하세요:

@import "tailwindcss";

@utility tab-4 {
  tab-size: 4;
}

커스텀 유틸리티는 프레임워크의 기본 유틸리티와 함께 자동으로 utilities 레이어에 삽입됩니다.

커스텀 변형 추가하기

v4.0에서 커스텀 변형을 추가하려면 새로운 @variant 지시자를 사용하세요:

@import "tailwindcss";

@variant pointer-coarse (@media (pointer: coarse));
@variant theme-midnight (&:where([data-theme="midnight"] *));

이를 통해 pointer-coarse:size-48theme-midnight:bg-slate-900 같은 유틸리티를 작성할 수 있습니다.

플러그인 사용하기

v4.0에서 플러그인을 로드하려면 새로운 @plugin 지시자를 사용하세요:

@import "tailwindcss";

@plugin "@tailwindcss/typography";

@plugin 지시자는 패키지 이름이나 로컬 경로를 인자로 받습니다.

레거시 설정 파일 사용하기

v4.0에서 기존 JS 설정 파일을 사용하려면 @config 지시어를 사용하여 불러오세요:

@import "tailwindcss";

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

v4.0에서는 JS 설정의 모든 기능이 지원되지 않는다는 점에 유의하세요. corePlugins, important, separator와 같은 옵션은 안정적인 v4.0 릴리스에서 전혀 지원되지 않을 가능성이 높습니다. 또한 safelist와 같은 옵션은 동작 방식이 달라질 수 있지만 다시 추가될 수도 있습니다.

Vue/Svelte에서 @apply 사용하기

Vue나 Svelte 컴포넌트의 <style> 블록에서 @apply를 사용하려면, 해당 컨텍스트에서 값을 사용할 수 있도록 테마 설정을 가져와야 합니다.

CSS 출력에서 CSS 변수를 중복하지 않고 이 작업을 수행하려면, 테마를 가져올 때 theme(reference)를 사용하세요:

<template>
  <h1>Hello world!</h1>
</template>

<style>
  @import "../../my-theme.css" theme(reference);

  h1 {
    @apply font-bold text-2xl text-red-500;
  }
</style>

기본 테마를 사용하는 경우, "tailwindcss/theme"를 직접 가져올 수 있습니다:

<template>
  <h1>Hello world!</h1>
</template>

<style>
  @import "tailwindcss/theme" theme(reference);

  h1 {
    @apply font-bold text-2xl text-red-500;
  }
</style>

v3에서의 변경 사항

Tailwind CSS v4.0은 프레임워크의 새로운 메이저 버전입니다. 가능한 한 이전 버전과의 호환성을 유지하려고 노력했지만, 새로운 릴리스에서 원하는 개선 사항을 구현하기 위해 몇 가지 주요 변경 사항이 필요했습니다.

여러분이 업그레이드를 최대한 쉽게 진행할 수 있도록, 거의 모든 변경 사항을 자동으로 처리해주는 훌륭한 마이그레이션 도구를 만들었습니다.

프로젝트를 자동으로 업그레이드하려면, 프로젝트 루트에서 다음 커맨드라인 명령어를 실행하세요:

Terminal
$ npx @tailwindcss/upgrade@next

마이그레이션 도구가 작업을 마치면, 모든 변경 사항을 검토하고 프로젝트를 테스트하여 예상대로 작동하는지 확인하세요. 운이 좋다면 곧바로 새로운 버전을 사용할 수 있을 겁니다.

하지만 마이그레이션 도구를 사용하면서 문제가 발생할 경우를 대비해, 모든 변경 사항을 상세히 정리한 목록을 아래에 제공합니다.

Dependency changes

PostCSS 사용하기

Tailwind CSS v3에서는 tailwindcss 패키지가 PostCSS 플러그인이었지만, v4.0부터는 PostCSS 플러그인이 전용 @tailwindcss/postcss 패키지로 이동했습니다.

Tailwind CSS v4.0은 CSS 임포트와 벤더 프리픽싱을 자동으로 처리하므로, 프로젝트에 postcss-importautoprefixer가 있다면 제거할 수 있습니다:

postcss.config.mjs
export default {
  plugins: {
    'postcss-import': {},
    'tailwindcss': {},
    'autoprefixer': {},
    '@tailwindcss/postcss': {},
  },
};

Vite 사용하기

Vite를 사용 중이라면, PostCSS 플러그인에서 새로 제공하는 전용 Vite 플러그인으로 마이그레이션하는 것을 권장합니다:

vite.config.ts
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [
    tailwindcss()
  ],
});

Tailwind CLI 사용하기

v4.0부터 Tailwind CLI는 전용 @tailwindcss/cli 패키지로 이동했습니다. 빌드 명령어를 새로운 패키지를 사용하도록 업데이트하세요:

npx tailwindcss -i input.css -o output.css
npx @tailwindcss/cli -i input.css -o output.css

@tailwind 지시자 제거

Tailwind CSS v4.0에서는 v3에서 사용하던 @tailwind 지시자 대신 일반 CSS @import 문을 사용하여 Tailwind를 불러옵니다:

@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss";

더 이상 사용되지 않는 유틸리티 제거

v3에서 더 이상 사용되지 않고 몇 년 동안 문서화되지 않았던 유틸리티들을 제거했습니다. 다음은 제거된 항목들과 그 대체 방법을 정리한 목록입니다:

더 이상 사용되지 않는 항목대체 방법
bg-opacity-*bg-black/50와 같은 투명도 수정자 사용
text-opacity-*text-black/50와 같은 투명도 수정자 사용
border-opacity-*border-black/50와 같은 투명도 수정자 사용
divide-opacity-*divide-black/50와 같은 투명도 수정자 사용
ring-opacity-*ring-black/50와 같은 투명도 수정자 사용
placeholder-opacity-*placeholder-black/50와 같은 투명도 수정자 사용
flex-shrink-*shrink-* 사용
flex-grow-*grow-* 사용
overflow-ellipsistext-ellipsis 사용
decoration-slicebox-decoration-slice 사용
decoration-clonebox-decoration-clone 사용

container 유틸리티 설정하기

v3에서는 container 유틸리티에 centerpadding과 같은 여러 설정 옵션이 있었지만, v4.0에서는 더 이상 존재하지 않습니다. v4.0에서 container 유틸리티를 커스터마이징하려면 @utility를 사용해 확장해야 합니다:

@import "tailwindcss";

@utility container {
  margin-inline: auto;
  padding-inline: 2rem;
}

기본 그림자 스케일 변경 사항

모든 그림자 유틸리티에 이름이 부여된 값을 갖도록 기본 그림자 스케일을 약간 조정했습니다.

이를 위해 shadowshadow-sm으로, shadow-smshadow-xs로, drop-shadowdrop-shadow-sm으로, drop-shadow-smdrop-shadow-xs로 이름을 변경했습니다:

v3v4
shadow-smshadow-xs
shadowshadow-sm
drop-shadow-smdrop-shadow-xs
drop-shadowdrop-shadow-sm

shadowdrop-shadow 유틸리티는 하위 호환성을 위해 여전히 작동하지만, shadow-smdrop-shadow-sm을 각각 shadow-xsdrop-shadow-xs로 대체하지 않으면 프로젝트에서 다른 모습으로 보일 수 있습니다.

기본 블러 스케일 변경 사항

모든 블러 유틸리티에 이름이 부여된 값을 갖도록 기본 블러 스케일을 조정했습니다.

이를 위해 blurblur-sm으로, blur-smblur-xs로 이름을 변경했습니다:

v3v4
blur-smblur-xs
blurblur-sm

하위 호환성을 위해 blur 유틸리티는 여전히 작동하지만, blur-smblur-xs로 변경하지 않으면 프로젝트에서 다른 모습으로 보일 수 있습니다.

기본 border-radius 스케일 변경 사항

모든 border-radius 유틸리티에 이름이 부여된 값을 제공하기 위해 기본 border-radius 스케일을 조정했습니다.

이를 위해 roundedrounded-sm으로, rounded-smrounded-xs로 이름을 변경했습니다:

v3v4
rounded-smrounded-xs
roundedrounded-sm

하위 호환성을 위해 rounded 유틸리티는 계속 작동하지만, rounded-smrounded-xs로 변경하지 않으면 프로젝트에서 다른 모습으로 보일 수 있습니다.

기본 테두리 색상 변경

v3에서는 테두리가 기본적으로 설정된 gray-200 색상을 사용했습니다. v4에서는 이를 currentColor로 업데이트하여 모든 브라우저의 기본 동작과 일치하도록 했습니다.

이 변경 사항을 프로젝트에 반영하려면, border 유틸리티를 사용하는 곳에서 테두리 색상 유틸리티를 사용하거나, v3의 동작을 유지하기 위해 다음 CSS 코드를 프로젝트에 추가하세요:

@import "tailwindcss";

@layer base {
  *,
  ::after,
  ::before,
  ::backdrop,
  ::file-selector-button {
    border-color: var(--color-gray-200, currentColor);
  }
}

기본 링 너비 변경

v3에서는 ring 유틸리티가 3px 링을 추가했습니다. v4에서는 이를 1px로 변경하여 테두리와 아웃라인과 일관성을 유지하도록 했습니다.

이 변경 사항을 프로젝트에 적용하려면 ring을 사용한 모든 부분을 ring-3으로 바꾸세요:

<div class="ring ring-blue-500">
<div class="ring-3 ring-blue-500">
  <!-- ... -->
</div>

기본 플레이스홀더 변경

v3에서는 플레이스홀더 텍스트가 기본적으로 설정된 gray-400 색상을 사용했습니다. v4에서는 이를 단순화하여 현재 텍스트 색상을 50% 투명도로 사용하도록 변경했습니다.

이 변경 사항은 눈에 띄지 않을 수도 있고(오히려 프로젝트가 더 좋아 보일 수도 있음), v3의 동작을 유지하고 싶다면 프로젝트에 다음 CSS를 추가하면 됩니다.

@import "tailwindcss";

@layer base {
  input::placeholder,
  textarea::placeholder {
    color: theme(--color-gray-400);
  }
}

outline-none에서 outline-hidden로 변경

v3에서 outline-none 유틸리티는 단순히 outline-style: none을 설정하는 것이 아니라 복잡한 클래스였습니다:

/* v3 */
.outline-none {
  outline: 2px solid transparent;
  outline-offset: 2px;
}

실제로 이 클래스는 접근성을 위해 강제 색상 모드에서도 보이도록 투명한 2px 윤곽선을 추가했습니다.

v4.0에서는 이를 단순화하여 이제 outline-none은 예상대로 outline-style: none만 설정합니다:

/* v4 */
.outline-none {
  outline-style: none;
}

v3에서 outline-none이 했던 작업을 수행하는 새로운 outline-hidden 유틸리티를 추가했습니다. 이 기능은 여전히 매우 유용하기 때문입니다.

이 변경 사항을 프로젝트에 반영하려면, outline-style: none을 정말로 원하는 경우가 아니라면 outline-none을 사용한 모든 부분을 outline-hidden으로 바꾸세요:

<input class="focus:outline-none">
<input class="focus:outline-hidden">

커스텀 유틸리티 추가하기

v3에서는 @layer utilities 내에 정의한 모든 커스텀 클래스가 Tailwind에 의해 진정한 유틸리티 클래스로 인식되었고, hover, focus, lg와 같은 변형자(variants)와 자동으로 작동했습니다.

v4.0에서는 네이티브 캐스케이드 레이어를 사용하며 더 이상 @layer at-rule을 가로채지 않기 때문에, 이를 대체하기 위해 @utility API를 도입했습니다:

@layer utilities {
  .tab-4 {
    tab-size: 4;
  }
}
@utility tab-4 {
  tab-size: 4;
}

v4.0에서 커스텀 유틸리티는 단일 클래스 이름이어야 하며 복잡한 선택자를 사용할 수 없습니다. 만약 커스텀 유틸리티가 단일 클래스 이름보다 복잡하다면, 중첩(nesting)을 사용하여 유틸리티를 정의하세요:

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

스택 순서에 민감한 변형

v3에서는 스택된 변형이 오른쪽에서 왼쪽으로 적용되었지만, v4에서는 CSS 문법과 더 비슷하게 보이도록 왼쪽에서 오른쪽으로 적용되도록 업데이트했습니다.

이 변경 사항을 적용하려면 프로젝트에서 순서에 민감한 스택된 변형의 순서를 반대로 바꿔야 합니다:

<ul class="py-4 first:*:pt-0 last:*:pb-0">
<ul class="py-4 *:first:pt-0 *:last:pb-0">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

이러한 경우는 거의 없을 가능성이 높습니다. 직접적인 자식 변형(*)이나 타이포그래피 플러그인 변형(prose-headings)을 사용하고 있을 가능성이 가장 높으며, 그 경우에도 다른 변형과 함께 스택된 경우에만 해당됩니다.

CSS 변수를 임의 값으로 사용하기

v3에서는 var(…) 없이도 CSS 변수를 임의 값으로 사용할 수 있었습니다. 하지만 최근 CSS 업데이트로 인해 이 방식이 종종 모호해질 수 있어, v4.0에서는 대괄호 대신 괄호를 사용하는 새로운 구문으로 변경했습니다.

이 변경 사항을 적용하려면, 기존의 변수 단축 구문을 새로운 변수 단축 구문으로 바꾸면 됩니다.

<div class="bg-[--brand-color]">
<div class="bg-(--brand-color)">
  <!-- ... -->
</div>

JS에서 테마 값 참조하기

v3에서는 resolveConfig 함수를 제공했는데, 이 함수를 사용하면 JS 설정을 평평한 객체로 변환하여 다른 자바스크립트 코드에서 사용할 수 있었습니다.

v4에서는 이 기능을 제거했습니다. 대신 생성된 CSS 변수를 직접 사용하는 방식을 권장합니다. 이 방식이 훨씬 간단하며, 번들 크기를 크게 줄일 수 있습니다.

모바일에서 호버 스타일이 무시되는 문제

v4.0에서는 hover 변형을 기본 입력 장치가 호버를 지원할 때만 적용되도록 업데이트했습니다:

@media (hover: hover) {
  .hover\:underline:hover {
    text-decoration: underline;
  }
}

이 변경으로 인해 터치 기기에서 탭 시 호버가 트리거되도록 사이트를 구축한 경우 문제가 발생할 수 있습니다. 이 문제가 발생한다면, 기존 구현을 사용하는 자신만의 hover 변형을 만들어 덮어쓸 수 있습니다:

@import "tailwindcss";

@variant hover (&:hover);

하지만 일반적으로 호버 기능을 사이트의 핵심 기능이 아닌 부가적인 기능으로 취급하는 것을 권장합니다. 터치 기기는 실제로 호버 기능을 지원하지 않기 때문에, 호버에 의존하지 않는 것이 좋습니다.

코어 플러그인은 비활성화할 수 없음

v3에서는 corePlugins 옵션을 사용해 프레임워크 내 특정 유틸리티를 완전히 비활성화할 수 있었습니다. 하지만 v4.0에서는 이 기능이 더 이상 지원되지 않습니다. 다만, 이 기능이 해결하던 문제와 유사한 문제를 해결하기 위한 다양한 아이디어를 이후 베타 버전에서 탐구할 계획입니다.

`theme()` 함수 사용하기

Tailwind CSS v4.0부터는 모든 테마 값에 대해 CSS 변수를 제공하므로, 가능한 경우 theme() 함수 대신 이러한 변수를 사용하는 것을 권장합니다:

@import "tailwindcss";

.my-class {
  background-color: theme(colors.red.500);
  background-color: var(--color-red-500);
}

여전히 theme() 함수를 사용해야 하는 경우(예: CSS 변수가 지원되지 않는 미디어 쿼리에서), 기존의 점 표기법 대신 CSS 변수 이름을 사용해야 합니다:

@import "tailwindcss";

@media (width >= theme(screens.xl)) {
@media (width >= theme(--breakpoint-xl)) {
  /* ... */
}

JavaScript 설정 파일 사용하기

JavaScript 설정 파일은 이전 버전과의 호환성을 위해 여전히 지원되지만, v4.0부터는 자동으로 감지되지 않습니다.

여전히 JavaScript 설정 파일을 사용해야 한다면, @config를 사용하여 명시적으로 로드해야 합니다:

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