Skip to content

API Reference

Abdulkader Safi edited this page Jul 8, 2026 · 1 revision

API reference

Four functions, plus a default export that bundles them.

css(styleObject) => string

Returns a class name. Injects the rules once, keyed by a hash of the object. Call it again with an equivalent object and you get the same class back with no DOM work.

const cls = css({
  color: "white",
  padding: 16,
  "&:hover": { color: "cyan" },
  "& span": { fontWeight: 700 },
  "@media (max-width: 600px)": { padding: 8 },
});
el.className = cls;

Key rules:

  • Property keys are CSS properties in camelCase (backgroundColor) or kebab strings ("background-color"). Both work. camelCase is what gives you autocomplete and typo-catching.
  • String and number values become declarations. A number gets px, except for the unitless properties React treats specially (opacity, zIndex, fontWeight, lineHeight, flex, order, gridColumn, and the rest). Custom properties (--foo) never get a unit.
  • An object value is a nested block. A key starting with & is replaced by the generated class: "&:hover", "& > a", "& span", "&.active". A key starting with @ is an at-rule (@media, @supports).
  • Nest descendant selectors with &, so "& span", not a bare "span". That prefix is what lets TypeScript separate a real selector from a misspelled property.
  • An array value sets fallbacks for one property: display: ["grid", "flex"].

keyframes(framesObject) => string

Injects an @keyframes block and returns the animation name. Use it in an animation value.

const spin = keyframes({
  from: { transform: "rotate(0deg)" },
  to: { transform: "rotate(360deg)" },
});

el.className = css({ animation: `${spin} 1s linear infinite` });

Stops can be from/to or percentages like "0%" and "100%".

injectGlobal(styleObject) => void

Writes unscoped global rules: resets, :root custom properties, body styles. Top-level keys are selectors, not properties.

injectGlobal({
  ":root": { "--accent": "#22d3ee" },
  body: { margin: 0, fontFamily: "system-ui" },
  "*": { boxSizing: "border-box" },
});

setVars(vars, target?) => void

Sets CSS custom properties at runtime. Defaults to :root; pass an element to scope them. Define var(--accent) in your styles, then call setVars to change it live. Everything using the variable updates with no re-injection.

setVars({ "--accent": "#f00" }); // on :root
setVars({ accent: "blue" }, myEl); // scoped, "--" added for you

Default export

The default export bundles all four functions. It is what the global build exposes as window.SafiCSS.

import SafiCSS from "saficss";
SafiCSS.css({ color: "red" });

Clone this wiki locally