타입스크립트로 작성하는 제로 런타임 스타일시트 라이브러리
빌드 시 생성되는 모든 스타일 - Sass , LESS 등과 유사하지만 TypeScript의 강력한 기능을 사용합니다.
type-safe token contracts을 사용하여 단일 글로벌 테마를 생성하거나 여러 테마를 생성합니다.
webpack, esbuild, Vite 및 Next.js에 대한 공식 통합이 제공됩니다.
Sprinkles, Recipes, Dessert Box와 같은 라이브러리를 사용하거나 직접 만들어보세요!
style
styleVariants
createVar
createTheme
createThemeContract
assignVars
fontFace
keyframes
createContainer
layer
addFunctionSerializer
globalStyle
createGlobalTheme
createGlobalThemeContract
globalFontFace
globalKeyframes
globalLayer
Sprinkles
Recipes
Dynamic
CSS Utils
kabab-case가 아니라 camelCase를 사용한다.
원래 단위가 없는 속성(flexGrow, opacity 등)말고는 px로 변환한다.
-를 지운 PascalCase를 사용한다.
-webkit-tap-highlight-color → WebkitTapHighlightColor
vanilla extract에서 선언되는 css variables는 vars 키워드 내부에 선언되어야 합니다.
createVar api를 통해 임의의 변수명을 생성해 참조할 수도 있습니다.
// styles.css.ts
import { style, createVar } from '@vanilla-extract/css';
const myVar = createVar();
const myStyle = style({
vars: {
'--my-global-variable': 'purple',
[myVar]: 'pink'
}
});
동일한 변수명을 참조하더라도 값은 다르게 선언될 수 있다. 아래 예시에서는 동일한 accentVar를 참조하나 클래스 명에 따라 다르게 동작하는 color 값을 볼 수 있다.
export const accentVar = createVar();
export const blue = style({
vars: {
[accentVar]: 'blue'
},
"@media": {
'(prefers-color-scheme: dark)': {
vars: {
[accentVar]: 'lightblue'
}
}
}
}
})
export const pink = style({
vars: {
[accentVar]: 'pink'
},
"@media": {
'(prefers-color-scheme: dark)': {
vars: {
[accentVar]: 'lightpink'
}
}
}
})
/* 전처리된 css variable. 각 클래스에서 --accentVar__l3kgsb2라는 동일한 변수 명을 참조하고 있으나 다른 값이 전용됨을 볼 수 있다. */
@media 키 값에 미디어 쿼리를 한 곳에 모아 작성할 수 있다.
파일의 제일 마지막에 추가되기 때문에 다른 스타일보다 우선선위가 높게 적용된다.
// styles.css.ts
import { style } from '@vanilla-extract/css';
const myStyle = style({
'@media': {
'screen and (min-width: 768px)': {
padding: 10
},
'(prefers-reduced-motion)': {
transitionProperty: 'color'
}
}
});두 가지 방법 (globalStyle에서는 사용할 수 없다.)
hover, first-of-type, before과 같은 simple pseudo selector는 style 함수 내부에서 1-depth level로 선언할 수 있습니다.
const myStyle = style({
':hover': {
color: 'pink'
},
더 복잡한 규칙을 구성할 수 있는 Seletors 옵션
&문자를 대상으로 해야 한다.export const parent = style({});
const link = style({
selectors: {
'&:hover:not(:active)': {
border: '2px solid aquamarine'
},
'nav li > &': {
textDecoration: 'underline'
}
[`${parent}:focus &`]: {
background: '#fafafa'
}
}
});
```tsx
import { style } from '@vanilla-extract/css';
// Invalid example:
export const child = style({});
export const parent = style({
selectors: {
// ❌ ERROR: Targetting `child` from `parent`
[`& ${child}`]: {...}
}
});
// Valid example:
export const parent = style({});
export const child = style({
selectors: {
[`${parent} &`]: {...}
}
});
```'& a[href]'를 전역적으로 대상으로 지정해야 하는 경우 globalStyle을 사용해야 한다./* styles.css.ts */
import { style, globalStyle } from '@vanilla-extract/css';
export const parent = style({});
globalStyle(`${parent} a[href]`, {
color: 'pink'
});
/* after transpile : CSS*/
.styles_parent__1hiof570 a[href] {
color: pink;
}Circular Selectors
/* style.css.ts */
import { style } from '@vanilla-extract/css';
export const child = style({
background: 'blue',
get selectors() {
return {
[`${parent} &`]: {
color: 'red'
}
};
}
});
export const parent = style({
background: 'yellow',
selectors: {
[`&:has(${child})`]: {
padding: 10
}
}
});
/* CSS */
.styles_child__1hiof570 {
background: blue;
}
.styles_parent__1hiof571 .styles_child__1hiof570 {
color: red;
}
.styles_parent__1hiof571 {
background: yellow;
}
.styles_parent__1hiof571:has(.styles_child__1hiof570) {
padding: 10px;
}@Container
@layer (브라우저 호환 주의)
다른 레이어와의 이름 충돌을 방지하기 위해 단일 범위의 레이어를 만들 수 있다.
// layer.css.ts
import { layer } from '@vanilla-extract/css';
export const reset = layer('reset');
export const framework = layer('framework');
export const app = layer('app');
@supports
일부 브라우저에 존재하지 않는 CSS 속성 값을 사용할 때, 배열을 사용하여 대체 값을 정의합니다.
import { style } from '@vanilla-extract/css';
export const myStyle = style({
// In Firefox and IE the "overflow: overlay" will be
// ignored and the "overflow: auto" will be applied
overflow: ['auto', 'overlay']
});