esm-styles 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +336 -87
- package/dist/lib/build.js +26 -9
- package/doc/ai-guide.md +221 -0
- package/doc/api-reference.md +262 -0
- package/doc/css-variables.md +32 -0
- package/doc/translation.md +710 -0
- package/doc/usage-guide.md +600 -0
- package/package.json +10 -3
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
# JS to CSS translations
|
|
2
|
+
|
|
3
|
+
JS object are translated to CSS this way:
|
|
4
|
+
|
|
5
|
+
## T1
|
|
6
|
+
|
|
7
|
+
JS object keys that contain another object translate to CSS selectors, while keys pointing to an end value (like string or number), transalte to CSS properties:
|
|
8
|
+
|
|
9
|
+
`source.styles.js`
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
{
|
|
13
|
+
p: {
|
|
14
|
+
fontSize: '16px',
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`output.css`
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
p {
|
|
23
|
+
font-size: 16px;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Key targeted to properties are converted automatically from `camelCase` to `kebab-case`.
|
|
28
|
+
|
|
29
|
+
## T2
|
|
30
|
+
|
|
31
|
+
Nested js objects translate to flat CSS:
|
|
32
|
+
|
|
33
|
+
`source.styles.js`
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
{
|
|
37
|
+
p: {
|
|
38
|
+
fontSize: '16px',
|
|
39
|
+
|
|
40
|
+
a: {
|
|
41
|
+
color: 'red',
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`output.css`
|
|
49
|
+
|
|
50
|
+
```css
|
|
51
|
+
p {
|
|
52
|
+
font-size: 16px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
p a {
|
|
56
|
+
color: red;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`p` and `a` are recognized as standard HTML tag names.
|
|
61
|
+
|
|
62
|
+
Note: keys named as standard HTML tag that contain primitive values generate invalid CSS:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
{
|
|
66
|
+
p: 'red',
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
goes to
|
|
71
|
+
|
|
72
|
+
```css
|
|
73
|
+
: {
|
|
74
|
+
p: red;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## T3
|
|
79
|
+
|
|
80
|
+
JS object keys with non-primitive values that were not recognized as standard HTML tag names convert to class selector:
|
|
81
|
+
|
|
82
|
+
`source.styles.js`
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
{
|
|
86
|
+
sticker: {
|
|
87
|
+
backgroundColor: 'yellow',
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
p: {
|
|
91
|
+
fontSize: '16px',
|
|
92
|
+
|
|
93
|
+
warning: {
|
|
94
|
+
color: 'red',
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`output.css`
|
|
101
|
+
|
|
102
|
+
```css
|
|
103
|
+
.sticker {
|
|
104
|
+
background-color: yellow;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
p {
|
|
108
|
+
font-size: 16px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
p.warning {
|
|
112
|
+
color: red;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## T4
|
|
117
|
+
|
|
118
|
+
JS object keys can contain pseudo-classes, vendor prefixes, ids and attributes:
|
|
119
|
+
|
|
120
|
+
`source.styles.js`
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
{
|
|
124
|
+
a: {
|
|
125
|
+
color: 'blue',
|
|
126
|
+
|
|
127
|
+
':hover': {
|
|
128
|
+
color: 'red',
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
ul: {
|
|
133
|
+
'-ms-overflow-style': 'none',
|
|
134
|
+
scrollbarWidth: 'none',
|
|
135
|
+
'::-webkit-scrollbar': {
|
|
136
|
+
display: 'none',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
input: {
|
|
141
|
+
'#id1': { font: `normal 16px/1.5 'Helvetica Neue', sans-serif` },
|
|
142
|
+
'[type=text]': {
|
|
143
|
+
'::placeholder': {
|
|
144
|
+
color: 'red',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`output.css`
|
|
152
|
+
|
|
153
|
+
```css
|
|
154
|
+
a {
|
|
155
|
+
color: blue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
a:hover {
|
|
159
|
+
color: red;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
ul {
|
|
163
|
+
-ms-overflow-style: none;
|
|
164
|
+
scrollbar-width: none;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
ul::-webkit-scrollbar {
|
|
168
|
+
display: none;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
input#id1 {
|
|
172
|
+
font: normal 16px/1.5 'Helvetica Neue', sans-serif;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
input[type='text']::placeholder {
|
|
176
|
+
color: red;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## T5
|
|
181
|
+
|
|
182
|
+
Workaround when class name equals to tag name: put underscore before name.
|
|
183
|
+
|
|
184
|
+
`source.styles.js`
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
{
|
|
188
|
+
div: {
|
|
189
|
+
video: {
|
|
190
|
+
width: '100%',
|
|
191
|
+
height: '100%',
|
|
192
|
+
},
|
|
193
|
+
_video: {
|
|
194
|
+
padding: '10px',
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`output.css`
|
|
201
|
+
|
|
202
|
+
```css
|
|
203
|
+
div video {
|
|
204
|
+
width: 100%;
|
|
205
|
+
height: 100%;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
div.video {
|
|
209
|
+
padding: 10px;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
(Generally, you should avoid using tag names as class names.)
|
|
214
|
+
|
|
215
|
+
## T6
|
|
216
|
+
|
|
217
|
+
Double underscore is used as shorthand to target descendant of any level with class name:
|
|
218
|
+
|
|
219
|
+
`source.styles.js`
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
{
|
|
223
|
+
div: {
|
|
224
|
+
fontSize: '16px',
|
|
225
|
+
|
|
226
|
+
video: {
|
|
227
|
+
width: '100%',
|
|
228
|
+
height: '100%',
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
_video: {
|
|
232
|
+
borderRadius: '10px',
|
|
233
|
+
},
|
|
234
|
+
|
|
235
|
+
__video: {
|
|
236
|
+
fontStyle: 'italic',
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`output.css`
|
|
243
|
+
|
|
244
|
+
```css
|
|
245
|
+
div {
|
|
246
|
+
font-size: 16px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
div video {
|
|
250
|
+
width: 100%;
|
|
251
|
+
height: 100%;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
div.video {
|
|
255
|
+
border-radius: 10px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
div .video {
|
|
259
|
+
font-style: italic;
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Double underscore always suggests that the key is a class name, not a tag name.
|
|
264
|
+
|
|
265
|
+
## T7
|
|
266
|
+
|
|
267
|
+
Key can be a complex selector:
|
|
268
|
+
|
|
269
|
+
`source.styles.js`
|
|
270
|
+
|
|
271
|
+
```js
|
|
272
|
+
{
|
|
273
|
+
ul: {
|
|
274
|
+
'> li:not(:last-child) > img': {
|
|
275
|
+
filter: 'grayscale(100%)',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
`output.css`
|
|
282
|
+
|
|
283
|
+
```css
|
|
284
|
+
ul > li:not(:last-child) > img {
|
|
285
|
+
filter: grayscale(100%);
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## T8
|
|
290
|
+
|
|
291
|
+
To use style for multiple selectors, comma can be used:
|
|
292
|
+
|
|
293
|
+
`source.styles.js`
|
|
294
|
+
|
|
295
|
+
```js
|
|
296
|
+
{
|
|
297
|
+
body: {
|
|
298
|
+
'main, aside': {
|
|
299
|
+
'input, textarea, button': {
|
|
300
|
+
outline: 'none',
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
`output.css`
|
|
308
|
+
|
|
309
|
+
```css
|
|
310
|
+
body main input,
|
|
311
|
+
body main textarea,
|
|
312
|
+
body main button,
|
|
313
|
+
body aside input,
|
|
314
|
+
body aside textarea,
|
|
315
|
+
body aside button {
|
|
316
|
+
outline: none;
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
More complex and nested expressions are supported:
|
|
321
|
+
|
|
322
|
+
`source.styles.js`
|
|
323
|
+
|
|
324
|
+
```js
|
|
325
|
+
{
|
|
326
|
+
body: {
|
|
327
|
+
'main > p, aside > blockquote': {
|
|
328
|
+
fontWeight: 700,
|
|
329
|
+
':hover': {
|
|
330
|
+
color: 'red',
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
`output.css`
|
|
338
|
+
|
|
339
|
+
```css
|
|
340
|
+
body main > p,
|
|
341
|
+
body aside > blockquote {
|
|
342
|
+
font-weight: 700;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
body main > p:hover,
|
|
346
|
+
body aside > blockquote:hover {
|
|
347
|
+
color: red;
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## T9
|
|
352
|
+
|
|
353
|
+
Content: if special character needed, use js unicode notation. It will be translated to CSS-compatible unicode (same goes for emoji):
|
|
354
|
+
|
|
355
|
+
`source.styles.js`
|
|
356
|
+
|
|
357
|
+
```js
|
|
358
|
+
{
|
|
359
|
+
span: {
|
|
360
|
+
'::before': {
|
|
361
|
+
content: '👀',
|
|
362
|
+
},
|
|
363
|
+
'::after': {
|
|
364
|
+
content: '\u00a0', // non-breaking space
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
`output.css`
|
|
371
|
+
|
|
372
|
+
```css
|
|
373
|
+
span::before {
|
|
374
|
+
content: '\00d83d\00dc40';
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
span::after {
|
|
378
|
+
content: '\0000a0';
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## T10
|
|
383
|
+
|
|
384
|
+
Media queries:
|
|
385
|
+
|
|
386
|
+
`source.styles.js`
|
|
387
|
+
|
|
388
|
+
```js
|
|
389
|
+
{
|
|
390
|
+
p: {
|
|
391
|
+
fontSize: '1rem',
|
|
392
|
+
|
|
393
|
+
'@media screen and (max-width: 768px)': {
|
|
394
|
+
fontSize: `${14 / 16}rem`,
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
|
|
398
|
+
ul: {
|
|
399
|
+
marginBlock: '1em',
|
|
400
|
+
|
|
401
|
+
'> li': {
|
|
402
|
+
fontSize: '16px',
|
|
403
|
+
|
|
404
|
+
'@media screen and (max-width: 768px)': {
|
|
405
|
+
fontSize: '14px',
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
`output.css`
|
|
413
|
+
|
|
414
|
+
```css
|
|
415
|
+
p {
|
|
416
|
+
font-size: 1rem;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
ul {
|
|
420
|
+
margin-block: 1em;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
ul > li {
|
|
424
|
+
font-size: 16px;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
@media screen and (max-width: 768px) {
|
|
428
|
+
p {
|
|
429
|
+
font-size: 0.875rem;
|
|
430
|
+
}
|
|
431
|
+
ul > li {
|
|
432
|
+
font-size: 14px;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Media query parts are extracted from nested keys and collected in the end of the CSS file.
|
|
438
|
+
|
|
439
|
+
## T11
|
|
440
|
+
|
|
441
|
+
Nested media queries also supported:
|
|
442
|
+
|
|
443
|
+
`source.styles.js`
|
|
444
|
+
|
|
445
|
+
```js
|
|
446
|
+
{
|
|
447
|
+
p: {
|
|
448
|
+
fontSize: '1rem',
|
|
449
|
+
|
|
450
|
+
'@media screen and (max-width: 768px)': {
|
|
451
|
+
fontSize: `${14 / 16}rem`,
|
|
452
|
+
|
|
453
|
+
'@media screen and (orientation: portrait)': {
|
|
454
|
+
fontSize: `${12 / 16}rem`,
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
`output.css`
|
|
462
|
+
|
|
463
|
+
```css
|
|
464
|
+
@media screen and (max-width: 768px) {
|
|
465
|
+
p {
|
|
466
|
+
font-size: 0.875rem;
|
|
467
|
+
}
|
|
468
|
+
@media screen and (orientation: portrait) {
|
|
469
|
+
p {
|
|
470
|
+
font-size: 0.75rem;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## T12
|
|
477
|
+
|
|
478
|
+
Named media queries and media selectors.
|
|
479
|
+
Named media queries and selectors are described in `esm-styles.config.js` and should be used as `@media-name`:
|
|
480
|
+
|
|
481
|
+
`source.styles.js`
|
|
482
|
+
|
|
483
|
+
```js
|
|
484
|
+
{
|
|
485
|
+
img: {
|
|
486
|
+
width: '100%',
|
|
487
|
+
'@dark': {
|
|
488
|
+
filter: 'brightness(0.8) saturate(0.8)',
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
div: {
|
|
492
|
+
fontFamily: 'var(--sans-serif)',
|
|
493
|
+
'@min-tablet': {
|
|
494
|
+
fontSize: '14px',
|
|
495
|
+
},
|
|
496
|
+
'@phone': {
|
|
497
|
+
fontSize: '12px',
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
`output.css`
|
|
505
|
+
|
|
506
|
+
```css
|
|
507
|
+
img {
|
|
508
|
+
width: 100%;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
div {
|
|
512
|
+
font-family: var(--sans-serif);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
@media (min-width: 500px) {
|
|
516
|
+
div {
|
|
517
|
+
font-size: 14px;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
@media (max-width: 499px) {
|
|
522
|
+
div {
|
|
523
|
+
font-size: 12px;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
:root.dark img {
|
|
528
|
+
filter: brightness(0.8) saturate(0.8);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
@media screen and (prefers-color-scheme: dark) {
|
|
532
|
+
:root.auto img {
|
|
533
|
+
filter: brightness(0.8) saturate(0.8);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
Note: for the name `@dark` is also configured in `config.js` as "media prefix" to include same styles for both auto- and user-selected dark mode.
|
|
539
|
+
|
|
540
|
+
In the legacy code there is a bug which won't allow to use media prefixes inside named media queries.
|
|
541
|
+
|
|
542
|
+
This doesn't work:
|
|
543
|
+
|
|
544
|
+
`source.styles.js`
|
|
545
|
+
|
|
546
|
+
```js
|
|
547
|
+
{
|
|
548
|
+
div: {
|
|
549
|
+
'@phone': {
|
|
550
|
+
fontWeight: 300,
|
|
551
|
+
|
|
552
|
+
'@dark': {
|
|
553
|
+
fontSize: '12px',
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
`output.css`
|
|
561
|
+
|
|
562
|
+
```css
|
|
563
|
+
@media (max-width: 499px) {
|
|
564
|
+
div {
|
|
565
|
+
font-weight: 300;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
@media screen and (prefers-color-scheme: dark) {
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
But this works as expected:
|
|
574
|
+
|
|
575
|
+
`source.styles.js`
|
|
576
|
+
|
|
577
|
+
```js
|
|
578
|
+
{
|
|
579
|
+
div: {
|
|
580
|
+
'@dark': {
|
|
581
|
+
fontSize: '12px',
|
|
582
|
+
|
|
583
|
+
'@phone': {
|
|
584
|
+
fontWeight: 300,
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
`output.css`
|
|
593
|
+
|
|
594
|
+
```css
|
|
595
|
+
:root.dark div {
|
|
596
|
+
font-size: 12px;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
@media (max-width: 499px) {
|
|
600
|
+
:root.dark div {
|
|
601
|
+
font-weight: 300;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
@media screen and (prefers-color-scheme: dark) {
|
|
606
|
+
:root.auto div {
|
|
607
|
+
font-size: 12px;
|
|
608
|
+
}
|
|
609
|
+
@media (max-width: 499px) {
|
|
610
|
+
:root.auto div {
|
|
611
|
+
font-weight: 300;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
## T13
|
|
618
|
+
|
|
619
|
+
Layers are supported. Layer keys' values are collected through the nested keys and grouped in the end of the file.
|
|
620
|
+
|
|
621
|
+
`source.styles.js`
|
|
622
|
+
|
|
623
|
+
```js
|
|
624
|
+
{
|
|
625
|
+
div: {
|
|
626
|
+
thin: {
|
|
627
|
+
fontWeight: 200,
|
|
628
|
+
'@layer a': { fontWeight: 300 },
|
|
629
|
+
},
|
|
630
|
+
},
|
|
631
|
+
blockquote: {
|
|
632
|
+
color: 'red',
|
|
633
|
+
'@layer a': { fontWeight: 300 },
|
|
634
|
+
},
|
|
635
|
+
}
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
`output.css`
|
|
639
|
+
|
|
640
|
+
```css
|
|
641
|
+
div.thin {
|
|
642
|
+
font-weight: 200;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
blockquote {
|
|
646
|
+
color: red;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
@layer a {
|
|
650
|
+
div.thin {
|
|
651
|
+
font-weight: 300;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
blockquote {
|
|
655
|
+
font-weight: 300;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
Also is possible to define layers order:
|
|
661
|
+
|
|
662
|
+
`source.styles.js`
|
|
663
|
+
|
|
664
|
+
```js
|
|
665
|
+
{
|
|
666
|
+
'@layer a, b, c': '',
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
`output.css`
|
|
671
|
+
|
|
672
|
+
```css
|
|
673
|
+
@layer a, b, c;
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
This key/value, if nested deeply, will be extracted and put in the beginning of the CSS file.
|
|
677
|
+
|
|
678
|
+
`source.styles.js`
|
|
679
|
+
|
|
680
|
+
```js
|
|
681
|
+
'@layer x, y, z': '',
|
|
682
|
+
|
|
683
|
+
a: {
|
|
684
|
+
color: 'blue',
|
|
685
|
+
|
|
686
|
+
':hover': {
|
|
687
|
+
color: 'red',
|
|
688
|
+
'@layer a, b, c': '',
|
|
689
|
+
},
|
|
690
|
+
|
|
691
|
+
'@layer c, b, a': '',
|
|
692
|
+
},
|
|
693
|
+
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
`output.css`
|
|
697
|
+
|
|
698
|
+
```css
|
|
699
|
+
@layer x, y, z;
|
|
700
|
+
@layer a, b, c;
|
|
701
|
+
@layer c, b, a;
|
|
702
|
+
|
|
703
|
+
a {
|
|
704
|
+
color: blue;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
a:hover {
|
|
708
|
+
color: red;
|
|
709
|
+
}
|
|
710
|
+
```
|