npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cssints/gradient

v0.33.0

Published

Eased gradients for cssints: an easing curve expanded into colour stops (mixed in oklab) at build time

Readme

@cssints/gradient

Eased gradients for cssints: a gradient from one colour to another along an easing curve, expanded into colour stops at build time, so the fade has no hard edge where a two-stop gradient shows one. It is one value member of cssints/plugin scope() and returns an <image>, so it goes where an image goes (backgroundImage, maskImage, borderImageSource). No runtime.

import { backgroundImage, createTokens } from "cssints" with { type: "cssints" };
import { gradient } from "@cssints/gradient" with { type: "cssints" };

const t = createTokens({ color: { $type: "color", ink: { $value: "#111111" } } });

// gradient(kind, direction, from, to, easing?, stops?)
export const fade = backgroundImage(
  gradient("linear", "to bottom", "#000", "transparent", "ease-in-out", 5),
);
export const glow = backgroundImage(
  gradient("radial", "circle at top", "red", "blue", "cubic-bezier(0.5, 0, 0.5, 1)", 4),
);
export const ink = backgroundImage(
  gradient("linear", "to right", t.color.ink, "white", "ease-in", 4),
);
._4we9ve {
  background-image: linear-gradient(
    to bottom,
    #000,
    #000000d7 27.44%,
    #00000080 50%,
    #00000028 72.56%,
    transparent
  );
}
._ba8wye {
  background-image: radial-gradient(circle at top, red, #c44a6f 37.04%, #5348d0 62.96%, blue);
}
._1l9gl59 {
  background-image: linear-gradient(
    to right,
    var(--color-ink),
    color-mix(in oklab, var(--color-ink), white 25.93%) 44.59%,
    color-mix(in oklab, var(--color-ink), white 74.07%) 83.41%,
    white
  );
}

Rules

  • Arguments, each its own string: kind is linear, radial or conic; direction is that function's first argument, required ("to bottom", "45deg", "circle at top", "at center", "from 90deg"); from and to are colours or colour tokens; easing is linear, ease, ease-in, ease-out, ease-in-out (the default) or cubic-bezier(x1, y1, x2, y2); stops is 2 to 64 (13 by default). They are checked in the types and again at build time, against one grammar.
  • Stops are placed as postcss-easing-gradients places them: the curve's parameter t is sampled evenly, x(t) is the position of a stop and y(t) the share of to in it. A curve that overshoots (y outside 0 to 1) is clamped to the two colours.
  • Colours are mixed in oklab with premultiplied alpha, as CSS mixes them, so transparent fades the other colour's hue and does not grey it. The endpoints are printed as written; the stops between them are sRGB hex (#rrggbbaa when not opaque). Positions and shares have two decimals at most, so the output is the same on every build.
  • Tokens and currentColor. A token arrives as var(--name) and currentColor is the element's: neither can be read at build time. When an endpoint cannot be, every stop is color-mix(in oklab, from, to N%) at the same positions, and the browser mixes them. color-mix() needs Chrome 111, Safari 16.2, Firefox 113: for older targets the build warns, as it does for any value.
  • Errors, at the call: a part outside the grammar (gradient: unexpected "steps(4" in "linear to bottom red blue steps(4)", expected linear | <cubic-bezier-easing-function> | <integer> | end of value), arguments in the wrong order (cssints: gradient(): "blue" is not an easing (the arguments are kind, direction, from, to, easing?, stops?)), and a gradient where an image does not go (css.color(gradient(…)), an error in the types and at build time).

Limits

  • A stop between two literal colours is clamped to sRGB: a wide-gamut endpoint (color(display-p3 …), a vivid oklch()) keeps its own value at the end, but the colours between are the nearest sRGB ones. Give it as a token to keep the gamut: the stops are then color-mix().
  • steps() and linear() easings are not taken, nor an easing token (there is no easing token type), nor a number token for stops; a repeating-* gradient, more than two colours and a colour interpolation method (in oklch) are not either.
  • The parts are joined with a space for the grammar (see "Functions" in the API reference), so "to", "bottom" as two arguments passes the grammar and is caught only by the argument check; write the direction as one string.
cd packages/gradient && bun run test        # the stop math, fixtures through the engine (output, errors)
cd packages/gradient && bun run typecheck   # and the type test, test/types/gradient.ts

Credits

The stops follow postcss-easing-gradients and easing-coordinates (MIT, Andreas Larsen): the easing curve sampled into colour stops. The code is written here; no code is copied. Colours are mixed with culori (MIT, Dan Burzo), a dependency.