lightningcss 1.0.0-alpha.71

A CSS parser, transformer, and minifier
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
<aside>

[[toc]]

</aside>

# Transpilation

Lightning CSS includes support for transpiling modern CSS syntax to support older browsers, including vendor prefixing and syntax lowering.

## Browser targets

By default Lightning CSS does not perform any transpilation of CSS syntax for older browsers. This means that if you write your code using modern syntax or without vendor prefixes, that’s what Lightning CSS will output. You can declare your app’s supported browsers using the `targets` option. When this is declared, Lightning CSS will transpile your code accordingly to ensure compatibility with your supported browsers.

Targets are defined using an object that specifies the minimum version of each browser you want to support. The easiest way to build a targets object is to use [browserslist](https://browserslist.dev). This lets you use a query that automatically updates over time as new browser versions are released, market share changes, etc. The following example will return a targets object listing browsers with >= 0.25% market share.

```js
import browserslist from 'browserslist';
import { transform, browserslistToTargets } from 'lightningcss';

// Call this once per build.
let targets = browserslistToTargets(browserslist('>= 0.25%'));

// Use `targets` for each file you transform.
let { code, map } = transform({
  // ...
  targets
});
```

For the best performance, you should call browserslist once for your whole build process, and reuse the same `targets` object when calling `transform` for each file.

Under the hood, `targets` are represented using an object that maps browser names to minimum versions. Version numbers are represented using a single 24-bit number, with one semver component (major, minor, patch) per byte. For example, this targets object would represent Safari 13.2.0.

```js
let targets = {
  safari: (13 << 16) | (2 << 8)
};
```

### CLI

When using the CLI, targets can be provided by passing a [browserslist](https://browserslist.dev) query to the `--targets` option. Alternatively, if the `--browserslist` option is provided, then `lightningcss` finds browserslist configuration, selects queries by environment and loads the resulting queries as targets.

Configuration discovery and targets resolution is modeled after the original `browserslist` Node package. The configuration is resolved in the following order:

- If a `BROWSERSLIST` environment variable is present, then load targets from its value.
- If a `BROWSERSLIST_CONFIG` environment variable is present, then load the browserslist configuration from the file at the provided path.
- If none of the above apply, then find, parse and use targets from the first `browserslist`, `.browserslistrc`, or `package.json` configuration file in any parent directory.

Browserslist configuration files may contain sections denoted by square brackets. Use these to specify different targets for different environments. Targets which are not placed in a section are added to `defaults` and used if no section matches the environment.

```ini
# Defaults, applied when no other section matches the provided environment.
firefox ESR

# Targets applied only to the staging environment.
[staging]
samsung >= 4
```

When using parsed configuration from `browserslist`, `.browserslistrc`, or `package.json` configuration files, the environment is determined by:

- the `BROWSERSLIST_ENV` environment variable if present
- the `NODE_ENV` environment variable if present
- otherwise `"production"` is used.

If no targets are found for the resulting environment, then the `defaults` configuration section is used.

### Feature flags

In most cases, setting the `targets` option and letting Lightning CSS automatically compile your CSS works great. However, in other cases you might need a little more control over exactly what features are compiled and which are not. That's where the `include` and `exclude` options come in.

The `include` and `exclude` options allow you to explicitly turn on or off certain features. These override the defaults based on the provided browser targets. For example, you might want to only compile colors, and handle auto prefixing or other features with another tool. Or you may want to handle everything except vendor prefixing with Lightning CSS. These options make that possible.

The `include` and `exclude` options are configured using the `Features` enum, which can be imported from `lightningcss`. You can bitwise OR multiple flags together to turn them on or off.

```js
import { transform, Features } from 'lightningcss';

let { code, map } = transform({
  // ...
  targets,
  // Always compile colors and CSS nesting, regardless of browser targets.
  include: Features.Colors | Features.Nesting,
  // Never add any vendor prefixes, regardless of targets.
  exclude: Features.VendorPrefixes
});
```

Here is a full list of available flags, described in the sections below:

<div class="features">

* `Nesting`
* `NotSelectorList`
* `DirSelector`
* `LangSelectorList`
* `IsSelector`
* `TextDecorationThicknessPercent`
* `MediaIntervalSyntax`
* `MediaRangeSyntax`
* `CustomMediaQueries`
* `ClampFunction`
* `ColorFunction`
* `OklabColors`
* `LabColors`
* `P3Colors`
* `HexAlphaColors`
* `SpaceSeparatedColorNotation`
* `LightDark`
* `FontFamilySystemUi`
* `DoublePositionGradients`
* `VendorPrefixes`
* `LogicalProperties`
* `Selectors` – shorthand for `Nesting | NotSelectorList | DirSelector | LangSelectorList | IsSelector`
* `MediaQueries` – shorthand for `MediaIntervalSyntax | MediaRangeSyntax | CustomMediaQueries`
* `Colors` – shorthand for `ColorFunction | OklabColors | LabColors | P3Colors | HexAlphaColors | SpaceSeparatedColorNotation | LightDark`

</div>

## Vendor prefixing

Based on your configured browser targets, Lightning CSS automatically adds vendor prefixed fallbacks for many CSS features. For example, when using the [`image-set()`](https://developer.mozilla.org/en-US/docs/Web/CSS/image/image-set()) function, Lightning CSS will output a fallback `-webkit-image-set()` value as well, since Chrome does not yet support the unprefixed value.

```css
.logo {
  background: image-set(url(logo.png) 2x, url(logo.png) 1x);
}
```

compiles to:

```css
.logo {
  background: -webkit-image-set(url(logo.png) 2x, url(logo.png) 1x);
  background: image-set("logo.png" 2x, "logo.png");
}
```

In addition, if your CSS source code (or more likely a library) includes unnecessary vendor prefixes, Lightning CSS will automatically remove them to reduce bundle sizes. For example, when compiling for modern browsers, prefixed versions of the `transition` property will be removed, since the unprefixed version is supported by all browsers.

```css
.button {
  -webkit-transition: background 200ms;
  -moz-transition: background 200ms;
  transition: background 200ms;
}
```

becomes:

```css
.button {
  transition: background .2s;
}
```

## Syntax lowering

Lightning CSS automatically compiles many modern CSS syntax features to more compatible output that is supported in your target browsers.

### Nesting

The [CSS Nesting](https://drafts.csswg.org/css-nesting/) spec enables style rules to be nested, with the selectors of the child rules extending the parent selector in some way. This is very commonly supported by CSS pre-processors like Sass, but with this spec, it will eventually be supported natively in browsers. Lightning CSS compiles this syntax to un-nested style rules that are supported in all browsers today.

```css
.foo {
  color: blue;

  .bar {
    color: red;
  }
}
```

is equivalent to:

```css
.foo {
  color: blue;
}

.foo .bar {
  color: red;
}
```

[Conditional rules](https://drafts.csswg.org/css-nesting/#conditionals) such as `@media` may also be nested within a style rule, without repeating the selector. For example:

```css
.foo {
  display: grid;

  @media (orientation: landscape) {
    grid-auto-flow: column;
  }
}
```

is equivalent to:

```css
.foo {
  display: grid;
}

@media (orientation: landscape) {
  .foo {
    grid-auto-flow: column;
  }
}
```

### Color mix

The [`color-mix()`](https://drafts.csswg.org/css-color-5/#color-mix) function allows you to mix two colors by the specified amount in a certain color space. Lightning CSS will evaluate this function statically when all components are known (i.e. not variables).

```css
.foo {
  color: color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%));
}
```

compiles to:

```css
.foo {
  color: #706a43;
}
```

### Relative colors

Relative colors allow you to modify the components of a color using math functions. In addition, you can convert colors between color spaces. Lightning CSS performs these calculations statically when all components are known (i.e. not variables).

This example lightens `slateblue` by 10% in the LCH color space.

```css
.foo {
  color: lch(from slateblue calc(l * 1.1) c h);
}
```

compiles to:

```css
.foo {
  color: lch(49.0282% 65.7776 296.794);
}
```

### LAB colors

Lightning CSS will convert [`lab()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/lab()), [`lch()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/lch()), [`oklab()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklab), and [`oklch()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklch) colors to fallback values for unsupported browsers when needed. These functions allow you to define colors in higher gamut color spaces, making it possible to use colors that cannot be represented by RGB.

```css
.foo {
  color: lab(40% 56.6 39);
}
```

compiles to:

```css
.foo {
  color: #b32323;
  color: color(display-p3 .643308 .192455 .167712);
  color: lab(40% 56.6 39);
}
```

As shown above, a `display-p3` fallback is included in addition to RGB when a target browser supports the P3 color space. This preserves high color gamut colors when possible.

### Color function

Lightning CSS converts the [`color()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color()) function to RGB when needed for compatibility with older browsers. This allows you to use predefined color spaces such as `display-p3`, `xyz`, and `a98-rgb`.

```css
.foo {
  color: color(a98-rgb 0.44091 0.49971 0.37408);
}
```

compiles to:

```css
.foo {
  color: #6a805d;
  color: color(a98-rgb .44091 .49971 .37408);
}
```

### HWB colors

Lightning CSS converts [`hwb()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hwb) colors to RGB.

```css
.foo {
  color: hwb(194 0% 0%);
}
```

compiles to:

```css
.foo {
  color: #00c4ff;
}
```

### Color notation

Space separated color notation is converted to hex when needed. Hex colors with alpha are also converted to `rgba()` when unsupported by all targets.

```css
.foo {
  color: #7bffff80;
  background: rgb(123 255 255);
}
```

compiles to:

```css
.foo {
  color: rgba(123, 255, 255, .5);
  background: #7bffff;
}
```

### light-dark() color function

The [`light-dark()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark) function allows you to specify a light mode and dark mode color in a single declaration, without needing to write a separate media query rule. In addition, it uses the [`color-scheme`](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme) property to control which theme to use, which allows you to set it programmatically. The `color-scheme` property also inherits so themes can be nested and the nearest ancestor color scheme applies.

Lightning CSS converts the `light-dark()` function to use CSS variable fallback when your browser targets don't support it natively. For this to work, you must set the `color-scheme` property on an ancestor element. The following example shows how you can support both operating system and programmatic overrides for the color scheme.

```css
html {
  color-scheme: light dark;
}

html[data-theme=light] {
  color-scheme: light;
}

html[data-theme=dark] {
  color-scheme: dark;
}

button {
  background: light-dark(#aaa, #444);
}
```

compiles to:

```css
html {
  --lightningcss-light: initial;
  --lightningcss-dark: ;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  html {
    --lightningcss-light: ;
    --lightningcss-dark: initial;
  }
}

html[data-theme="light"] {
  --lightningcss-light: initial;
  --lightningcss-dark: ;
  color-scheme: light;
}

html[data-theme="dark"] {
  --lightningcss-light: ;
  --lightningcss-dark: initial;
  color-scheme: dark;
}

button {
  background: var(--lightningcss-light, #aaa) var(--lightningcss-dark, #444);
}
```

### Logical properties

CSS [logical properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties) allow you to define values in terms of writing direction, so that UIs mirror in right-to-left languages. Lightning CSS will compile these to use the `:dir()` selector when unsupported. If the `:dir()` selector is unsupported, it is compiled as described [below](#%3Adir()-selector).

```css
.foo {
  border-start-start-radius: 20px
}
```

compiles to:

```css
.foo:dir(ltr) {
  border-top-left-radius: 20px;
}

.foo:dir(rtl) {
  border-top-right-radius: 20px;
}
```


### :dir() selector

The [`:dir()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:dir) selector matches elements based on the writing direction. Lightning CSS compiles this to use the `:lang()` selector when unsupported, which approximates this behavior as closely as possible.

```css
a:dir(rtl) {
  color:red
}
```

compiles to:

```css
a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
  color: red;
}
```

If multiple arguments to `:lang()` are unsupported, it is compiled as described [below](#%3Alang()-selector).

### :lang() selector

The [`:lang()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:lang) selector matches elements based on their language. Some browsers do not support multiple arguments to this function, so Lightning CSS compiles them to use `:is()` when needed.

```css
a:lang(en, fr) {
  color:red
}
```

compiles to:

```css
a:is(:lang(en), :lang(fr)) {
  color: red;
}
```

When the `:is()` selector is unsupported, it is compiled as described [below](#%3Ais()-selector).

### :is() selector

The [`:is()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:is) matches when one of its arguments matches. Lightning CSS falls back to the `:-webkit-any` and `:-moz-any` prefixed selectors.

```css
p:is(:first-child, .lead) {
  margin-top: 0;
}
```

compiles to:

```css
p:-webkit-any(:first-child, .lead) {
  margin-top: 0;
}

p:-moz-any(:first-child, .lead) {
  margin-top: 0;
}

p:is(:first-child, .lead) {
  margin-top: 0;
}
```

<div class="warning">

**Note**: The prefixed versions of these selectors do not support complex selectors (e.g. selectors with combinators). Lightning CSS will only output prefixes if the arguments are simple selectors. Complex selectors in `:is()` are not currently compiled.

</div>

### :not() selector

The [`:not()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:not) selector can accept multiple arguments, and matches if none of the arguments match. Some older browsers only support a single argument, so Lightning CSS compiles this when needed. The `:is` selector is used to ensure the specificity remains the same, with fallback to `-webkit-any` and `-moz-any` as needed (described above).

```css
p:not(:first-child, .lead) {
  margin-top: 1em;
}
```

compiles to:

```css
p:not(:is(:first-child, .lead)) {
  margin-top: 1em;
}
```

### Math functions

Lightning CSS simplifies [math functions](https://w3c.github.io/csswg-drafts/css-values/#math) including `clamp()`, `round()`, `rem()`, `mod()`, `abs()`, and `sign()`, [trigonometric functions](https://w3c.github.io/csswg-drafts/css-values/#trig-funcs) including `sin()`, `cos()`, `tan()`, `asin()`, `acos()`, `atan()`, and `atan2()`, and [exponential functions](https://w3c.github.io/csswg-drafts/css-values/#exponent-funcs) including `pow()`, `log()`, `sqrt()`, `exp()`, and `hypot()` when all arguments are known (i.e. not variables). In addition, the numeric constants `e`, `pi`, `infinity`, `-infinity`, and `NaN` are supported in all calculations.

```css
.foo {
  width: round(calc(100px * sin(pi / 4)), 5px);
}
```

compiles to:

```css
.foo {
  width: 70px;
}
```

### Media query ranges

[Media query range syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#syntax_improvements_in_level_4) allows defining media queries using comparison operators to create ranges and intervals. Lightning CSS compiles this to the corresponding `min` and `max` media features when needed.

```css
@media (480px <= width <= 768px) {
  .foo { color: red }
}
```

compiles to:

```css
@media (min-width: 480px) and (max-width: 768px) {
  .foo { color: red }
}
```

### Shorthands

Lightning CSS compiles the following shorthands to corresponding longhands when the shorthand is not supported in all target browsers:

* Alignment shorthands: [place-items](https://developer.mozilla.org/en-US/docs/Web/CSS/place-items), [place-content](https://developer.mozilla.org/en-US/docs/Web/CSS/place-content), [place-self](https://developer.mozilla.org/en-US/docs/Web/CSS/place-self)
* [Overflow shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/overflow) with multiple values (e.g. `overflow: hidden auto`)
* [text-decoration](https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration) with thickness, style, color, etc.
* Two value [display](https://developer.mozilla.org/en-US/docs/Web/CSS/display) syntax (e.g. `display: inline flex`)

### Double position gradients

CSS gradients support using two positions in a color stop to repeat the color at two subsequent positions. When unsupported, Lightning CSS compiles it.

```css
.foo {
  background: linear-gradient(green, red 30% 40%, pink);
}
```

compiles to:

```css
.foo {
  background: linear-gradient(green, red 30%, red 40%, pink);
}
```

### system-ui font

The `system-ui` font allows you to use the operating system default font. When unsupported, Lightning CSS compiles it to a font stack that works across major platforms.

```css
.foo {
  font-family: system-ui;
}
```

compiles to:

```css
.foo {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue;
}
```

## Draft syntax

Lightning CSS can also be configured to compile several draft specs that are not yet available natively in any browser. Because these are drafts and the syntax can still change, they must be enabled manually in your project.

### Custom media queries

Support for [custom media queries](https://drafts.csswg.org/mediaqueries-5/#custom-mq) is included in the Media Queries Level 5 draft spec. This allows you to define media queries that are reused in multiple places within a CSS file. Lightning CSS will perform this substitution ahead of time when this feature is enabled.

For example:

```css
@custom-media --modern (color), (hover);

@media (--modern) and (width > 1024px) {
  .a { color: green; }
}
```

is equivalent to:

```css
@media ((color) or (hover)) and (width > 1024px) {
  .a { color: green; }
}
```

Because custom media queries are a draft, they are not enabled by default. To use them, enable the `customMedia` option under `drafts` when calling the Lightning CSS API. When using the CLI, enable the `--custom-media` flag.

```js
let { code, map } = transform({
  // ...
  drafts: {
    customMedia: true
  }
});
```

## Pseudo class replacement

Lightning CSS supports replacing CSS pseudo classes such as `:focus-visible` with normal CSS classes that can be applied using JavaScript. This makes it possible to polyfill these pseudo classes for older browsers.

```js
let { code, map } = transform({
  // ...
  pseudoClasses: {
    focusVisible: 'focus-visible'
  }
});
```

The above configuration will result in the `:focus-visible` pseudo class in all selectors being replaced with the `.focus-visible` class. This enables you to use a JavaScript [polyfill](https://github.com/WICG/focus-visible), which will apply the `.focus-visible` class as appropriate.

The following pseudo classes may be configured as shown above:

* `hover` – corresponds to the `:hover` pseudo class
* `active` – corresponds to the `:active` pseudo class
* `focus` – corresponds to the `:focus` pseudo class
* `focusVisible` – corresponds to the `:focus-visible` pseudo class
* `focusWithin` – corresponds to the `:focus-within` pseudo class

## Non-standard syntax

For compatibility with other tools, Lightning CSS supports parsing some non-standard CSS syntax. This must be enabled by turning on a flag under the `nonStandard` option.

```js
let { code, map } = transform({
  // ...
  nonStandard: {
    deepSelectorCombinator: true
  }
});

```

Currently the following features are supported:

* `deepSelectorCombinator` – enables parsing the Vue/Angular `>>>` and `/deep/` selector combinators.