Skip to content

Diamond Gradients

A diamond gradient is a gradiente-specific gradient kind. It behaves like a radial gradient from the user's point of view, but it uses a diamond distance field instead of a circular distance field. Pixels are measured by how far they move horizontally and vertically from the center, so equal-distance contours form diamonds.

That makes diamond-gradient(...) useful for faceted glows, UI highlights, isometric-looking surfaces, hard-edged bands, generated pattern systems, and effects where a radial gradient feels too round.

css
diamond-gradient(farthest-corner at 48% 45% in oklch, #5851db 0%, #c13584 35%, #fcb045 70%, #405de6 100%)
Diamond gradient exampleOff-center OKLCH diamond fielddiamond-gradient(at 48% 45% in oklch, #5851db 0%, #c13584 35%, #fcb045 70%, #405de6 100%)
Preview loads when it reaches the viewport.

diamond-gradient is not a native CSS gradient function. Every preview block on this page is rendered by gradiente in four targets at once: CSS target, Canvas 2D, Canvas WebGL, and SVG. The CSS target is a generated SVG data URL, and the SVG target is a pattern payload. The WebGL column is captured as a snapshot so the page does not keep many live WebGL contexts open at the same time.

gradiente integration

Use a diamond gradient in your framework

Diamond gradients are not native CSS functions, so transformTo('css') returns a background-ready SVG data URL. The same parsed gradiente model can still be mounted in React, Vanilla JS, Vue, or Svelte.

ReactDiamondGradientPreview.tsx

What A Diamond Gradient Contains

The diamond gradient model has five conceptual parts:

Function name`diamond-gradient(...)` or `repeating-diamond-gradient(...)`. The public instance type remains `diamond-gradient`; repeating is stored as config.
Distance fieldA diamond metric. `circle` keeps x/y radii equal; `ellipse` allows different x/y radii.
SizeAn extent keyword such as `closest-side`, `closest-corner`, `farthest-side`, `farthest-corner`, or explicit length/percentage radii.
PositionA center point introduced by `at`, such as `at left top`, `at center`, or `at 25% 75%`.
Stop listColor stops, optional percentage positions, optional double positions, and color hints along the diamond radius.

Internally, GradientDiamond reuses the radial config model. The important difference is not the public syntax; it is the distance calculation used by the renderers.

ts
type GradientDiamondConfig = GradientRadialConfig

type GradientDiamondConfigResolved = {
  shape: 'circle' | 'ellipse'
  size:
    | {
        kind: 'extent'
        value: 'closest-side' | 'closest-corner' | 'farthest-side' | 'farthest-corner'
      }
    | {
        kind: 'explicit'
        x: GradientLengthPercentage
        y?: GradientLengthPercentage
      }
  position: GradientPosition
  interpolation: {
    colorSpace: GradientColorSpace
    hue?: GradientHueInterpolation
  }
  isRepeating?: boolean
}

Stop positions are normalized numbers where 0 means the center and 1 means the resolved diamond boundary. Repeating renderers can sample beyond 1 when the visible rectangle needs additional diamond bands to cover the corners.

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

What gradiente Does

For diamond-gradient, gradiente handles the work that cannot be delegated to native CSS:

  • Parses diamond strings into a GradientDiamond instance.
  • Stores size, center position, interpolation, stops, and repeating state.
  • Reuses radial config parsing without exposing a separate one-off model.
  • Resolves default values from one constructor location.
  • Resolves missing stop positions.
  • Preserves color hints as first-class stop data.
  • Compacts double-position stops during serialization.
  • Samples the diamond field for CSS and SVG targets.
  • Draws the same model to Canvas 2D and Canvas WebGL.
  • 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
diamond-gradient(
  [shape] [size] [at position] [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 diamond config tokens. Everything after the first comma belongs to the stop list.

css
diamond-gradient(closest-side at 30% 35% in oklch, red 0%, 35%, blue 100%)
Diamond gradient exampleSize, position, interpolation, color hint, and stopsdiamond-gradient(closest-side at 30% 35% in oklch, red 0%, 35%, blue 100%)
Preview loads when it reaches the viewport.

That example contains:

  • closest-side: the diamond reaches the closest side from its center.
  • at 30% 35%: the center is placed near the upper-left area.
  • in oklch: colors are interpolated in OKLCH.
  • red 0%: the first color stop is placed at the center.
  • 35%: a color hint that moves the midpoint of the red-to-blue transition.
  • blue 100%: the final color stop is placed at the resolved diamond boundary.

Defaults

If diamond config is omitted, gradiente uses the same config defaults as the radial family:

css
diamond-gradient(red, blue)
Diamond gradient exampleDefault diamond gradientdiamond-gradient(red, blue)
Preview loads when it reaches the viewport.

The class defaults are:

txt
shape: "ellipse"
size.kind: "extent"
size.value: "farthest-corner"
position: center center
interpolation.colorSpace: "srgb"
isRepeating: false

Default values are omitted from toString(). That is why diamond-gradient(ellipse farthest-corner at center in srgb, red, blue) can serialize to the compact diamond-gradient(red, blue).

Diamond Geometry

The diamond renderer uses a Manhattan-like distance field:

txt
t = abs(x - center.x) / radius.x + abs(y - center.y) / radius.y

The color is sampled at t. When t is 0, the pixel is at the center. When t is 1, the pixel lies on the resolved diamond boundary. Values above 1 are outside that boundary and matter mostly for repeating gradients or for filling the outer area.

circle keeps the x and y radii equal, so the diamond has symmetrical axes.

css
diamond-gradient(circle, red, blue)
Diamond gradient exampleCircle-shaped diamond metricdiamond-gradient(circle, red, blue)
Preview loads when it reaches the viewport.

ellipse allows different x and y radii. It is the default because it adapts better to rectangular boxes.

css
diamond-gradient(ellipse 35% 70%, cyan, blue 60%, black)
Diamond gradient exampleExplicit stretched diamonddiamond-gradient(35% 70%, cyan 0%, blue 60%, black 100%)
Preview loads when it reaches the viewport.

The words circle and ellipse are inherited from radial syntax, but for a diamond gradient they describe the radii used by the diamond distance field, not a circular visual shape.

Size

Size determines the resolved x/y radii used by the diamond field. It can be keyword-based or explicit.

The extent keywords are:

`closest-side`The diamond reaches the closest side from the center.
`closest-corner`The diamond reaches the closest corner from the center.
`farthest-side`The diamond reaches the farthest side from the center.
`farthest-corner`The diamond reaches the farthest corner from the center. This is the default.

closest-side is useful for local highlights that should stop quickly.

css
diamond-gradient(closest-side, red, blue)
Diamond gradient exampleclosest-side extentdiamond-gradient(closest-side, red, blue)
Preview loads when it reaches the viewport.

closest-corner depends on both the center and the rectangular paint area.

css
diamond-gradient(closest-corner at 25% 75%, #ff74f6, #405de6)
Diamond gradient exampleclosest-corner extentdiamond-gradient(closest-corner at 25% 75%, #ff74f6, #405de6)
Preview loads when it reaches the viewport.

farthest-side creates broader fields without forcing the diamond to reach the farthest corner.

css
diamond-gradient(farthest-side at left center, #ff74f6, #405de6)
Diamond gradient examplefarthest-side extentdiamond-gradient(farthest-side at left center, #ff74f6, #405de6)
Preview loads when it reaches the viewport.

Explicit sizes use concrete radii. A circle uses one length value; an ellipse can use two length or percentage values. For an explicit diamond ellipse, the first value is the x radius and the second value is the y radius:

css
diamond-gradient(40% 80% at 35% 65% in oklab, red 0%, yellow 50%, blue 100%)
Diamond gradient exampleExplicit x/y radiidiamond-gradient(40% 80% at 35% 65% in oklab, red, yellow, blue)
Preview loads when it reaches the viewport.

Position

Position moves the diamond center. It always follows at.

Keyword positions use x/y keywords:

css
diamond-gradient(at top left, red, blue)
Diamond gradient exampleKeyword positiondiamond-gradient(at left top, red, blue)
Preview loads when it reaches the viewport.

gradiente normalizes keyword positions into x/y order. For example, at top left serializes as at left top.

Value positions use two length-percentage values:

css
diamond-gradient(at 25% 75%, red, blue)
Diamond gradient examplePercentage positiondiamond-gradient(at 25% 75%, red, blue)
Preview loads when it reaches the viewport.

The current parser keeps positions strict: keyword positions are keyword-only, and value positions require two length-percentage tokens. Mixed CSS forms such as left 20px top 10px are not part of this model yet.

Stop List

The stop list defines what colors appear as the diamond expands away from the center. A practical diamond gradient usually has 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
diamond-gradient(red 0%, yellow 40%, blue 100%)
Diamond gradient examplePositioned color stopsdiamond-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
diamond-gradient(red 0%, 35%, blue 100%)
Diamond gradient exampleColor hintdiamond-gradient(red 0%, 35%, blue 100%)
Preview loads when it reaches the viewport.

Double-position stops create hard diamond bands. 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
diamond-gradient(red 0% 35%, blue 35% 100%)
Diamond gradient exampleHard diamond bandsdiamond-gradient(red 0% 35%, blue 35% 100%)
Preview loads when it reaches the viewport.

Interpolation

Interpolation controls the path between colors. It matters a lot for diamond gradients because the sharp center and diagonal bands make muddy midpoints or abrupt hue changes very visible.

The default interpolation space is srgb.

css
diamond-gradient(in srgb, red, blue)
Diamond gradient examplesRGB interpolationdiamond-gradient(red, blue)
Preview loads when it reaches the viewport.

Perceptual spaces such as oklab often produce smoother ramps.

css
diamond-gradient(at 25% 75% in oklab, red, blue)
Diamond gradient exampleOKLab interpolationdiamond-gradient(at 25% 75% 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
diamond-gradient(in oklch longer hue, hsl(325, 64%, 54%), hsl(208, 94%, 47%))
Diamond gradient exampleOKLCH longer hue interpolationdiamond-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 Diamond Gradients

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

css
repeating-diamond-gradient(at center, red 0%, blue 20%)
Diamond gradient exampleRepeating diamond gradientrepeating-diamond-gradient(red 0%, blue 20%)
Preview loads when it reaches the viewport.

Repeating diamond gradients are useful for hard-edged UI rings, scan effects, generated pattern systems, isometric grids, warning fields, and abstract backgrounds.

Programmatic Construction

Most users should start with parse() because it gives you the same input shape used by the DSL. When you need to build a gradient directly, use GradientDiamond.

The constructor takes two parameters:

txt
new GradientDiamond(stops, config?)

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

ts
import { GradientDiamond } from 'gradiente'

const gradient = new GradientDiamond(
  [
    {
      type: 'color-stop',
      value: '#ff74f6',
      position: 0,
    },
    {
      type: 'color-stop',
      value: '#405de6',
      position: 1,
    },
  ],
  {
    size: {
      kind: 'extent',
      value: 'closest-side',
    },
    position: {
      kind: 'values',
      x: {
        kind: 'percent',
        value: 35,
      },
      y: {
        kind: 'percent',
        value: 45,
      },
    },
    interpolation: {
      colorSpace: 'oklch',
    },
  },
)
Diamond gradient exampleEquivalent constructor outputdiamond-gradient(closest-side at 35% 45% in oklch, #ff74f6, #405de6)
Preview loads when it reaches the viewport.

Transforming A Diamond 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(
  'diamond-gradient(40% 80% at 35% 65% 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)
Diamond gradient exampleRenderer transformer inputdiamond-gradient(40% 80% at 35% 65% in oklch longer hue, #ff74f6, #405de6)
Preview loads when it reaches the viewport.

The transformer outputs have different shapes:

`css`A CSS background string. For diamond gradients it is a generated SVG data URL because CSS has no native `diamond-gradient()` function.
`canvas-2d`A paint object with `draw(ctx, width, height)`.
`canvas-webgl`A paint object with `draw(canvas, width, height)`.
`svg`An SVG pattern 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 = 'diamond-gradient(closest-side at 35% 45% in oklch, #ff74f6 0%, 42%, #405de6 100%)'
const normalized = format(input)
Diamond gradient exampleFormatted user inputdiamond-gradient(closest-side at 35% 45% 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.

Practical Checklist

Use this order when building or validating a diamond gradient:

  1. Choose whether the default ellipse metric is enough or whether circle should force equal x/y radii.
  2. Choose a size: an extent keyword for adaptive behavior, explicit radii for controlled geometry.
  3. Choose a position with at when the diamond center should move away from the default center.
  4. Choose interpolation: srgb for simple parity, oklab or oklch for smoother ramps.
  5. Add at least two color stops for useful visual output.
  6. Add explicit stop positions when band widths must survive editing.
  7. Use color hints when the transition midpoint needs to move.
  8. Use double-position stops when you need hard diamond bands.
  9. Use format() before storing user input.
  10. Use transformTo() for renderer output instead of trying to hand-convert the string.