0
# Styled Components
1
2
Create React components with CSS-in-JS styling, variants, responsive design support, and full TypeScript integration. Styled components offer polymorphic `as` prop support, forwarded refs, and CSS prop overrides.
3
4
## Capabilities
5
6
### Styled Function
7
8
Creates styled React components from HTML elements or existing React components.
9
10
```typescript { .api }
11
/**
12
* Creates a styled React component with CSS-in-JS styling
13
* @param type - HTML element tag name or React component
14
* @param composers - Style objects, strings, functions, or other components to compose
15
* @returns Styled React component with forwardRef support and variant props
16
*/
17
function styled<
18
Type extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
19
Composers extends Array<string | React.ComponentType<any> | Function | { [name: string]: unknown }>
20
>(
21
type: Type,
22
...composers: Composers
23
): StyledComponent<Type, StyledComponentProps<Composers>, {}, CSS>;
24
25
interface StyledComponent<Type, Props = {}, Media = {}, CSS = {}>
26
extends React.ForwardRefExoticComponent<
27
ComponentProps<Type> & TransformProps<Props, Media> & { css?: CSS }
28
> {
29
/** Standard component call with variant props */
30
(props: ComponentProps<Type> & TransformProps<Props, Media> & { css?: CSS }): React.ReactElement | null;
31
32
/** Polymorphic 'as' prop call to change the rendered element type */
33
<As extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(
34
props: ComponentProps<As> & TransformProps<Props, Media> & { as: As; css?: CSS }
35
): React.ReactElement | null;
36
37
/** CSS class name generated for this component */
38
className: string;
39
/** CSS selector for targeting this component */
40
selector: string;
41
42
/** Internal symbols for type extraction */
43
[$$StyledComponentType]: Type;
44
[$$StyledComponentProps]: Props;
45
[$$StyledComponentMedia]: Media;
46
}
47
48
type StyledComponentProps<Composers extends readonly unknown[]> =
49
Composers extends readonly [infer First, ...infer Rest]
50
? First extends { variants?: infer V }
51
? V & StyledComponentProps<Rest>
52
: StyledComponentProps<Rest>
53
: {};
54
55
type TransformProps<Props, Media> = {
56
[K in keyof Props]: (
57
| Props[K]
58
| (
59
& { [KMedia in `@${keyof Media | 'initial'}`]?: Props[K] }
60
& { [KMedia in string]: Props[K] }
61
)
62
);
63
};
64
```
65
66
**Usage Examples:**
67
68
```typescript
69
import { styled, ComponentProps, CSS, $$StyledComponentType, $$StyledComponentProps, $$StyledComponentMedia } from "@stitches/react";
70
71
// Style HTML elements
72
const Button = styled('button', {
73
backgroundColor: 'blue',
74
color: 'white',
75
padding: '12px 16px',
76
border: 'none',
77
borderRadius: '4px',
78
cursor: 'pointer',
79
80
'&:hover': {
81
backgroundColor: 'darkblue'
82
}
83
});
84
85
// Style existing React components
86
const CustomInput = styled(ExistingComponent, {
87
border: '1px solid gray',
88
padding: '8px'
89
});
90
91
// Use polymorphic 'as' prop
92
function App() {
93
return (
94
<>
95
<Button>Regular button</Button>
96
<Button as="a" href="/link">Link styled as button</Button>
97
</>
98
);
99
}
100
```
101
102
### Variants
103
104
Define multiple style variations that can be controlled via props.
105
106
```typescript { .api }
107
interface VariantConfig<T = any> {
108
variants?: {
109
[variantName: string]: {
110
[variantValue: string | number]: StyleObject;
111
};
112
};
113
compoundVariants?: Array<{
114
[variantName: string]: string | number;
115
css: StyleObject;
116
}>;
117
defaultVariants?: {
118
[variantName: string]: string | number;
119
};
120
}
121
```
122
123
**Usage Examples:**
124
125
```typescript
126
const Button = styled('button', {
127
padding: '12px 16px',
128
border: 'none',
129
borderRadius: '4px',
130
131
variants: {
132
color: {
133
primary: { backgroundColor: 'blue', color: 'white' },
134
secondary: { backgroundColor: 'gray', color: 'black' },
135
danger: { backgroundColor: 'red', color: 'white' }
136
},
137
size: {
138
small: { padding: '8px 12px', fontSize: '14px' },
139
medium: { padding: '12px 16px', fontSize: '16px' },
140
large: { padding: '16px 24px', fontSize: '18px' }
141
},
142
outline: {
143
true: { backgroundColor: 'transparent', border: '2px solid' }
144
}
145
},
146
147
compoundVariants: [
148
{
149
color: 'primary',
150
outline: true,
151
css: { borderColor: 'blue', color: 'blue' }
152
}
153
],
154
155
defaultVariants: {
156
color: 'primary',
157
size: 'medium'
158
}
159
});
160
161
// Usage with variant props
162
<Button color="danger" size="large">Delete</Button>
163
<Button color="primary" outline>Outlined Primary</Button>
164
```
165
166
### CSS Prop Override
167
168
Override component styles on individual instances using the css prop.
169
170
```typescript { .api }
171
interface StyledComponentProps {
172
/** Override styles for this specific instance */
173
css?: StyleObject;
174
}
175
```
176
177
**Usage Examples:**
178
179
```typescript
180
const Card = styled('div', {
181
padding: '16px',
182
backgroundColor: 'white',
183
borderRadius: '8px'
184
});
185
186
// Override styles with css prop
187
<Card css={{ backgroundColor: 'lightgray', padding: '24px' }}>
188
Custom styled card
189
</Card>
190
```
191
192
### Responsive Design
193
194
Apply different styles based on configured media queries.
195
196
**Usage Examples:**
197
198
```typescript
199
const ResponsiveBox = styled('div', {
200
padding: '16px',
201
202
// Apply styles at different breakpoints
203
'@media (min-width: 768px)': {
204
padding: '24px'
205
},
206
207
// Or use configured media queries
208
'@bp2': {
209
padding: '32px'
210
}
211
});
212
213
// Responsive variants
214
const ResponsiveText = styled('p', {
215
variants: {
216
size: {
217
small: {
218
fontSize: '14px',
219
'@bp2': { fontSize: '16px' }
220
},
221
large: {
222
fontSize: '18px',
223
'@bp2': { fontSize: '24px' }
224
}
225
}
226
}
227
});
228
```
229
230
### Component Composition
231
232
Compose styled components together for inheritance and extension.
233
234
**Usage Examples:**
235
236
```typescript
237
// Base button
238
const BaseButton = styled('button', {
239
padding: '12px 16px',
240
border: 'none',
241
borderRadius: '4px',
242
cursor: 'pointer'
243
});
244
245
// Extend base button
246
const PrimaryButton = styled(BaseButton, {
247
backgroundColor: 'blue',
248
color: 'white'
249
});
250
251
// Further extend
252
const LargePrimaryButton = styled(PrimaryButton, {
253
padding: '16px 24px',
254
fontSize: '18px'
255
});
256
```
257
258
### Forward Ref Support
259
260
All styled components automatically support React.forwardRef for ref forwarding.
261
262
**Usage Examples:**
263
264
```typescript
265
import { useRef } from 'react';
266
267
const Input = styled('input', {
268
padding: '8px',
269
border: '1px solid gray',
270
borderRadius: '4px'
271
});
272
273
function App() {
274
const inputRef = useRef<HTMLInputElement>(null);
275
276
const focusInput = () => {
277
inputRef.current?.focus();
278
};
279
280
return (
281
<>
282
<Input ref={inputRef} placeholder="Type here..." />
283
<button onClick={focusInput}>Focus Input</button>
284
</>
285
);
286
}
287
```
288
289
## Type Safety
290
291
```typescript { .api }
292
// Extract variant props from styled component
293
type VariantProps<Component extends { [key: string]: any }> =
294
TransformProps<
295
Component[$$StyledComponentProps],
296
Component[$$StyledComponentMedia]
297
>;
298
299
// Transform props with media query support
300
type TransformProps<Props, Media> = {
301
[K in keyof Props]: Props[K] | {
302
[MediaQuery in keyof Media | '@initial']?: Props[K];
303
};
304
};
305
306
// Component props with styling support
307
type StyledComponentProps<Type, Props, Media, CSS> =
308
React.ComponentPropsWithRef<Type> &
309
TransformProps<Props, Media> &
310
{ css?: CSS; as?: never };
311
```
312
313
**Usage Examples:**
314
315
```typescript
316
// Extract props type from styled component
317
const StyledButton = styled('button', {
318
variants: {
319
size: { small: {}, large: {} },
320
color: { primary: {}, secondary: {} }
321
}
322
});
323
324
type ButtonProps = VariantProps<typeof StyledButton>;
325
// ButtonProps = { size?: 'small' | 'large'; color?: 'primary' | 'secondary' }
326
327
// Use in other components
328
function CustomButton(props: ButtonProps) {
329
return <StyledButton {...props} />;
330
}
331
```