tailwindCSS v4
선호하는 스타일링 라이브러리에 대한 질문을 받으면, 나는 언제나 '디자인 시스템이 잘 갖춰진 프로젝트라면 tailwindCSS(이하 테일윈드)를, 그렇지 않은 경우라면 moduleCSS를 선택한다'고 답해왔다. 그러나 오늘부터는 이 대답의 결이 조금 달라질 것 같다. 새로운 버전의 테일윈드가 출시되었고, 이 라이브러리의 메인테이너가 내린 많은 결정들이 내 마음에 쏙 들었기 때문이다.
Theme variables
이전까지만 해도 테일윈드의 클래스를 입맛대로 수정하려면 tailwind.config.ts를 사용해야 했다. 아래는 내가 실제로 작성했던 설정 파일 일부이다. spacing의 값을 rem으로 덮어쓰기 위해 여러 과정을 거치고 있고, [ 이런 ] 어처구니 없는 문제를 맞닥트리기도 했다.
import type { Config } from "tailwindcss";
const range = (start: number, end: number) => {
let arr = [];
let length = end - start;
for (let i = 0; i <= length; i++) {
arr[i] = start;
start++;
}
return arr;
};
type Accum = {
[key: string]: string;
};
const accum: Accum = range(0, 1600).reduce((acc, px) => {
acc[`${px}`] = `${px / 10}rem`;
return acc;
}, {} as Accum);
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./utils/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
spacing: {
...accum,
},
새로운 버전의 테일윈드는 @theme이라는 사용자 정의 앳룰을 제공한다. 이와 함께 추가된 테마 변수를 사용하면 손쉽게 새로운 클래스를 생성하거나 기존의 클래스를 덮어쓸 수 있다.
예를 들어보자. 이전 버전에서 나는 0부터 1600까지의 spacing을 정의하기 위해서 실제로 1601개의 클래스 네임을 생성해야 했다. 하지만 새로운 버전에서는 --spacing 테마 변수 하나로 이를 정의할 수 있다. 아래는 클래스 내부에서 크기를 계산할 때 --spacing 테마 변수를 추종하는 일부 속성을 나열한 것이다.
// css
@theme {
--spacing: 0.1rem;
}
// class definition
w-<number> | width: calc(var(--spacing) * <number>);
min-w-<number> | min-width: calc(var(--spacing) * <number>);
max-w-<number> | max-width: calc(var(--spacing) * <number>);
h-<number> | height: calc(var(--spacing) * <number>);
min-h-<number> | min-height: calc(var(--spacing) * <number>);
max-h-<number> | max-height: calc(var(--spacing) * <number>);
p-<number> | padding: calc(var(--spacing) * <number>);
m-<number> | margin: calc(var(--spacing) * <number>);
gap-<number> | gap: calc(var(--spacing) * <value>);
leading-<number> | line-height: calc(var(--spacing) * <number>)
이와 관련된 더 자세한 내용은 공식 문서의 [ theme variables ]에서 확인할 수 있으며, 참고로 남겨놓자면 --spacing 테마 변수의 기본 값은 0.25rem이며 아쉽게도 font-size는 --spacing 테마 변수를 추종하지 않는다(까비 아깝소).
Dynamic Utility Values
이전 버전에서는 정적인 값만 지원되었으나, 4.0부터는 동적으로 계산된 값도 사용할 수 있다. 참고로 css 변수를 사용할 때는 대괄호가 아니라 소괄호를 사용해야 한다.
<div class="hover:bg-[hsl(200,100%,50%)] active:scale-[1.25]">
<div class="hover:bg-[hsl(200,100%,50%)] active:scale-(--large-scale)">
opacity
기존에는 배경이나 글자 등의 투명도를 조절하기 위해 `bg-opacity-*` 등의 클래스를 사용해야 했다. 새로운 버전의 테일윈드에서는 분수(fraction) 형태로 이를 조절할 수 있게 되었다.
bg-black/50
text-black/50
border-black/50
placeholder-black/50
container query
지난 버전에서는 플러그인으로 제공되었던 컨테이너 쿼리가 새로운 버전에 공식적으로 포함되었다. container-name도 사용할 수 있으며, `--container-*` 테마 변수를 사용해 컨테이너의 크기에 따라 동적으로 스타일을 변경시킬 구간을 추가할 수 있다. 컨테이너 쿼리가 추가된 것은 좋지만 anchor position 관련 스타일은 없는 게 조금 아쉽긴 하다.
<div class="@container/main">
<!-- ... -->
<div class="flex flex-row @sm/main:flex-col">
<!-- ... -->
</div>
</div>
컨테이너 쿼리 길이 단위를 사용하려면 대괄호를 써야한다.
<div class="@container">
<div class="w-[50cqw]">
<!-- ... -->
</div>
</div>
data attributes
data-* 속성은 표준이 아닌 속성이나 추가적인 DOM 속성과 같은 다른 조작을 하지 않고도, 의미론적 표준 HTML 요소에 추가 정보를 저장할 수 있게 한다. 테일윈드에서는 세 가지 방식으로 이 속성에 대한 스타일링을 지원한다.
// data-*의 존재 유무
<div data-active class="data-active:border-purple-500">
<!-- ... -->
</div>
// 특정 data-* 값 일치
<div data-size="large" class="data-[size=large]:p-8">
<!-- ... -->
</div>
// custom-variant 사용
@custom-variant data-checked (&[data-ui~="checked"]);
<div data-ui="checked active" class="data-checked:underline">
<!-- ... -->
</div>
open
새로운 버전에는 <details>나 <dialog>, popover API가 open 상태일 때 조건부로 스타일링하기 위해 상태 기반 유틸리티 클래스 open이 추가되었다.
<div>
<button popovertarget="my-popover">Open Popover</button>
<div popover id="my-popover" class="opacity-0 open:opacity-100 ...">
<!-- ... -->
</div>
</div>
자식 및 자손 선택자
<li class="py-4 first:pt-0 ...">
<li class="py-4 last:pb-0 ...">
<li class="py-4 only:py-0 ...">
<li class="py-4 odd:py-0 ...">
<li class="py-4 even:py-0 ...">
<div class="nth-3:underline">
<div class="nth-last-5:underline">
<div class="nth-of-type-4:underline">
<div class="nth-last-of-type-6:underline">
<div class="nth-[2n-1]:underline">
<a href="#" class="mr-2 first-of-type:mr-6 ...">
<a href="#" class="mr-2 last-of-type:mr-6 ...">
<a href="#" class="mr-2 only-of-type:mr-6 ...">
tailwindCSS in next.js 15
이 포스트를 쓰고 있는 현재까지도 next.js는 4버전이 아니라 3.4.1 버전의 테일윈드를 사용하고 있다. 따라서 업데이트를 해주어야 하는데, 그 방식은 아래와 같다. 설치되어있는 tailwind.config.js 파일의 경우 4버전에서는 더이상 쓸모가 없으므로 삭제해주면 된다.
// Tailwind CSS 설치
npm install tailwindcss@next @tailwindcss/postcss@next -D
// postcss 파일 수정
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
'@tailwindcss/postcss': {},
},
};
export default config;
// globals.css 수정
@import 'tailwindcss';
@theme {}
블로그의 정보
Ayden's journal
Beard Weard Ayden