Vanilla Extract
Published at 2025-03-25
Vanilla Extract
날짜: 2025년 3월 25일
Vanilla Extract는 TypeScript 기반의 CSS-in-JS 라이브러리로, 정적 CSS를 생성하면서도 타입 안정성을 제공하는 것이 특징입니다.
Vanilla Extract VS Styled-Components
특징 | Vanilla Extract 🌿 | Styled-Components 🎨 |
---|---|---|
스타일 적용 방식 | 정적 CSS 파일 생성 (Zero-runtime) | 런타임에 동적으로 생성 |
사용 언어 | TypeScript 기반 | JavaScript 기반 |
CSS 변수 지원 | 디자인 토큰 관리 가능 | ThemeProvider 사용 |
스타일링 방식 | 클래스를 직접 사용 | JSX 내에서 styled.div 등 사용 |
Vanilla Extract에서 스타일링
[button.css.ts]
import { style } from '@vanilla-extract/css';
export const primaryButton = style({
padding: '10px 20px',
borderRadius: '5px',
border: 'none',
backgroundColor: 'blue',
color: 'white',
});
[Button.tsx]
import React from 'react';
import { button } from './button.css';
export default function Button() {
return <button className={primaryButton}>Click Me</button>; // 생성된 클래스를 `className`에 할당
}
직접 props를 전달 받을 수 없는 Vanilla Extract에서 동적 스타일링 하는 방법
- className을 조건부로 변경
- css 변수로 props 값을 동적으로 사용
예시
- 인풋 1에서 입력한 값으로 인풋 2의 width 를 변경해보기
[input.css.ts]
import { style } from '@vanilla-extract/css';
export const input = style({
padding: '8px',
border: '1px solid #ccc',
borderRadius: '4px',
fontSize: '16px',
width: 'var(--dynamic-width, 200px)', // 변수 이름 정의
});
[input.tsx]
import React, { useState } from 'react';
import { input } from './input.css';
export default function InputComponent() {
const [width, setWidth] = useState<number>(200); // 기본값 200px
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
const numericValue = value ? Number(value) : 0; // 숫자만 받도록 처리
setWidth(numericValue);
};
return (
<div>
{/* 1번 인풋 - 숫자 입력 */}
<input
type="number"
value={width}
onChange={handleInputChange}
placeholder="Enter width"
style={{ marginBottom: '10px' }}
/>
<br />
{/* 2번 인풋 - width 값에 따라 동적으로 변경 */}
<input
className={input}
style={{ '--dynamic-width': `${width}px` } as React.CSSProperties} // 설정한 변수로 값 적용
placeholder="Resizable Input"
/>
</div>
);
}
CSS-in-JS?
- CSS를 JavaScript 코드 안에서 정의하고 컴포넌트와 함께 관리할 수 있다.
- props나 state 값에 따라 스타일을 실시간으로 변경할 수 있다.
css 파일에서 디자인 토큰 예시:
[.css]
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--font-size-small: 12px;
--font-size-medium: 16px;
--font-size-large: 24px;
}
.button {
background-color: var(--primary-color);
font-size: var(--font-size-medium);
}