0
# Property Definition
1
2
Core functionality for defining atomic CSS properties with conditions, shorthands, and responsive configurations. This is the foundation for creating custom utility class systems.
3
4
## Capabilities
5
6
### defineProperties
7
8
Defines a collection of utility classes with properties, conditions and shorthands. Supports multiple overloads for different configuration combinations.
9
10
```typescript { .api }
11
/**
12
* Define properties with conditions, shorthands, and responsive arrays
13
*/
14
function defineProperties<
15
Properties extends AtomicProperties,
16
ResponsiveLength extends number,
17
Conditions extends BaseConditions,
18
Shorthands extends { [shorthandName: string]: Array<keyof Properties> },
19
DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
20
>(
21
options: ConditionalAtomicOptions<Properties, Conditions, DefaultCondition> &
22
ShorthandOptions<Properties, Shorthands> &
23
ResponsiveArrayOptions<Conditions, ResponsiveLength>
24
): ConditionalWithResponsiveArrayAtomicStyles<
25
Properties,
26
Conditions,
27
ResponsiveLength,
28
DefaultCondition
29
> & ShorthandAtomicStyles<Shorthands>;
30
31
/**
32
* Define properties with conditions and shorthands
33
*/
34
function defineProperties<
35
Properties extends AtomicProperties,
36
Conditions extends BaseConditions,
37
Shorthands extends { [shorthandName: string]: Array<keyof Properties> },
38
DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
39
>(
40
options: ConditionalAtomicOptions<Properties, Conditions, DefaultCondition> &
41
ShorthandOptions<Properties, Shorthands>
42
): ConditionalAtomicStyles<Properties, Conditions, DefaultCondition> &
43
ShorthandAtomicStyles<Shorthands>;
44
45
/**
46
* Define properties with conditions and responsive arrays
47
*/
48
function defineProperties<
49
Properties extends AtomicProperties,
50
Conditions extends BaseConditions,
51
ResponsiveLength extends number,
52
DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
53
>(
54
options: ConditionalAtomicOptions<Properties, Conditions, DefaultCondition> &
55
ResponsiveArrayOptions<Conditions, ResponsiveLength>
56
): ConditionalWithResponsiveArrayAtomicStyles<
57
Properties,
58
Conditions,
59
ResponsiveLength,
60
DefaultCondition
61
>;
62
63
/**
64
* Define properties with conditions only
65
*/
66
function defineProperties<
67
Properties extends AtomicProperties,
68
Conditions extends BaseConditions,
69
DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
70
>(
71
options: ConditionalAtomicOptions<Properties, Conditions, DefaultCondition>
72
): ConditionalAtomicStyles<Properties, Conditions, DefaultCondition>;
73
74
/**
75
* Define unconditional properties with shorthands
76
*/
77
function defineProperties<
78
Properties extends AtomicProperties,
79
Shorthands extends { [shorthandName: string]: Array<keyof Properties> }
80
>(
81
options: UnconditionalAtomicOptions<Properties> &
82
ShorthandOptions<Properties, Shorthands>
83
): UnconditionalAtomicStyles<Properties> & ShorthandAtomicStyles<Shorthands>;
84
85
/**
86
* Define unconditional properties only
87
*/
88
function defineProperties<Properties extends AtomicProperties>(
89
options: UnconditionalAtomicOptions<Properties>
90
): UnconditionalAtomicStyles<Properties>;
91
```
92
93
### Configuration Options
94
95
The defineProperties function accepts various configuration options:
96
97
#### Properties
98
99
Define which CSS properties and values should be available. Properties can be defined as arrays for simple mappings or objects for semantic mappings.
100
101
```typescript
102
// Array format for valid CSS values
103
properties: {
104
display: ['none', 'block', 'flex'],
105
flexDirection: ['row', 'column']
106
}
107
108
// Object format for semantic mappings
109
properties: {
110
padding: {
111
small: '4px',
112
medium: '8px',
113
large: '16px'
114
},
115
color: {
116
primary: '#007bff',
117
secondary: '#6c757d'
118
}
119
}
120
121
// Style objects for complex scenarios
122
properties: {
123
background: {
124
red: {
125
vars: { [alpha]: '1' },
126
background: `rgba(255, 0, 0, ${alpha})`
127
}
128
}
129
}
130
```
131
132
#### Conditions
133
134
Define a set of media/feature queries, selectors, or other conditions for the provided properties.
135
136
```typescript
137
conditions: {
138
mobile: {},
139
tablet: { '@media': 'screen and (min-width: 768px)' },
140
desktop: { '@media': 'screen and (min-width: 1024px)' },
141
darkMode: { '@media': '(prefers-color-scheme: dark)' },
142
hover: { selector: '&:hover' },
143
focus: { selector: '&:focus' },
144
supportsGrid: { '@supports': 'display: grid' },
145
largeContainer: { '@container': '(min-width: 800px)' }
146
}
147
```
148
149
#### Default Condition
150
151
Defines which condition(s) should be used when a non-conditional value is requested.
152
153
```typescript
154
// Single default condition
155
defaultCondition: 'mobile'
156
157
// Multiple default conditions for mutually exclusive scenarios
158
defaultCondition: ['lightMode', 'darkMode']
159
160
// Force explicit condition usage
161
defaultCondition: false
162
```
163
164
#### Shorthands
165
166
Maps custom shorthand properties to multiple underlying CSS properties.
167
168
```typescript
169
shorthands: {
170
padding: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight'],
171
paddingX: ['paddingLeft', 'paddingRight'],
172
paddingY: ['paddingTop', 'paddingBottom'],
173
placeItems: ['justifyContent', 'alignItems']
174
}
175
```
176
177
#### Responsive Arrays
178
179
Providing an array of condition names enables responsive array notation by defining the order of conditions.
180
181
```typescript
182
responsiveArray: ['mobile', 'tablet', 'desktop']
183
```
184
185
#### CSS Layers
186
187
Optional CSS layer for generated styles. This wraps all generated CSS classes in the specified layer, useful for managing cascade order in complex stylesheets.
188
189
```typescript
190
// Add all generated styles to the 'utilities' layer
191
'@layer': 'utilities'
192
193
// Example with CSS layer
194
const layeredProperties = defineProperties({
195
'@layer': 'components',
196
properties: {
197
padding: {
198
small: '8px',
199
medium: '16px',
200
large: '24px'
201
},
202
margin: {
203
none: '0',
204
auto: 'auto'
205
}
206
}
207
});
208
209
// Generated CSS will be wrapped in @layer components { ... }
210
```
211
212
**CSS Output:**
213
```css
214
@layer components {
215
.padding_small_mobile {
216
padding: 8px;
217
}
218
219
.margin_auto_mobile {
220
margin: auto;
221
}
222
}
223
```
224
225
## Usage Examples
226
227
**Basic responsive properties:**
228
229
```typescript
230
import { defineProperties } from "@vanilla-extract/sprinkles";
231
232
const responsiveProperties = defineProperties({
233
conditions: {
234
mobile: {},
235
tablet: { '@media': 'screen and (min-width: 768px)' },
236
desktop: { '@media': 'screen and (min-width: 1024px)' }
237
},
238
defaultCondition: 'mobile',
239
properties: {
240
display: ['none', 'flex', 'block'],
241
flexDirection: ['row', 'column'],
242
paddingTop: {
243
small: '10px',
244
medium: '20px',
245
large: '30px'
246
}
247
}
248
});
249
```
250
251
**Color properties with theme conditions:**
252
253
```typescript
254
const colorProperties = defineProperties({
255
conditions: {
256
lightMode: {},
257
darkMode: { '@media': '(prefers-color-scheme: dark)' }
258
},
259
defaultCondition: 'lightMode',
260
properties: {
261
color: {
262
primary: '#007bff',
263
secondary: '#6c757d'
264
},
265
background: {
266
surface: '#ffffff',
267
elevated: '#f8f9fa'
268
}
269
}
270
});
271
```
272
273
**Properties with shorthands and responsive arrays:**
274
275
```typescript
276
const spacingProperties = defineProperties({
277
conditions: {
278
mobile: {},
279
tablet: { '@media': 'screen and (min-width: 768px)' },
280
desktop: { '@media': 'screen and (min-width: 1024px)' }
281
},
282
defaultCondition: 'mobile',
283
responsiveArray: ['mobile', 'tablet', 'desktop'],
284
properties: {
285
paddingTop: { small: '4px', medium: '8px', large: '16px' },
286
paddingBottom: { small: '4px', medium: '8px', large: '16px' },
287
paddingLeft: { small: '4px', medium: '8px', large: '16px' },
288
paddingRight: { small: '4px', medium: '8px', large: '16px' }
289
},
290
shorthands: {
291
padding: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight'],
292
paddingX: ['paddingLeft', 'paddingRight'],
293
paddingY: ['paddingTop', 'paddingBottom']
294
}
295
});
296
```
297
298
**Unconditional properties:**
299
300
```typescript
301
const unconditionalProperties = defineProperties({
302
properties: {
303
fontFamily: {
304
heading: 'Georgia, serif',
305
body: 'Arial, sans-serif',
306
mono: 'Consolas, monospace'
307
},
308
borderRadius: {
309
small: '2px',
310
medium: '4px',
311
large: '8px'
312
}
313
}
314
});
315
```
316
317
**CSS layer integration:**
318
319
```typescript
320
const layeredUtilities = defineProperties({
321
'@layer': 'utilities',
322
conditions: {
323
mobile: {},
324
tablet: { '@media': 'screen and (min-width: 768px)' },
325
desktop: { '@media': 'screen and (min-width: 1024px)' }
326
},
327
defaultCondition: 'mobile',
328
properties: {
329
display: ['none', 'block', 'flex'],
330
position: ['static', 'relative', 'absolute', 'fixed'],
331
zIndex: {
332
hide: -1,
333
base: 0,
334
elevated: 10,
335
modal: 100
336
}
337
},
338
shorthands: {
339
hide: ['display'],
340
show: ['display']
341
}
342
});
343
344
// Generated CSS will be organized in the utilities layer
345
// @layer utilities {
346
// .display_none_mobile { display: none; }
347
// .zIndex_modal_mobile { z-index: 100; }
348
// /* etc... */
349
// }
350
```