Tailwind CSS 설정 및 사용
Tailwind의 유틸리티 우선 방식을 이해하고 설정·전역 지시어·반응형 클래스로 일관된 컴포넌트 UI를 만듭니다.
이전 글들에서 CSS 모듈, Sass, CSS-in-JS 같은 여러 스타일링 방식을 살펴봤습니다. 각 방식은 고유한 장단점이 있으며 프로젝트의 요구사항에 따라 고릅니다. 이 글에서는 프론트엔드에서 널리 쓰이는 Tailwind CSS의 개념과 사용 방법을 다룹니다. Tailwind CSS는 유틸리티 우선(utility-first) CSS 프레임워크로, 미리 정의된 작은 유틸리티 클래스를 HTML 마크업에 직접 적용해 스타일을 구성합니다. 이 방식은 기존 CSS 작성 방식과 다른 접근을 제시하며, 빠른 개발 속도와 일관된 디자인 시스템 구축에 장점이 있습니다. Next.js는 Tailwind CSS 통합을 쉽고 효율적으로 지원합니다.
Tailwind CSS란 무엇인가요?
Tailwind CSS는 저수준(low-level) CSS 프레임워크입니다. btn, card 같은 의미 중심(semantic)의 클래스 이름을 미리 정의해 제공하는 대신, flex, pt-4, text-center, rotate-90처럼 CSS 속성과 값의 쌍에 직접 대응하는 많은 유틸리티 클래스를 제공합니다.
HTML 요소의 class 속성에 여러 유틸리티 클래스를 조합해 스타일을 만들며, 소스에서 실제로 쓴 유틸리티를 감지해 필요한 CSS를 컴파일 시점에 만들어 내므로 런타임 스타일 엔진이 필요하지 않습니다. 사용자 정의도 폭넓게 할 수 있어, Tailwind CSS 4에서는 전역 CSS의 @theme 블록으로 색상, 글꼴, 간격 같은 디자인 토큰을 확장합니다. sm:, md:, lg: 같은 접두사로 반응형 디자인을 쉽게 구현하고, hover:, focus:, active: 같은 접두사로 상호작용 상태의 스타일도 직접 적용할 수 있습니다.
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
버튼
</button>위 코드는 background-color, padding, font-weight, border-radius 등 여러 CSS 속성을 유틸리티 클래스로 조합해 버튼 하나를 스타일링합니다.
왜 Tailwind CSS를 사용해야 할까요? (이점)
Tailwind CSS를 쓰면 CSS 파일을 오가며 클래스 이름을 고민하거나 새로 작성하지 않고, HTML 마크업 안에서 빠르게 스타일을 적용할 수 있습니다. 공통 토큰의 간격, 색상, 글꼴 체계를 다시 쓰기 쉬워 일관된 디자인 시스템을 만들기도 좋습니다. 다만 임의의 값도 쓸 수 있으므로, 일관성은 팀의 사용 규칙에 달려 있습니다.
컴포넌트 마크업에서 어떤 유틸리티를 적용했는지 확인하기 쉬워 유지보수에도 도움이 됩니다. 다만 유틸리티는 전역 CSS이므로 CSS 모듈처럼 클래스 이름을 지역화하지는 않습니다. Tailwind는 탐지한 클래스에 해당하는 CSS만 만들며, 최종 크기는 쓴 클래스와 변형, 추가 CSS의 양에 따라 달라집니다. 브라우저에서 JavaScript로 유틸리티 CSS를 만드는 엔진이 필요 없지만, CSS 계산과 레이아웃, 페인팅 비용까지 사라지는 것은 아닙니다. 그리고 반응형 디자인은 모바일 우선으로, 접두사가 없는 클래스는 모든 화면 크기에 적용되고 md: 같은 접두사는 해당 중단점(breakpoint) 이상에 적용됩니다.
Next.js에서 Tailwind CSS 설정 및 사용하기
Next.js는 Tailwind CSS의 공식 설치 가이드를 제공하며 설정 과정도 간단합니다. 다음의 PostCSS 플러그인, @import, @theme은 Tailwind CSS 4의 설정이므로, Tailwind CSS 3 프로젝트의 지시어와 설정 파일을 그대로 섞지 않습니다. 이미 Tailwind가 연결된 프로젝트라면 현재 설정과 의존성의 버전을 확인한 뒤 예제 페이지의 세 파일만 추가하고, 아직 연결되지 않은 프로젝트만 설치 단계부터 진행합니다.
설정은 세 가지가 맞물려 동작합니다. PostCSS 설정은 CSS 처리에 Tailwind를 연결하고, globals.css의 import는 스타일 입력을 제공하며, 루트 레이아웃의 import는 앱에 그 전역 CSS를 연결합니다. 이 가운데 하나라도 빠지면 JSX에 클래스 이름을 적어도 원하는 규칙이 나타나지 않을 수 있습니다. 공식 PostCSS 설치 안내와 함께 비교해 보세요.
새 프로젝트라면 create-next-app의 기본 권장 설정을 고를 때 Tailwind가 포함됩니다. 다만 권장 설정은 src/ 디렉터리를 쓰지 않고, 16.4부터는 Cache Components도 켜므로, 이 교재와 같은 구성을 원하면 Next.js 16 프로젝트 생성처럼 설정을 직접 고르고 Tailwind 질문에 Yes를 선택합니다. 이미 설정된 프로젝트라면 설치와 설정 파일을 중복해서 추가하지 않습니다.
npx create-next-app@16 my-app-with-tailwind
# ? Would you like to use Tailwind CSS? Yes기존 프로젝트에 추가하는 경우에는 다음 단계를 따릅니다. 먼저 tailwindcss, 공식 Tailwind PostCSS 플러그인, PostCSS를 개발 의존성으로 설치합니다.
npm install -D tailwindcss @tailwindcss/postcss postcss다음으로 프로젝트 루트에 postcss.config.mjs를 만들고 Tailwind 플러그인을 등록합니다. Tailwind CSS 4의 기본 설정에는 tailwind.config.js나 content 배열이 필요하지 않습니다.
export default {
plugins: {
'@tailwindcss/postcss': {},
},
};Next.js의 전역 CSS 파일에서는 Tailwind를 한 줄로 불러옵니다. 아래의 @theme 블록은 브랜드 색상 토큰을 하나 더하는 예입니다.
@import "tailwindcss";
@theme {
--color-brand-500: #2563eb;
}Tailwind는 소스에 적힌 완전한 클래스 이름을 평문 토큰으로 탐지합니다. node_modules나 .gitignore에 들어 있는 파일처럼 기본적으로 제외되는 범위에 필요한 소스가 있다면 @source로 명시합니다. 마지막으로 src/app/layout.tsx에서 위에서 설정한 전역 CSS 파일을 import합니다.
import './globals.css';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ko">
<body>{children}</body>
</html>
);
}설정한 뒤 스타일이 빠졌다면, 증상에 맞는 입력부터 확인합니다.
NEXT · 9.4 · Tailwind CSS
스타일 누락은 처리 연결·소스 탐지·적용 조건을 확인합니다
Tailwind CSS 4 예제의 PostCSS 플러그인, globals.css의 @import, Root Layout의 import를 확인합니다. 특정 클래스만 빠진 경우에는 이름 탐지와 적용 조건을 구분합니다.
| 확인 대상 | 관련 입력 | 판단 기준 |
|---|---|---|
| 전체 유틸리티 | PostCSS 플러그인, globals.css, Root Layout import | CSS 처리 연결과 최종 스타일시트 로드를 각각 확인 |
| 동적 색상 클래스 | 조건별 완전한 클래스 이름 | bg-${tone}-600 같은 문자열 조각은 계산하지 않음; 완성된 이름으로 매핑 |
| 외부 패키지 클래스 | 자동 탐지 제외 경로와 @source | node_modules 등 탐지 밖의 필요한 소스를 명시 |
| 반응형 규칙 | 기본 클래스와 md: 등 접두사 | 기본은 모든 크기, 접두사는 해당 breakpoint 이상; 미디어 조건과 최종 규칙 확인 |
- 전체 유틸리티
- 관련 입력: PostCSS 플러그인, globals.css, Root Layout import판단 기준: CSS 처리 연결과 최종 스타일시트 로드를 각각 확인
- 동적 색상 클래스
- 관련 입력: 조건별 완전한 클래스 이름판단 기준: bg-${tone}-600 같은 문자열 조각은 계산하지 않음; 완성된 이름으로 매핑
- 외부 패키지 클래스
- 관련 입력: 자동 탐지 제외 경로와 @source판단 기준: node_modules 등 탐지 밖의 필요한 소스를 명시
- 반응형 규칙
- 관련 입력: 기본 클래스와 md: 등 접두사판단 기준: 기본은 모든 크기, 접두사는 해당 breakpoint 이상; 미디어 조건과 최종 규칙 확인
탐지기는 소스를 평문으로 읽고 알려진 유틸리티를 생성합니다. 완전한 클래스 문자열을 작성해도 화면의 적용 결과는 CSS 순서·미디어 조건·상태 조건까지 확인해야 합니다.
위 그림은 스타일이 빠졌을 때 확인할 입력을 CSS 규칙 생성과 현재 적용이라는 두 판단으로 나누어 보여 줍니다. PostCSS 플러그인과 globals.css의 @import로 이루어진 CSS 처리 연결, 그리고 대상 소스에 적힌 조건별 완전한 클래스 이름은 유틸리티 CSS를 만드는 두 개의 독립된 입력입니다. 그렇게 만든 CSS를 루트 레이아웃의 import로 화면에 로드한 뒤, 현재 요소의 className, 화면 폭, hover 같은 상태가 적용 조건을 만족하면 최종 스타일이 적용되고, 만족하지 않으면 기대한 규칙이 적용되지 않으므로 입력, 로드, 조건을 증상에 맞게 다시 확인합니다. 그림의 설명처럼 화살표는 입력과 산출물, 조건의 전달 관계이며, 클릭이 빌드 CSS를 다시 만드는 실행 흐름이 아닙니다.
아래쪽 표는 확인 대상별로 정리합니다. 전체 유틸리티가 빠졌다면 PostCSS 플러그인, globals.css, 루트 레이아웃 import를 보며 CSS 처리 연결과 최종 스타일시트 로드를 각각 확인합니다. 동적인 색상 클래스는 bg-${tone}-600 같은 문자열 조각을 계산하지 않으므로 완성된 이름으로 매핑해야 하고, 외부 패키지의 클래스는 자동 탐지에서 제외되는 node_modules 등의 필요한 소스를 @source로 명시합니다. 반응형 규칙은 기본 클래스가 모든 크기에, 접두사 클래스가 해당 중단점 이상에 적용되므로 미디어 조건과 최종 규칙을 확인합니다.
문자열 조합을 완전한 선택지로 바꾸기
tone이 blue라고 해도, 소스 탐지기는 bg-와 tone과 -600을 이어 붙인 문자열을 JavaScript처럼 실행하지 않습니다. 조건별로 bg-blue-600과 bg-red-600처럼 완전한 이름을 소스에 적고 그 가운데 하나를 고르면, 탐지 단계에서 두 클래스가 모두 보이고 화면에서는 고른 클래스가 적용됩니다. 클래스가 CSS에 만들어지는 조건과, 그 규칙이 현재 요소와 미디어, 상태에 적용되는 조건은 따로 확인합니다. 이 조건은 클래스 탐지 공식 안내에 정리되어 있습니다. 소스 제외 경로에만 있는 클래스를 @source로 등록하는 것은 CSS 규칙을 만드는 입력을 넓히는 일일 뿐, 브라우저의 클릭 핸들러를 실행하게 하거나 서버에 데이터를 저장하는 설정이 아닙니다.
다음은 두 색상만 허용하는 작은 컴포넌트입니다. 소스에 각 클래스 이름이 완전히 적혀 있고, 실행할 때 그 가운데 하나를 고릅니다. CSS 처리와 소스 탐지 범위가 연결되어 있다는 전제에서 씁니다.
type Tone = 'blue' | 'red';
const toneClasses: Record<Tone, string> = {
blue: 'bg-blue-600 hover:bg-blue-700',
red: 'bg-red-600 hover:bg-red-700',
};
export function ToneButton({ tone }: { tone: Tone }) {
return <button className={`${toneClasses[tone]} text-white px-4 py-2`}>선택 색상</button>;
}이 버튼은 표시만 할 뿐 클릭 상태를 바꾸는 핸들러는 없습니다. Tone은 개발할 때의 타입 조건이며, 외부에서 들어온 값을 실행 중에 검증하지는 않습니다. 외부 값으로 고른다면 먼저 blue나 red 가운데 하나인지 검사합니다. 폭처럼 연속적인 값을 표현할 때는 끝없이 많은 w-[...] 클래스 문자열을 조합하기보다, 검증한 값을 인라인 스타일이나 CSS 변수로 넘기는 방식도 검토합니다.
생성된 규칙과 적용된 규칙 구분하기
기본 md:는 48rem 이상이라는 최소 폭 조건입니다. 그래서 md:flex-row는 작은 화면 전용이라는 뜻이 아니며, 정확히 48rem인 폭에서도 적용됩니다. 같은 요소에 같은 속성을 서로 다르게 지정하는 클래스를 함께 두면, HTML의 클래스 나열 순서를 뒤집어도 우선순위가 바뀌지 않습니다. 예를 들어 같은 계층과 명시도에서 .flex 규칙 뒤에 .grid 규칙이 있다면 className="grid flex"여도 grid가 이깁니다. 실제 스타일시트의 순서, CSS 계층, 명시도를 확인하고, 의도한 값 하나를 조건으로 고르는 편이 분명합니다.
Tailwind CSS 사용 예시
이제 컴포넌트나 페이지의 JSX, TSX 파일에서 Tailwind CSS 유틸리티 클래스를 직접 쓸 수 있습니다. 버튼과 카드 컴포넌트를 Tailwind CSS로 스타일링해 보겠습니다. 먼저 서버 컴포넌트인 페이지가 두 컴포넌트를 가져와 배치합니다.
// 클라이언트 컴포넌트를 사용하기 위해 use client 지시어를 가진 파일 임포트
import TailwindButton from './TailwindButton';
import TailwindCard from './TailwindCard';
export default function TailwindCssPage() {
return (
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-8">
<h1 className="text-4xl font-bold text-gray-800 mb-8">
Tailwind CSS 예제
</h1>
<p className="text-lg text-gray-600 mb-12 text-center">
유틸리티 클래스를 사용하여 컴포넌트를 빠르게 스타일링합니다.
</p>
<div className="flex flex-col md:flex-row gap-8 w-full max-w-4xl">
{/* TailwindButton은 클라이언트 컴포넌트 */}
<TailwindButton />
{/* TailwindCard는 클라이언트 컴포넌트 */}
<TailwindCard title="Tailwind 카드" description="이것은 Tailwind CSS로 스타일링된 카드 컴포넌트입니다.">
<p className="text-gray-700">추가적인 내용입니다.</p>
<button className="mt-4 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors">
자세히 보기
</button>
</TailwindCard>
</div>
</div>
);
}페이지의 클래스 이름은 대부분 하나의 CSS 속성에 대응하지만, text-4xl과 text-lg처럼 글자 크기와 줄 높이를 함께 정하는 클래스도 있습니다. 예를 들어 flex flex-col items-center는 세로 방향 flex 배치와 가운데 정렬을, md:flex-row는 중간 너비(md) 이상의 화면에서만 가로 배치로 바꾸라는 뜻입니다. TailwindButton은 상태로 클릭 수를 관리하는 클라이언트 컴포넌트입니다. hover:나 active:처럼 앞에 붙은 접두사는 그 상태일 때만 뒤의 클래스를 적용하므로, 버튼은 마우스를 올리면 조금 커지고 누르는 동안 조금 작아집니다.
"use client";
import React, { useState } from 'react';
export default function TailwindButton() {
const [count, setCount] = useState(0);
return (
<div className="flex flex-col items-center p-6 bg-white rounded-xl shadow-lg w-full md:w-1/2">
<h2 className="text-2xl font-semibold text-gray-700 mb-4">카운터 버튼</h2>
<p className="text-xl text-blue-600 mb-4">현재 카운트: <span className="font-bold">{count}</span></p>
<button
onClick={() => setCount(prev => prev + 1)}
className="bg-blue-500 hover:bg-blue-600 text-white font-bold py-3 px-6 rounded-lg shadow-md transition-all duration-300 ease-in-out transform hover:scale-105 active:scale-95"
>
클릭하여 카운트 증가
</button>
<p className="mt-4 text-sm text-gray-500">이 버튼은 클라이언트 컴포넌트에서 상태를 관리합니다.</p>
</div>
);
}TailwindCard는 다음 코드에서 클라이언트 컴포넌트로 선언되어 있지만, 정적인 props와 children을 표시하는 기능만으로는 "use client"가 꼭 필요하지 않습니다. 상태를 쓰는 TailwindButton과 구분해 두세요.
"use client";
import React from 'react';
interface TailwindCardProps {
title: string;
description: string;
children?: React.ReactNode;
}
export default function TailwindCard({ title, description, children }: TailwindCardProps) {
return (
<div className="bg-white p-8 rounded-xl shadow-lg hover:shadow-xl transition-shadow duration-300 w-full md:w-1/2">
<h2 className="text-3xl font-bold text-gray-800 mb-4">
{title}
</h2>
<p className="text-gray-600 mb-6 leading-relaxed">
{description}
</p>
{children}
</div>
);
}앞에서 설명한 Tailwind CSS 설치와 설정(postcss.config.mjs, globals.css)을 마치고, src/app/tailwind-css 폴더에 위 page.tsx, TailwindButton.tsx, TailwindCard.tsx를 만듭니다. 개발 서버(npm run dev)를 실행한 뒤 http://localhost:3000/tailwind-css에 접속하면 Tailwind CSS 클래스가 적용된 UI를 볼 수 있습니다.
"클릭하여 카운트 증가" 버튼을 눌러 상태 변화와 스타일이 잘 동작하는지 확인합니다. 배경색이 바뀌는 hover 상태와 카운트가 바뀌는 클릭은 따로 확인해야 합니다. hover와 active는 CSS의 적용 조건이고, 카운트 증가는 React의 클릭 핸들러와 상태 갱신이므로, 스타일이 보인다고 핸들러가 실행되었다고 판단할 수는 없습니다. 브라우저 개발자 도구에서 요소의 클래스 목록을 보면, CSS-in-JS나 CSS 모듈과 달리 해시가 붙지 않고 작성한 유틸리티 클래스 이름이 그대로 나타납니다.
Tailwind CSS의 장점과 고려사항
Tailwind CSS를 쓰면 CSS 파일을 오가지 않고 HTML과 JSX 안에서 대부분의 스타일을 구현할 수 있어 개발 생산성이 높아지며, 공통 토큰과 유틸리티 조합을 컴포넌트에 모아 여러 화면에서 다시 쓸 수 있습니다.
고려할 점도 있습니다. 복잡한 컴포넌트에서는 class 속성이 매우 길어질 수 있습니다. @apply 지시어로 반복되는 유틸리티 묶음을 사용자 정의 클래스로 추상화할 수 있지만, 이는 Tailwind의 핵심 철학에서 벗어날 수 있습니다. 기존 CSS에 익숙한 개발자는 유틸리티 우선 방식에 적응하고, 각 스타일이 어떤 클래스 이름에 대응하는지 익히는 데 시간이 걸릴 수 있습니다.
동적인 값은 상태에 따라 이미 완성된 클래스 이름을 고르는 방식으로 표현하며, 연속적인 값은 CSS 변수나 인라인 스타일로 넘깁니다. 문자열 조각을 이어 붙여 만든 새 클래스 이름은 소스 탐지기가 계산하지 않습니다. 또한 CSS를 직접 작성할 일이 줄어 CSS의 기본 개념에 대한 이해가 얕아질 수 있다는 비판도 있습니다.
더 깊이: Tailwind CSS 4가 기대하는 브라우저와 전처리기
Tailwind CSS 4는 최신 브라우저를 전제로 설계되었습니다. Tailwind CSS의 호환성 안내에 따르면 핵심 기능이 Chrome 111, Safari 16.4, Firefox 128 이상에 기대므로, 이보다 오래된 브라우저에서는 유틸리티가 의도대로 적용되지 않을 수 있습니다. Next.js 16이 지원하는 브라우저는 Chrome·Edge 111, Firefox 111, Safari 16.4 이상이라서 둘의 기준은 Firefox에서만 어긋납니다. Firefox 111부터 127까지를 꼭 지원해야 하는 서비스라면, Next.js 문서가 오래된 브라우저 지원을 위해 따로 안내하는 Tailwind CSS 3 설정을 검토합니다.
전처리기와 함께 쓰는 방식도 달라졌습니다. Tailwind CSS 4는 Sass, Less, Stylus 같은 CSS 전처리기와 함께 쓰도록 설계되지 않았으며, Tailwind 자체가 import 묶기와 벤더 접두사 추가를 맡고 중첩과 변수는 최신 CSS로 처리합니다. 그래서 9장 2절의 Sass와 이 글의 Tailwind를 한 프로젝트에서 함께 쓰더라도, Tailwind를 불러오는 전역 CSS는 Sass 파일로 만들지 않고 일반 CSS로 두는 편이 안전합니다.
정리
- Tailwind CSS는 속성과 값에 대응하는 유틸리티 클래스를 마크업에 조합하는 유틸리티 우선 프레임워크이며, 쓴 클래스만 컴파일 시점에 CSS로 만듭니다.
- Tailwind CSS 4는
@tailwindcss/postcss플러그인,globals.css의@import "tailwindcss", 루트 레이아웃의 import로 연결하며,tailwind.config.js없이@theme으로 토큰을 확장합니다. - 소스 탐지기는 완전한 클래스 이름만 찾으므로, 동적인 클래스는 문자열 조합 대신 완성된 이름의 매핑으로 고릅니다.
- 접두사 없는 클래스는 모든 크기에,
md:같은 접두사 클래스는 해당 중단점 이상에 적용되며, 같은 속성의 충돌은 클래스 나열 순서가 아니라 스타일시트의 순서로 정해집니다. - hover와 active는 CSS의 적용 조건일 뿐이며, 클릭에 따른 상태 변화는 React의 이벤트 핸들러가 처리합니다.
연습 문제
1. 화면 폭, 클래스 선택, 상태를 따로 예상하기
기본 중단점을 바꾸지 않았고 1rem=16px이며 다른 CSS 규칙이 없다고 가정합니다. 페이지의 두 컴포넌트를 담은 flex flex-col md:flex-row 영역은 viewport 600px와 800px에서 각각 어느 방향일까요? 이어서 카운터 버튼을 두 번 누르면 0에서 어떤 값이 되는지 설명해 보세요. 마지막으로 bg- 문자열 조합만 있던 코드를 완전한 두 클래스 이름의 매핑으로 바꾸면, 왜 다시 빌드할 때 탐지 결과를 기대할 수 있는지 적어 보세요.
해설 보기
기본 md는 48rem이므로 이 전제에서는 768px 이상입니다. 600px에서는 기본 flex-col이, 800px에서는 md:flex-row가 적용됩니다. 공식 반응형 안내는 접두사 없는 규칙과 중단점 이상의 규칙을 구분합니다. 중단점 설정을 바꾸면 이 문제의 기준값도 함께 바뀝니다.
카운터는 React가 이전 값을 받아 1을 더하는 함수형 갱신을 두 번 처리하므로 2가 됩니다. Tailwind의 hover, active 클래스가 카운트 값을 바꾸는 것은 아닙니다. 완전한 클래스 이름의 매핑은 소스 탐지기의 입력에 그 이름을 제공하지만, 그 소스가 실제 탐지 대상이고 CSS 처리가 연결되어 있어야 한다는 조건도 필요합니다. 탐지 입력을 고치는 것과, 이미 로드된 브라우저의 스타일시트가 갱신되는 과정도 구별합니다.
2. 문자열 조합과 탐지기
소스에는 `bg-${tone}-600` 조합만 있고, 완전한 색상 클래스는 다른 탐지 대상에도 없습니다. 런타임에 tone이 blue가 되면 탐지기가 그 코드의 실행 결과를 알아서 계산할까요? ToneButton의 매핑으로 바꾸면 어떤 입력이 달라질까요?
해설 보기
계산하지 않습니다. 탐지기는 소스를 평문으로 읽을 뿐, 프로그램의 문자열 조합을 실행하지 않습니다. 매핑으로 바꾸면 소스에 bg-blue-600, bg-red-600과 hover 클래스의 완전한 이름이 생깁니다. 그 소스가 실제 탐지 대상이고 CSS 처리가 연결되어 있어야 생성 입력에 반영되며, 런타임에는 허용한 색상에 맞는, 이미 만들어진 클래스를 고릅니다.
3. 중단점의 기준 폭
기본 md=48rem, 1rem=16px이고 다른 규칙이 없다고 가정합니다. flex flex-col md:flex-row는 viewport 767px와 768px에서 각각 어떤 방향일까요?
해설 보기
767px에서는 column, 768px에서는 row입니다. 48 × 16 = 768이므로 md 규칙은 768px 이상에서 적용되며, 접두사 없는 기본 column은 md보다 작은 폭에서 유지됩니다. 중단점을 바꾸거나 추가 CSS가 있다면 그 조건도 다시 적용해야 합니다.
4. 같은 속성을 지정한 두 클래스
같은 CSS 계층과 명시도에서 .flex { display: flex } 뒤에 .grid { display: grid }가 있고 다른 규칙은 없습니다. class="grid flex"와 class="flex grid" 가운데 어느 쪽이 grid일까요? 혼동을 줄이려면 코드를 어떻게 만들면 좋을까요?
해설 보기
두 경우 모두 grid입니다. 주어진 조건에서는 스타일시트에서 뒤에 있는 .grid가 같은 속성을 덮으며, HTML의 클래스 문자열 순서는 이 규칙 순서를 바꾸지 않습니다. grid와 flex 가운데 원하는 클래스 하나만 조건에 따라 고르면 같은 속성의 충돌을 피할 수 있습니다.
5. hover와 클릭 구분하기
TailwindButton의 카운트는 0입니다. 버튼 위에 포인터만 올린 뒤 두 번 클릭했습니다. hover만 한 시점과 두 번 클릭한 뒤의 카운트는 무엇일까요? ToneButton도 같은 카운트를 저절로 늘릴까요?
해설 보기
hover만 했을 때는 0이고, 두 번 클릭한 뒤에는 2입니다. 카운트를 늘리는 것은 setCount(prev => prev + 1)이 연결된 클릭 핸들러입니다. ToneButton에는 그 핸들러와 카운트 상태가 없으므로, 색상과 hover 클래스를 붙였다는 이유로 카운트가 늘어나지 않습니다.
Tailwind CSS를 Next.js에 연결하는 공식 절차는 Next.js 문서의 Tailwind CSS 안내에서도 확인할 수 있습니다.
이것으로 9장을 마칩니다. 9장에서는 CSS 모듈, Sass, CSS-in-JS, Tailwind CSS로 Next.js 애플리케이션에 스타일을 입히는 방법과 각 방식을 고르는 기준을 정리했습니다. 다음 장의 Auth.js 설정부터는 Auth.js로 사용자 인증을 구현하는 방법을 알아봅니다.