Skip to content

Repository files navigation

bakeware License Build status npm

  • Utility functions for vanilla-extract
  • TypeScript-ready, with built-in type definitions
  • Simplifies working with @layer
  • Supports type scale and vertical rhythm out of the box
  • normalize helper suited for 2026 usage
  • Access custom property values from themes
  • Manage breakpoints with ease

Installation

npm install bakeware

style(layer?, rule, debugId?)

Extends vanilla-extract's style, enabling a cleaner way to implement layers. If layer is not set, it behaves like the original function.

Description Default
layer CSS @layer name. undefined
rule
debugId undefined
import { style } from "bakeware";

// With layer
const withLayer = style("base", {
  color: "blue",
});
// @layer base {
//   .withLayer {
//     color: blue;
//   }
// }

// Without layer
const withoutLayer = style({
  color: "red",
});
// .withoutLayer {
//   color: red;
// }

spacing(...values, options?)

Generates a space-separated string of values, following CSS conventions.

Description Default
values A list of numbers or strings.
options.baseValue Base value used to calculate the spacing units. 1rem
options.ratio A ratio of the base value used as a spacing unit. 1/4
options.separator Character used to separate the fragments—" " or ",". " "
import { spacing } from "bakeware";

spacing(1, 2);
// "0.25rem 0.5rem"

spacing(1, 2, { ratio: 2 });
// "0.5rem 1rem"

spacing(1, 2, { baseValue: "16px" });
// "4px 8px"

// Comma-separated declarations
`translate3d(${spacing(1, 2, 3, { separator: "," })})`;
// "translate3d(0.25rem,0.5rem,0.75rem)"

verticalRhythm(signature, options?)

Creates a vertical rhythm system based on a given signature.

Description Default
signature An object { lineHeight, spacingRatio } or a string in the format "${number}/${number}".
options.typeScale typeScale configuration—when set, the returned object includes a fontSize method. undefined
options.whitespaceRatio Minimum whitespace between the line height and the actual text, expressed as a ratio between 0 and 1. 0
import { verticalRhythm } from "bakeware";

const { spacing } = verticalRhythm({ lineHeight: 1.5, spacingRatio: 1/4 });

spacing(1, 2);
// "0.375rem 0.75rem"
import { verticalRhythm } from "bakeware";

const { spacing } = verticalRhythm("4/6");

spacing(1, 2);
// "0.375rem 0.75rem"
import { verticalRhythm } from "bakeware";

const { fontSize, spacing } = verticalRhythm("2/3", {
  typeScale: "geometrical.goldenRatio",
  whitespaceRatio: 0.2,
});

spacing(1, 2);
// "0.75rem 1.5rem"

fontSize(0);
// { fontSize: "1rem", lineHeight: "1.5rem" }

fontSize(1);
// { fontSize: "1.618033988749895rem", lineHeight: "3rem" }

fontSize(2);
// { fontSize: "2.618033988749895rem", lineHeight: "4.5rem" }

typeScale(scale, unit?)

Generates a type scale based on mathematical or geometric formulas.

Description Default
scale A string path (e.g., "natural.majorSecond") or a number representing the ratio.
unit The CSS unit to use for the resulting font size. "rem"
import { typeScale } from "bakeware";

const { fontSize } = typeScale("natural.majorSecond");

fontSize(0);
// "1rem"

fontSize(1);
// "1.125rem"

fontSize(2);
// "1.265625rem"

normalize(layer?)

CSS normalization based on Normalize.css and recent discussions across the web. It focuses on minimal impact, resetting only the styles strictly necessary while adding a few convenience styles from modern CSS specs.

Description Default
layer Optional CSS layer name to wrap the normalization rules. undefined
import { layer } from "@vanilla-extract/css";
import { normalize } from "bakeware";

const layoutLayer = layer("layout");

normalize(layoutLayer);

alpha(color, value)

Adjusts the opacity of a color, with support for var declarations generated by createTheme.

Description Default
color The color string to modify.
value A number between 0 and 1.

transition(...properties, options?)

Makes implementing CSS transitions easy.

Description Default
properties CSS property names.
options.behavior "normal"
options.delay undefined
options.duration "0s"
options.timingFunction "ease"
import { style, transition } from "bakeware";

const example = style({
  transition: transition("opacity", "transform", {
    duration: 200,
  }).toString(),
});
// .example {
//   transition: opacity 200ms,transform 200ms;
// }

transition(...).add(...properties, options?)

Adds declarations to the output using different options—see transition above for the available arguments.

import { transition } from "bakeware";

transition("opacity", { duration: "100ms" })
  .add("height", { delay: 200, duration: "1s", timingFunction: "linear" })
  .add("display", { behavior: "allow-discrete", duration: 500 })
  .toString();
// "opacity 100ms,height 200ms linear 1s,display 500ms allow-discrete"

transition(...).toString()

Returns the CSS transition string.

import { transition } from "bakeware";

transition("opacity").toString()
// "opacity 0s"

createTransition(options?)

Generates a transition function with its own default options—see transition above for the available options.

import { createTransition, transition } from "bakeware";

const customTransition = createTransition({ duration: 200 });

transition("opacity").toString();
// "opacity 0s"

customTransition("opacity").toString();
// "opacity 200ms"

animation(name, options?)

Makes implementing CSS animations easy.

Description Default
name Animation name.
options.delay undefined
options.direction "normal"
options.duration "0s"
options.fillMode undefined
options.iterationCount "1"
options.playState "running"
options.timeline "auto"
options.timingFunction "ease"
import { keyframes } from "@vanilla-extract/css";
import { animation, style } from "bakeware";

const fade = keyframes({
  from: {
    opacity: 0,
  },
  to: {
    opacity: 1,
  },
});

const example = style({
  animation: animation(fade, {
    duration: 200,
  }).toString(),
});
// .example {
//   animation: 200ms fade;
// }

animation(...).add(...properties, options?)

Adds declarations to the output using different options—see animation above for the available arguments.

import { animation } from "bakeware";

animation("blur", { duration: "100ms" })
  .add("slideOut", { delay: 200, duration: "1s", timingFunction: "linear" })
  .add("blink", { duration: 500, playState: "paused" })
  .toString();
// "100ms blur,200ms linear 1s slideOut,500ms paused blink"

animation(...).toString()

Returns the CSS animation string.

import { animation } from "bakeware";

animation("blur").toString()
// "0s blur"

createAnimation(options?)

Generates an animation function with its own default options—see animation above for the available options.

import { animation, createAnimation } from "bakeware";

const customAnimation = createAnimation({ duration: 200 });

animation("blur").toString();
// "0s blur"

customAnimation("blur").toString();
// "200ms blur"

fontFace(rule, debugId?)

Extends vanilla-extract's fontFace, making the src definition cleaner. Fully compatible with the original function.

Description Default
rule
debugId
import { fontFace } from "bakeware";

fontFace({
  src: {
    local: "Helvetica",
    opentype: { tech: "variations", url: "./helvetica.otf" },
    truetype: "./helvetica.ttf",
    woff2: { url: "./helvetica.woff2" },
  },
});
// local("Helvetica"),url("./helvetica.otf") format(opentype) tech("variations"),url("./helvetica.ttf") format(truetype),url("./helvetica.woff2") format(woff2)

// Can also be used with an array of strings
fontFace([
  {
    src: [
      'local("Helvetica")',
      'url("./helvetica.otf") format(opentype) tech("variations")',
      'url("./helvetica.ttf") format(truetype)',
      'url("./helvetica.woff2") format(woff2)',
    ],
  },
]);

// Can also be used like vanilla-extract original function
fontFace([
  {
    src: 'local("Helvetica"), url("./helvetica.otf") format(opentype) tech("variations"), url("./helvetica.ttf") format(truetype), url("./helvetica.woff2") format(woff2)',
  },
]);

breakpoints(value)

Description Default
value

Generates a set of media query strings for a given collection of breakpoints.

import { breakpoints, style } from "bakeware";

const breakpoint = breakpoints({
  sm: "600px",
  md: "900px",
  lg: "1200px",
});
// {
//   sm: "(min-width: 600px)",
//   md: "(min-width: 900px)",
//   lg: "(min-width: 1200px)",
//   not: {
//     sm: "not all and (min-width: 600px)",
//     md: "not all and (min-width: 900px)",
//     lg: "not all and (min-width: 1200px)",
//   },
// }

style({
  "@media": {
    // >= 900px
    [breakpoint.md]: {
      display: "flex",
    },

    // < 900px
    [breakpoint.not.md]: {
      padding: "1rem",
    },
  },
});
// @media (min-width: 900px) {
//   display: flex;
// }
//
// @media not all and (min-width: 900px) {
//   padding: 1rem;
// }

// It accepts min, max and mediaType
breakpoints({
  mobile: { min: "240px", max: "479px" },
  tablet: { min: "480px", max: "1023px" },
  desktop: { min: "1024px" },
  print: { mediaType: "print" },
});
// {
//   mobile: "(min-width: 240px) and (max-width: 479px)",
//   tablet: "(min-width: 480px) and (max-width: 1023px)",
//   desktop: "(min-width: 1024px)",
//   print: "print",
//   not: {
//     mobile: "not all and (min-width: 240px) and (max-width: 479px)",
//     tablet: "not all and (min-width: 480px) and (max-width: 1023px)",
//     desktop: "not all and (min-width: 1024px)",
//     print: "not print"
//   }
// }

createTheme(themeContract?, tokens, debugId?)

Extends vanilla-extract's createTheme, exposing the vars values. Fully compatible with the original implementation.

Description Default
themeContract
tokens
debugId

createTheme.var(declaration)

Used to access the value of a custom property generated by createTheme.

Description Default
declaration The value returned by createTheme.
import { createTheme } from "bakeware";

const [_, vars] = createTheme({
  example: "#000",
});
// {
//   example: "var(--example_xxxxxxx)",
// }

createTheme.var(vars.example);
// "#000"

globalStyle(layer?, selector, rule)

Extends vanilla-extract's globalStyle, enabling a cleaner way to implement layers. If layer is not set, it behaves like the original function.

Description Default
layer CSS @layer name. undefined
selector
rule
import { globalStyle } from "bakeware";

globalStyle("reset", "*", {
  boxSizing: "border-box",
});
// @layer reset;
//
// @layer reset {
//   * {
//     box-sizing: border-box;
//   }
// }

globalStyles(layer?, rules)

Sets global styles all at once, with layer support.

Description Default
layer CSS @layer name. undefined
rules Object containing selectors as keys and rules as values.
import { globalStyles } from "bakeware";

globalStyles("reset", {
  "*": {
    boxSizing: "border-box",
  },
  svg: {
    display: "inline-block",
  },
});
// @layer reset;
//
// @layer reset {
//   * {
//     box-sizing: border-box;
//   }
//   svg {
//     display: inline-block;
//   }
// }

License

The MIT License

Copyright (C) 2026-present stldo

About

Utility library handling the basic ingredients of styling, built to work alongside vanilla-extract

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages