본문 바로가기

Frontend Dev Log

TailwindCSS v4!! v3와 달라진 점!!!!

오늘은 버전 업그레이드가 된 TailwindCSS v4 사용법에 대해 이야기 해보려고 한다.

 

보통 나는 프론트엔드 개발을 할 때 Next.js + TailwindCSS를 사용한다. 이번에 우연히 새로운 프로젝트를 셋팅하게 됐는데, 이전처럼 셋팅하니 에러가 난다?

⨯ ./app/globals.css  

Error evaluating Node.js code  

Error: It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin. The PostCSS plugin has moved to a separate package, so to continue using Tailwind CSS with PostCSS you'll need to install `@tailwindcss/postcss` and update your PostCSS configuration.

    [at We (/Users/jeongjin-ug/jinuk_project/clone_coding/drive-sys/node_modules/tailwindcss/dist/lib.js:35:2121)]

    [at eval (turbopack:///[project]/postcss.config.mjs/transform.ts:66:14)]

    [at <anonymous>]

    [at Module.init (turbopack:///[project]/postcss.config.mjs/transform.ts:53:33)]

    [at run (turbopack:///[turbopack-node]/ipc/evaluate.ts:77:20)]

근데 좀 이상했다. v3까지는 당연히 따라오던 tailwind.config 파일과 postcss.config 파일이 제대로 작동하지 않았고, 심지어 공식 문서에서는 “설정 없이도 시작 가능”이라는 메시지가 보였다.

 
Tailwindcss v4 공식 문서 중 일부

그래서 Reddit이나 Stack Overflow, 공식 문서 등등 찾아보다가 ‘v4가 v3랑 셋팅법이 좀 달라졌구나~’라고 생각이 들어서 뭐가 다른지 블로그를 남기게 되었다.

 

(v3셋팅대로 하면 에러나고, 에러를 고쳐서 커스텀 색상 클래스가 안 먹더라 하…)

 

기존 v3의 Tailwind 셋팅 방식

TailwindCSS v3는 설정 중심의 구조였다. 거의 모든 설정은 tailwind.config와 postcss.config에 모여있었다.

 

tailwind.config.ts 예시:

import type { Config } from "tailwindcss";

const config: Config = {
  content: ["./src/**/*.{ts,tsx}"],
  theme: {
    extend: {
      colors: {
        primary: "#FF5570",
      },
    },
  },
  plugins: [],
};

export default config;

 

global.css 예시:

@tailwind base;
@tailwind components;
@tailwind utilities;

---

그리고 여기에 autoprefixer나 postcss-import 등은 별도 설치가 필요했었다.

 

postcss.config.mjs 예시:

export default {
  plugins: {
    'postcss-import': {},       // CSS 파일 간 import 지원
    'tailwindcss': {},          // Tailwind CSS 적용
    'autoprefixer': {},         // 브라우저 벤더 프리픽스 자동 추가
  },
};

 

Tailwind v4의 새로운 설정 흐름

v4는 설정 철학이 좀 다르다. 핵심은 두 가지다.

“CSS-first 구성”

  • CSS 파일 내에서 @config, @theme inline을 통해 설정 가능

“PostCSS 자동화”

  • 별도 autoprefixer, postcss-import 없이 @tailwindcss/postcss만 사용
항목 v3 v4
설정 중심 tailwind.config.ts CSS 파일 (globals.css)
import 방식 @tailwind 3종 @import "tailwindcss" 한 줄
설정 전달 방식 PostCSS + JS 객체 @config, @theme inline
자동 처리 X prefix, import 자동 내장

 

완성한 Tailwind CSS v4 설정 코드

tailwind.config.ts (선택 옵션)

import type { Config } from 'tailwindcss';
import "tailwindcss-animated";

const config: Config = {
    content: [                                                              // which files to search for tailwind classes
        './app/**/*.{js,ts,jsx,tsx}',                                       /* → Find tailwind classes used as class ='' in files defined here and convert them to CSS */
        './components/**/*.{js,ts,jsx,tsx}',                                 
    ],                                                                      
    theme: {                                                                       
        extend: {                                                           // setting to extend the default tailwind theme
            colors: {
                brand: {                                                    // set brand color
                    DEFAULT: "#FA7275",                                     /* → Register custom color: Use like bg-brand, text-red, bg-light-200 */
                    100: "#EA6365",
                },
                red: "#FF7474",
                error: "#B80000",
                green: "#3DD9B3",
                orange: "#F9AB72",
                blue: "#56BBFF",
                pink: "#EEA8FD",
                light: {
                    100: "#333F4E",
                    200: "#A3B2C7",
                    300: "#F2F5F9",
                    400: "#F2F4F8",
                },
                dark: {
                    100: "#04050C",
                    200: "#131524"
                }
            },
            fontFamily: {                                                   // set font family
                poppins : [                                                 /* → Resister a custom font (ususally a variable declared as @font-face or Google Fonts) with a class name*/
                    "var(--font-poppins)"
                ]
            },
            boxShadow: {                                                    // custome shadow setting:
                "drop-1": "0px 10px 30px 0px rgba(66, 71, 97, 0.1)",        // drop-1: default shadow
                "drop-2": "0px 8px 30px 0 rgba(65, 89, 214, 0.3)",          // drop-2: accent shadow     
                "drop-3": "0px 8px 30px 0 rgba(65, 89, 214, 0.1)",          // drop-3: accent shadow
            },
            borderRadius: {                                                 // set border radius
                lg: "var(--radius)",                                        /* → tailwind default rounded-lg classes are mapped to values set here */
                md: "calc(var(--radius) - 2px)",
                sm: "calc(var(--radius) - 4px)",
            },
            keyframes: {                                                    // custom animation setting:
                "caret-blink": {                                            /* → custom animation available with tailwind utility animate-caret-blink */
                    "0%, 70%, 100%" : { opacity: "1" },
                    "20%, 50%" : { opacity: "0" }
                }
            },
            animation: {
                "caret-blink": "caret-blink 1.25s ease-out infinite",
            },
        },
    },
    plugins: [                                                              // external tailwind plugins
        require("tailwindcss-animate"),                                    // tailwindcss-animated: animation plugin
    ]
};

export default config;

 

app/globals.css

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

:root {
  --background: #ffffff;
  --foreground: #171717;
}

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
}

@media (prefers-color-scheme: dark) {
  :root {
    --background: #0a0a0a;
    --foreground: #ededed;
  }
}

body {
  background: var(--background);
  color: var(--foreground);
}

 

postcss.config.mjs

export default {
  plugins: {
    "@tailwindcss/postcss": {}, // 이거 하나면 끝
  },
};

 

 

 

만약, tailwind.config.ts를 사용하기 싫다면?

→ Tailwind CSS v4에서는 기존 tailwind.config.ts에 작성하던 설정 코드를 globals.css에 직접 작성하면 된다. 이제 설정은 config가 아니라 globals.css에다 쓴다 — @config, @theme inline, CSS 변수로.

 

https://www.reddit.com/r/tailwindcss/comments/1i9e7k2/solution_tailwind_v4_missing_tailwindconfigjs/

 

From the tailwindcss community on Reddit: (Solution) Tailwind V4 Missing tailwind.config.js

Explore this post and more from the tailwindcss community

www.reddit.com

이건 내가 봤던 Reddit 글이다. 참고하면 좋을듯?

(Reddit이 참 노다지야 노다지)

Tailwind v4 공식 문서

Vite 프로젝트라면, PostCSS 플러그인을 굳이 설정하지 않아도 @tailwindcss/vite 플러그인 하나만 사용해도 모든 설정이 가능하다고 한다!

참고: https://tailwindcss.com/docs/upgrade-guide#using-vite

 

Upgrade guide - Getting started

Upgrading your Tailwind CSS projects from v3 to v4.

tailwindcss.com

 

 

끝내는 말

v4로 변한 걸 모르고 있다가, 셋팅 할 때 에러가 나서 좀 당황했다.. 그런데 뭐 알고보니까 디자인 시스템 연결성을 조금 더높여준 업그레이드인 거 같다는 생각이 들었다. 설정 파일을 줄이면서 선택옵션으로는 사용할 수 있는 구조가 마음에 들었다.

 

v3에서 v4로 옮겨가면서 느낀 핵심!

  • 설정 파일이 더는 필수가 아니라는 점
  • CSS 파일 하나로 색상, 폰트, 다크 모드까지 커버 가능하다는 점
  • 협업 효율?이 올라가고, 파일은 줄어든다는 점

 

결론은 ‘v4 좋은 거 같다!’