vanilla-extract

website·Indexed 36 days ago

https://vanilla-extract.style/

A CSS-in-TypeScript library that provides a type-safe way to write styles. It features a zero-runtime approach, generating static CSS at build time. The ecosystem includes specialized packages like Sprinkles for atomic CSS, Recipes for multi-variant styles, and Dynamic for runtime variable updates, with official integrations for Vite, Webpack, Next.js, Astro, Rollup, esbuild, Parcel, and Gatsby.

Tokens
19.1K
Snippets
121
Records
132
Agent score
70%

What's inside vanilla-extract

  1. Overview of Sprinkles atomic CSS framework

    Sprinkles is a zero-runtime atomic CSS framework built on top of vanilla-extract. It allows you to generate a static set of custom utility classes that can be composed either statically at build time or dynamically at runtime. This provides a type-safe alternative to frameworks like Tailwind CSS or Styled System without the overhead of runtime CSS-in-JS style generation.
  2. vanilla-extract Framework and Tooling Support

    vanilla-extract is framework agnostic and provides official integrations for the following build tools: webpack, esbuild, Vite, and Next.js. It can be extended with additional libraries such as Sprinkles and Recipes.
  3. Create a basic theme with createTheme

    Use createTheme to define a set of CSS variables and a corresponding container class. It returns a tuple containing a class name (to apply the theme to an element) and a theme contract (a typed object used to reference the variables in your styles).
    import { createTheme } from '@vanilla-extract/css';
    
    export const [themeClass, vars] = createTheme({
      color: {
        brand: 'blue'
      },
      font: {
        body: 'arial'
      }
    });
  4. Implement responsive styles with Media Queries

    Embed media queries directly within a style definition using the @media key. Vanilla Extract renders these at the end of the generated CSS file, ensuring they have higher precedence than base styles. It also merges @media, @supports, and @container blocks to optimize output size.
    import { style } from '@vanilla-extract/css';
    
    const myStyle = style({
      '@media': {
        'screen and (min-width: 768px)': {
          padding: 10
        },
        '(prefers-reduced-motion)': {
          transitionProperty: 'color'
        }
      }
    });
  5. Implement Container Queries in Vanilla Extract

    Use the @container key within a style() definition to apply styles based on the size of a container. You can use generic container queries or create scoped containers using createContainer() to target specific named containers.
    import { style, createContainer } from '@vanilla-extract/css';
    
    // 1. Simple container query
    const simpleStyle = style({
      '@container': {
        '(min-width: 768px)': {
          padding: 10
        }
      }
    });
    
    // 2. Scoped container query
    const sidebar = createContainer();
    
    const scopedStyle = style({
      containerName: sidebar,
      '@container': {
        [`${sidebar} (min-width: 768px)`]: {
          padding: 10
        }
      }
    });
  6. Reuse styles using Style Composition

    Style composition in vanilla-extract allows you to reuse existing styles by passing an array of class names and/or style objects to the style() function. This creates a 'classlist' (a space-separated string of classes) that can be assigned to DOM elements. When used within other vanilla-extract selectors, composed classes are handled as a single unique identifier to ensure predictable CSS output.
    import { style } from '@vanilla-extract/css';
    
    // Define a base style
    const base = style({ padding: 12 });
    
    // Compose the base style with new properties
    // primary will result in a string containing both the base class and the primary class
    const primary = style([base, { background: 'blue' }]);
    const secondary = style([base, { background: 'aqua' }]);
  7. Define multiple font weights for a single family with globalFontFace

    To define multiple font-face rules (such as different weights or styles) for the same font family, pass an array of configuration objects as the second argument to globalFontFace. Each object in the array will generate a separate @font-face rule sharing the same family name.
    import { globalFontFace, style } from '@vanilla-extract/css';
    
    const gentium = 'GlobalGentium';
    
    globalFontFace(gentium, [
      {
        src: 'local("Gentium")',
        fontWeight: 'normal'
      },
      {
        src: 'local("Gentium Bold")',
        fontWeight: 'bold'
      }
    ]);
    
    export const font = style({
      fontFamily: gentium
    });
  8. Assign styles to CSS Cascade Layers

    Assign styles to CSS layers using the @layer key within a style definition. You can use a string for the layer name or a scoped layer reference created via the layer() API. Note: Vanilla Extract does not polyfill cascade layers; ensure target browsers support the feature.
    import { style, layer } from '@vanilla-extract/css';
    
    // Using a string layer name
    const textSimple = style({
      '@layer': {
        typography: {
          fontSize: '1rem'
        }
      }
    });
    
    // Using a scoped layer reference
    const typographyLayer = layer();
    const textScoped = style({
      '@layer': {
        [typographyLayer]: {
          fontSize: '1rem'
        }
      }
    });
  9. Animate CSS variables using keyframes

    To animate CSS variables, define the variable using createVar and then update its value within the vars property of a keyframe step. This allows for smooth transitions of custom properties, provided the browser supports the @property rule (which vanilla-extract handles via the syntax option in createVar).
    import {
      createVar,
      fallbackVar,
      keyframes,
      style
    } from '@vanilla-extract/css';
    
    const angle = createVar({
      syntax: '<angle>',
      inherits: false,
      initialValue: '0deg'
    });
    
    const angleKeyframes = keyframes({
      '0%': {
        vars: {
          [angle]: '0deg'
        }
      },
      '100%': {
        vars: {
          [angle]: '360deg'
        }
      }
    });
    
    export const root = style({
      backgroundImage: `linear-gradient(${angle}, rgba(153, 70, 198, 0.35) 0%, rgba(28, 56, 240, 0.46) 100%)`,
      animation: `${angleKeyframes} 7s infinite ease-in-out both`,
    
      vars: {
        // Fallback for browsers not supporting @property
        [angle]: fallbackVar(angle, '180deg')
      }
    });
  10. Assign CSS variables within media queries

    CSS variables created with createVar can be reassigned within media queries using the vars key. This allows the variable's value to change based on conditions like prefers-color-scheme.
    import { createVar, style } from '@vanilla-extract/css';
    
    export const accentVar = createVar();
    
    export const blue = style({
      vars: {
        [accentVar]: 'blue'
      },
      '@media': {
        '(prefers-color-scheme: dark)': {
          vars: {
            [accentVar]: 'lightblue'
          }
        }
      }
    });