Skip to content

Linear Gradients

A linear gradient is a color ramp projected along a straight axis. The renderer places an invisible line across the paint area, maps each pixel onto that line, and samples the ordered stops at the matching position.

In gradiente, a linear gradient is not just a CSS string. It is a typed gradient model with direction, interpolation settings, stops, optional color hints, and a repeating flag. The same model can be transformed into CSS, Canvas 2D, Canvas WebGL, SVG, or a custom transformer target.

css
linear-gradient(120deg in oklch, #ff74f6 0%, #fb7655 45%, #405de6 100%)
Linear gradient example120deg OKLCH ramplinear-gradient(120deg in oklch, #ff74f6 0%, #fb7655 45%, #405de6 100%)
Preview loads when it reaches the viewport.

Every preview block on this page renders the same source gradient in four targets at once: CSS, Canvas 2D, Canvas WebGL, and SVG. The WebGL column is a snapshot generated through transformTo('canvas-webgl', gradient) so the page does not keep many live WebGL contexts open at the same time. Preview rendering is lazy-loaded as each example approaches the viewport.

gradiente integration

Use a linear gradient in your framework

The same gradiente model can be mounted in React, Vanilla JS, Vue, or Svelte. Each example parses the source string, converts it through transformTo('css'), and applies the result as a real background image.

ReactLinearGradientPreview.tsx

What A Linear Gradient Contains

The linear gradient model has four conceptual parts:

Function name`linear-gradient(...)` or `repeating-linear-gradient(...)`. The public instance type remains `linear-gradient`; repeating is stored as config.
DirectionA keyword direction such as `to right`, a diagonal such as `to top left`, or an angle such as `120deg`, `0.25turn`, `1.57rad`, or `100grad`.
InterpolationThe color space after `in`, plus an optional hue route for polar color spaces: `shorter`, `longer`, `increasing`, or `decreasing`.
Stop listColor stops, optional percentage positions, optional double positions, and color hints.

The model that gradiente stores is renderer-agnostic:

ts
type GradientLinearConfig = {
  angle: number
  interpolation: {
    colorSpace: GradientColorSpace
    hue?: GradientHueInterpolation
  }
  isRepeating?: boolean
}

The angle is normalized to radians. Stop positions are stored as normalized numbers where 0 means 0% and 1 means 100%.

The stop model for a linear gradient is the shared gradiente stop model:

ts
type GradientLinearStop =
  | {
      type: 'color-stop'
      value: string
      position: number
    }
  | {
      type: 'color-hint'
      position: number
    }

Color values stay as strings so they can preserve author intent. Renderers convert and sample them only when they need concrete colors.

What gradiente Does

For linear-gradient, gradiente handles the work that usually gets scattered across parsers, UI code, serializers, and renderers:

  • Parses CSS-like strings into a GradientLinear instance.
  • Normalizes direction into radians.
  • Resolves missing stop positions.
  • Sorts stops while preserving stable order for equal positions.
  • Preserves color hints as first-class stop data.
  • Compacts double-position stops during serialization.
  • Stores repeating state from repeating-linear-gradient(...).
  • Samples interpolation for renderers that need concrete color stops.
  • Transforms the same model to CSS, Canvas 2D, Canvas WebGL, and SVG.

Anatomy

The full syntax has one optional configuration item followed by a required stop list:

css
linear-gradient(
  [direction] [in color-space [hue-mode hue]],
  color-stop-or-hint,
  color-stop-or-hint,
  ...
)

The first comma-separated item is treated as configuration only when it contains direction or interpolation tokens. Everything after the first comma belongs to the stop list.

css
linear-gradient(to right in oklch, red 0%, 35%, blue 100%)
Linear gradient exampleDirection, interpolation, color hint, and stopslinear-gradient(to right in oklch, red 0%, 35%, blue 100%)
Preview loads when it reaches the viewport.

That example contains:

  • to right: the gradient axis goes left to right.
  • in oklch: colors are interpolated in OKLCH.
  • red 0%: the first color stop is placed at the start.
  • 35%: a color hint that moves the midpoint of the red-to-blue transition.
  • blue 100%: the final color stop is placed at the end.

Direction

Direction decides how the invisible sampling line crosses the paint box.

If direction is omitted, gradiente uses the CSS-like default: top to bottom. The internal angle is Math.PI radians and the serializer omits it because it is the default.

css
linear-gradient(red, blue)
Linear gradient exampleDefault directionlinear-gradient(red, blue)
Preview loads when it reaches the viewport.

Keyword directions are best when authoring by hand because they are readable.

css
linear-gradient(to right, red, blue)
Linear gradient exampleKeyword directionlinear-gradient(to right, red, blue)
Preview loads when it reaches the viewport.

Diagonal keyword directions are also supported.

css
linear-gradient(to top left, red 0%, blue 100%)
Linear gradient exampleDiagonal keyword directionlinear-gradient(to top left, red, blue)
Preview loads when it reaches the viewport.

Numeric angles are better for generated data, animation, or precise controls. gradiente accepts deg, rad, turn, and grad.

css
linear-gradient(0.25turn, red, blue)
Linear gradient exampleNumeric anglelinear-gradient(to right, red, blue)
Preview loads when it reaches the viewport.

Angles are normalized. For example, 450deg is equivalent to 90deg, so serialization can become to right.

css
linear-gradient(450deg, red, blue)
Linear gradient exampleNormalized anglelinear-gradient(to right, red, blue)
Preview loads when it reaches the viewport.

Common direction values map to these internal angles:

omitted / `to bottom``Math.PI` radians. This is the default and is omitted from `toString()`.
`to top``0` radians.
`to right``Math.PI / 2` radians.
`to left``Math.PI * 1.5` radians.
diagonals`to top right`, `to bottom right`, `to bottom left`, and `to top left` are stored as normalized diagonal angles.

Stop List

The stop list defines what colors appear on the gradient line and where they appear. Practical linear gradients usually have at least two color stops.

If a color stop has no explicit position, gradiente resolves it from neighboring stops. The first unresolved color stop becomes 0%; the last unresolved color stop becomes 100%; unresolved stops between known positions are distributed evenly.

css
linear-gradient(red 0%, yellow 40%, blue 100%)
Linear gradient examplePositioned color stopslinear-gradient(red 0%, yellow 40%, blue 100%)
Preview loads when it reaches the viewport.

Color hints are bare percentages between two color stops. They do not create a new color stop. They move the perceived midpoint of the interpolation segment.

css
linear-gradient(to right, red 0%, 35%, blue 100%)
Linear gradient exampleColor hintlinear-gradient(to right, red 0%, 35%, blue 100%)
Preview loads when it reaches the viewport.

Double-position stops create hard ranges. A color written with two positions is stored as two adjacent color stops with the same color, then serialized back into the compact form when possible.

css
linear-gradient(to right, red 0% 35%, blue 35% 100%)
Linear gradient exampleDouble-position stopslinear-gradient(to right, red 0% 35%, blue 35% 100%)
Preview loads when it reaches the viewport.

Interpolation

Interpolation controls the path between colors. This is one of the most important differences between a plain CSS string and gradiente's renderer model: Canvas 2D, WebGL, and SVG do not all support CSS Color 4 interpolation syntax natively, so gradiente resolves renderable color stops for those targets.

The default interpolation space is srgb.

css
linear-gradient(in srgb, red, blue)
Linear gradient examplesRGB interpolationlinear-gradient(red, blue)
Preview loads when it reaches the viewport.

Perceptual spaces such as oklab often produce smoother ramps.

css
linear-gradient(in oklab, red, blue)
Linear gradient exampleOKLab interpolationlinear-gradient(in oklab, red, blue)
Preview loads when it reaches the viewport.

Polar color spaces can use hue interpolation modes. gradiente supports shorter, longer, increasing, and decreasing.

css
linear-gradient(in oklch longer hue, hsl(325, 64%, 54%), hsl(208, 94%, 47%))
Linear gradient exampleOKLCH longer hue interpolationlinear-gradient(in oklch longer hue, hsl(325, 64%, 54%), hsl(208, 94%, 47%))
Preview loads when it reaches the viewport.

Supported color spaces are:

txt
oklab
lch
oklch
hsl
hwb
lab
srgb
srgb-linear
xyz
display-p3
a98-rgb
prophoto-rgb
rec2020

Repeating Linear Gradients

repeating-linear-gradient(...) uses the same internal gradient kind as linear-gradient(...). The prefix sets isRepeating: true in the config, while the instance type remains linear-gradient.

css
repeating-linear-gradient(to right, red 0%, blue 10%)
Linear gradient exampleRepeating linear gradientrepeating-linear-gradient(to right, red 0%, blue 10%)
Preview loads when it reaches the viewport.

Repeating gradients are especially useful for stripes, scanlines, rulers, debugging overlays, and generated pattern systems.

Programmatic Construction

Most users should start with parse() because it gives you the same input shape people already know from CSS. When you need to build a gradient directly, use GradientLinear.

The constructor takes two parameters:

txt
new GradientLinear(stops, config?)

stops is required. config is optional and missing values are resolved from class defaults.

ts
import { GradientLinear } from 'gradiente'

const gradient = new GradientLinear(
  [
    {
      type: 'color-stop',
      value: '#ff74f6',
      position: 0,
    },
    {
      type: 'color-stop',
      value: '#405de6',
      position: 1,
    },
  ],
  {
    angle: Math.PI / 2,
    interpolation: {
      colorSpace: 'oklch',
    },
  },
)
Linear gradient exampleEquivalent constructor outputlinear-gradient(to right in oklch, #ff74f6, #405de6)
Preview loads when it reaches the viewport.

Transforming A Linear Gradient

Every renderer target receives the same source model. That is the main point of the Core API: parse once, transform many times.

ts
import { parse, transformTo } from 'gradiente'

const gradient = parse(
  'linear-gradient(135deg in oklch longer hue, #ff74f6, #405de6)'
)

const css = transformTo('css', gradient)
const canvas2d = transformTo('canvas-2d', gradient)
const webgl = transformTo('canvas-webgl', gradient)
const svg = transformTo('svg', gradient)
Linear gradient exampleRenderer transformer inputlinear-gradient(to bottom right in oklch longer hue, #ff74f6, #405de6)
Preview loads when it reaches the viewport.

The transformer outputs have different shapes:

`css`A CSS background string.
`canvas-2d`A paint object with `draw(ctx, width, height)`.
`canvas-webgl`A paint object with `draw(canvas, width, height)`.
`svg`An SVG paint server payload with `defs`, `url`, and serialized SVG data.

Normalization

Use format() before storing user input. It parses the string into the internal model and serializes it back to the canonical gradiente string.

ts
import { format } from 'gradiente'

const input = 'linear-gradient(to right in oklch, #ff74f6 0%, 42%, #405de6 100%)'
const normalized = format(input)
Linear gradient exampleFormatted user inputlinear-gradient(to right in oklch, #ff74f6 0%, 42%, #405de6 100%)
Preview loads when it reaches the viewport.

Normalization is useful when users type gradients manually, when editor state is saved, or when generated gradients need stable output for tests and snapshots.

Defaults

These are the class defaults for a new linear gradient when config values are not provided:

txt
angle: Math.PI
interpolation.colorSpace: "srgb"
isRepeating: false

Default values are omitted from toString(). For example, 180deg and in srgb are default values for a non-repeating linear gradient, so they do not need to be serialized.

Practical Checklist

Use this order when building or validating a linear gradient:

  1. Choose a direction: a keyword for hand-authored gradients, an angle for generated data.
  2. Choose interpolation: srgb for CSS parity, oklab or oklch for smoother ramps.
  3. Add at least two color stops for useful visual output.
  4. Add explicit stop positions when the design must survive editing.
  5. Use color hints when the transition midpoint needs to move.
  6. Use double-position stops when you need hard bands.
  7. Use format() before storing user input.
  8. Use transformTo() for renderer output instead of hand-converting the string.