> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/zhcndoc/bun/llms.txt
> Use this file to discover all available pages before exploring further.

# CSS

> Bun's bundler has built-in support for CSS with modern features

Bun's bundler has built-in support for CSS with the following features:

* Transpile modern/future features for compatibility with all browsers (including vendor prefixes)
* Minification
* CSS Modules
* Tailwind (via native bundler plugin)

## Transpilation

Bun's CSS bundler lets you use modern/future CSS features without worrying about browser compatibility—thanks to transpilation and vendor prefixing enabled by default.

Bun's CSS parser and bundler is a direct port of LightningCSS from Rust to Zig, with bundling methodology inspired by esbuild. The transpiler converts modern CSS syntax into backwards-compatible equivalents for a range of browsers.

<Note>Special thanks to the authors of LightningCSS and esbuild for their excellent work.</Note>

## Browser compatibility

By default, Bun's CSS bundler targets browsers that support:

* ES2020
* Edge 88+
* Firefox 78+
* Chrome 87+
* Safari 14+

## Syntax downleveling

### Nesting

The CSS nesting specification allows you to write more concise and intuitive stylesheets by nesting selectors within each other. Instead of repeating parent selectors throughout your CSS file, you can write child styles directly inside parent blocks.

```css styles.css theme={null}
/* Using nesting */
.card {
  background: white;
  border-radius: 4px;

  .title {
    font-size: 1.2rem;
    font-weight: bold;
  }

  .content {
    padding: 1rem;
  }
}
```

Bun's CSS bundler automatically converts this nested syntax into traditional flat CSS for compatibility with all browsers:

```css styles.css theme={null}
/* Compiled output */
.card {
  background: white;
  border-radius: 4px;
}

.card .title {
  font-size: 1.2rem;
  font-weight: bold;
}

.card .content {
  padding: 1rem;
}
```

You can also nest media queries and other at-rules within selectors, avoiding repeated selector patterns:

```css styles.css theme={null}
.responsive-element {
  display: block;

  @media (min-width: 768px) {
    display: flex;
  }
}
```

Compiles to:

```css styles.css theme={null}
.responsive-element {
  display: block;
}

@media (min-width: 768px) {
  .responsive-element {
    display: flex;
  }
}
```

### Color mixing

The `color-mix()` function lets you easily blend two colors in a specified proportion within a chosen color space. This powerful feature lets you create color variations without manually calculating result values.

```css styles.css theme={null}
.button {
  /* Mix blue and red at 30%:70% in RGB color space */
  background-color: color-mix(in srgb, blue 30%, red);

  /* Create a lighter variant for hover state */
  &:hover {
    background-color: color-mix(in srgb, blue 30%, red, white 20%);
  }
}
```

Bun's CSS bundler evaluates these color mixes at build time (when all color values are known, not CSS variables), generating static color values that work in all browsers:

```css styles.css theme={null}
.button {
  /* The exact computed result color */
  background-color: #b31a1a;
}

.button:hover {
  background-color: #c54747;
}
```

This feature is particularly useful for creating programmatic color systems like tints, shades, and accents without a preprocessor or custom tooling.

### Relative colors

CSS now allows you to modify individual components of colors using relative color syntax. This powerful feature lets you create color variants by adjusting lightness, saturation, or individual channels without recalculating the entire color.

```css styles.css theme={null}
.theme-color {
  /* Start with a base color and increase its lightness by 15% */
  --accent: lch(from purple calc(l + 15%) c h);

  /* Take our brand blue and make a desaturated version */
  --subtle-blue: oklch(from var(--brand-blue) l calc(c * 0.8) h);
}
```

Bun's CSS bundler calculates these relative color modifications at build time (when not using CSS variables), generating static color values for browsers:

```css theme={null}
.theme-color {
  --accent: lch(69.32% 58.34 328.37);
  --subtle-blue: oklch(60.92% 0.112 240.01);
}
```

This is excellent for theme generation, creating accessible color variants, or building color scales based on mathematical relationships rather than hard-coded values.

### LAB colors

Modern CSS supports perceptually uniform color spaces like LAB, LCH, OKLAB, and OKLCH, which offer significant advantages over traditional RGB. These color spaces can represent colors beyond the standard RGB gamut, bringing more vibrant and visually consistent designs.

```css styles.css theme={null}
.vibrant-element {
  /* A vibrant red that's outside the sRGB gamut boundaries */
  color: lab(55% 78 35);

  /* Smooth gradient using perceptual color space */
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}
```

Bun's CSS bundler automatically converts these advanced color formats to backwards-compatible fallbacks for browsers that haven't implemented them yet:

```css styles.css theme={null}
.vibrant-element {
  /* Fallback to closest RGB approximation */
  color: #ff0f52;
  /* P3 fallback for browsers with wider gamut support */
  color: color(display-p3 1 0.12 0.37);
  /* Original value for browsers that support the format */
  color: lab(55% 78 35);

  background: linear-gradient(to right, #cd4e15, #3887ab);
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}
```

This layered approach ensures the best color rendering across all browsers while letting you use the latest color technology in your designs.

### color function

The `color()` function provides a standardized way to specify colors using various predefined color spaces, expanding your design options beyond traditional RGB space. This enables access to wider color gamuts, creating more vibrant designs.

```css styles.css theme={null}
.vivid-element {
  /* Use Display P3 color space for wider gamut */
  color: color(display-p3 1 0.1 0.3);

  /* Use A98 RGB color space */
  background-color: color(a98-rgb 0.44 0.5 0.37);
}
```

Bun's CSS bundler provides appropriate fallbacks:

```css styles.css theme={null}
.vivid-element {
  color: #ff0c52;
  color: color(display-p3 1 0.1 0.3);

  background-color: #648464;
  background-color: color(a98-rgb 0.44 0.5 0.37);
}
```

## CSS Modules

CSS Modules provide local scoping for CSS by default, preventing naming conflicts and making styles more maintainable.

```css Button.module.css theme={null}
.primary {
  background-color: blue;
  color: white;
}

.secondary {
  background-color: gray;
  color: black;
}
```

```tsx Button.tsx theme={null}
import styles from "./Button.module.css";

export function Button({ variant }) {
  return (
    <button className={styles[variant]}>
      Click me
    </button>
  );
}
```

The CSS bundler will:

1. Generate unique class names
2. Export a mapping object
3. Bundle the transformed CSS

```css Output theme={null}
._Button_primary_1a2b3c {
  background-color: blue;
  color: white;
}

._Button_secondary_4d5e6f {
  background-color: gray;
  color: black;
}
```

## Importing CSS

CSS can be imported in JavaScript/TypeScript files:

```ts app.ts theme={null}
import "./styles.css";
```

All imported CSS files are bundled into a single CSS file in the output directory:

```text theme={null}
.
├── app.ts
├── styles.css
└── out
    ├── app.js
    └── app.css
```

## @import statements

CSS `@import` statements are resolved and bundled:

```css main.css theme={null}
@import "./reset.css";
@import "./theme.css";

body {
  font-family: sans-serif;
}
```

All imports are inlined into a single CSS file.

## url() references

Asset references in `url()` are resolved and copied to the output directory:

```css styles.css theme={null}
.background {
  background-image: url("./image.png");
}

@font-face {
  font-family: "CustomFont";
  src: url("./font.woff2") format("woff2");
}
```

Assets are hashed and copied:

```css Output theme={null}
.background {
  background-image: url("./image-a1b2c3.png");
}

@font-face {
  font-family: "CustomFont";
  src: url("./font-d4e5f6.woff2") format("woff2");
}
```

## Minification

Enable CSS minification:

```bash theme={null}
bun build ./app.ts --outdir ./out --minify
```

This removes whitespace, shortens color values, and optimizes the CSS.

## Vendor prefixes

Vendor prefixes are automatically added based on the browser targets:

```css Input theme={null}
.box {
  display: flex;
  user-select: none;
}
```

```css Output theme={null}
.box {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
```

## Custom properties

CSS custom properties (variables) are preserved:

```css theme={null}
:root {
  --primary-color: blue;
  --spacing: 1rem;
}

.button {
  background-color: var(--primary-color);
  padding: var(--spacing);
}
```

## Media queries

Media queries are preserved and can be nested:

```css theme={null}
.container {
  width: 100%;

  @media (min-width: 768px) {
    width: 750px;
  }

  @media (min-width: 1024px) {
    width: 960px;
  }
}
```

## CSS chunking

When code splitting is enabled, CSS is also split into chunks:

```bash theme={null}
bun build ./entry-a.ts ./entry-b.ts --outdir ./out --splitting
```

Shared CSS is extracted into separate chunk files.

## Tailwind CSS

Bun provides a native bundler plugin for Tailwind CSS. See the [Tailwind documentation](https://tailwindcss.com) for setup instructions.

```ts theme={null}
import tailwindPlugin from "@tailwindcss/bun";

await Bun.build({
  entrypoints: ["./app.ts"],
  outdir: "./out",
  plugins: [tailwindPlugin()],
});
```

## Performance

Bun's CSS bundler is extremely fast:

* Written in Zig for maximum performance
* Parallel processing of CSS files
* Efficient memory usage
* Fast source map generation

## Limitations

* No PostCSS support yet (use plugins as an alternative)
* No SASS/SCSS support (but nesting is supported natively)
* CSS layers are preserved but not optimized
