React implementation of Stitches CSS-in-JS library with type-safe styling and variants
—
Generate CSS classes with variants and compound variants for maximum flexibility. The css function creates reusable CSS classes that can be applied to any element or component without React component overhead.
Creates CSS classes with variants and compound variants for reusable styling.
/**
* Creates a CSS class with optional variants and compound variants
* @param composers - Style objects, strings, functions, or other components to compose
* @returns CSS component function with className and selector properties
*/
function css<
Composers extends Array<string | React.ComponentType<any> | Function | { [name: string]: unknown }>
>(
...composers: Composers
): CssComponent<'span', StyledComponentProps<Composers>, {}, CSS>;
interface CssComponent<Type = 'span', Props = {}, Media = {}, CSS = {}> {
/** Apply CSS class with optional variant props and responsive variants */
(props?: TransformProps<Props, Media> & { css?: CSS } & { [name: string]: any }):
string & { className: string; selector: string; props: any };
/** CSS class name generated for this style */
className: string;
/** CSS selector for targeting this class */
selector: string;
/** Internal symbols for type extraction */
[$$StyledComponentType]: Type;
[$$StyledComponentProps]: Props;
[$$StyledComponentMedia]: Media;
}
type StyledComponentProps<Composers extends readonly unknown[]> =
Composers extends readonly [infer First, ...infer Rest]
? First extends { variants?: infer V }
? V & StyledComponentProps<Rest>
: StyledComponentProps<Rest>
: {};
type TransformProps<Props, Media> = {
[K in keyof Props]: (
| Props[K]
| (
& { [KMedia in `@${keyof Media | 'initial'}`]?: Props[K] }
& { [KMedia in string]: Props[K] }
)
);
};Usage Examples:
import { css, CSS, TransformProps, StyledComponentProps, $$StyledComponentType, $$StyledComponentProps, $$StyledComponentMedia } from "@stitches/react";
// Basic CSS class
const buttonStyles = css({
padding: '12px 16px',
borderRadius: '4px',
border: 'none',
cursor: 'pointer',
backgroundColor: 'blue',
color: 'white'
});
// Apply to JSX elements
function Button({ children }) {
return <button className={buttonStyles()}>{children}</button>;
}
// Or get just the class name
const className = buttonStyles.className;Create CSS classes with multiple style variations controlled by props.
interface CssVariantConfig {
variants?: {
[variantName: string]: {
[variantValue: string | number]: StyleObject;
};
};
compoundVariants?: Array<{
[variantName: string]: string | number;
css: StyleObject;
}>;
defaultVariants?: {
[variantName: string]: string | number;
};
}Usage Examples:
const cardStyles = css({
padding: '16px',
backgroundColor: 'white',
borderRadius: '8px',
variants: {
size: {
small: { padding: '12px', fontSize: '14px' },
medium: { padding: '16px', fontSize: '16px' },
large: { padding: '24px', fontSize: '18px' }
},
elevation: {
flat: { boxShadow: 'none' },
low: { boxShadow: '0 2px 4px rgba(0,0,0,0.1)' },
high: { boxShadow: '0 8px 16px rgba(0,0,0,0.15)' }
},
color: {
neutral: { backgroundColor: 'white' },
primary: { backgroundColor: 'lightblue' },
success: { backgroundColor: 'lightgreen' },
warning: { backgroundColor: 'lightyellow' },
danger: { backgroundColor: 'lightcoral' }
}
},
compoundVariants: [
{
size: 'large',
elevation: 'high',
css: { padding: '32px' }
}
],
defaultVariants: {
size: 'medium',
elevation: 'low',
color: 'neutral'
}
});
// Usage with variant props
function Card({ size, elevation, color, children }) {
return (
<div className={cardStyles({ size, elevation, color })}>
{children}
</div>
);
}
// Or apply specific variants
<div className={cardStyles({ size: 'large', color: 'primary' })}>
Large primary card
</div>Compose multiple CSS classes together for complex styling.
Usage Examples:
const baseBox = css({
padding: '16px',
borderRadius: '4px'
});
const coloredBox = css(baseBox, {
backgroundColor: 'lightblue',
border: '1px solid blue'
});
const interactiveBox = css(coloredBox, {
cursor: 'pointer',
transition: 'all 0.2s ease',
'&:hover': {
backgroundColor: 'blue',
color: 'white'
}
});
// Use composed classes
<div className={interactiveBox()}>
Interactive colored box
</div>Apply different styles based on media queries within CSS classes.
Usage Examples:
const responsiveGrid = css({
display: 'grid',
gap: '16px',
gridTemplateColumns: '1fr',
'@media (min-width: 768px)': {
gridTemplateColumns: 'repeat(2, 1fr)',
gap: '24px'
},
'@media (min-width: 1024px)': {
gridTemplateColumns: 'repeat(3, 1fr)',
gap: '32px'
}
});
// Or use configured breakpoints
const responsiveText = css({
fontSize: '16px',
lineHeight: 1.4,
'@bp2': {
fontSize: '18px',
lineHeight: 1.5
},
'@bp3': {
fontSize: '20px',
lineHeight: 1.6
}
});Generate CSS classes dynamically based on runtime conditions.
Usage Examples:
const dynamicButton = css({
padding: '12px 16px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
variants: {
theme: {
light: {
backgroundColor: 'white',
color: 'black',
border: '1px solid gray'
},
dark: {
backgroundColor: 'black',
color: 'white',
border: '1px solid gray'
}
},
loading: {
true: {
opacity: 0.6,
cursor: 'not-allowed',
pointerEvents: 'none'
}
}
}
});
function DynamicButton({ theme, loading, children, ...props }) {
return (
<button
className={dynamicButton({ theme, loading })}
{...props}
>
{loading ? 'Loading...' : children}
</button>
);
}Work with CSS class metadata and selectors for advanced use cases.
Usage Examples:
const myStyles = css({
color: 'blue',
padding: '16px'
});
// Get class name for external use
const className = myStyles.className;
console.log(className); // "c-abc123"
// Get CSS selector
const selector = myStyles.selector;
console.log(selector); // ".c-abc123"
// Use in CSS-in-JS libraries or global styles
const globalStyles = css({
[`${myStyles.selector}:hover`]: {
color: 'red'
}
});Use CSS custom properties and variables within CSS classes.
Usage Examples:
const themedComponent = css({
'--primary-color': 'blue',
'--spacing': '16px',
backgroundColor: 'var(--primary-color)',
padding: 'var(--spacing)',
variants: {
theme: {
dark: {
'--primary-color': 'darkblue',
'--spacing': '20px'
}
}
}
});
// CSS custom properties work with theme tokens
const tokenBasedStyles = css({
'--card-bg': '$colors$cardBackground',
'--card-padding': '$space$4',
backgroundColor: 'var(--card-bg)',
padding: 'var(--card-padding)'
});// Extract variant props from CSS component
type VariantProps<CssComponent> = CssComponent extends (props: infer P) => any
? P
: never;
// CSS component function signature
interface CssComponentFunction<Props = {}> {
(props?: Props): string & {
className: string;
selector: string;
props: Props;
};
}Usage Examples:
const styledCard = css({
variants: {
size: { small: {}, large: {} },
color: { primary: {}, secondary: {} }
}
});
// Extract variant props type
type CardProps = VariantProps<typeof styledCard>;
// CardProps = { size?: 'small' | 'large'; color?: 'primary' | 'secondary' }
// Use in component props
interface MyCardProps extends CardProps {
title: string;
children: React.ReactNode;
}
function MyCard({ title, children, ...styleProps }: MyCardProps) {
return (
<div className={styledCard(styleProps)}>
<h3>{title}</h3>
{children}
</div>
);
}Install with Tessl CLI
npx tessl i tessl/npm-stitches--react