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

css-magic-gradient

v1.2.7

Published

Generate CSS gradients (linear, radial, conic) with TypeScript. Includes presets, WCAG accessibility utilities, Vue 3 and React reactive hooks.

Readme

TypeScript library for generating CSS gradients — linear, radial, and conic. Includes gradient presets, color harmony generators, WCAG accessibility utilities, CSS variable support, canvas export, Vue 3 reactive hooks, and React hooks — with a single runtime dependency.


Contents


Features

  • createLinearGradient — linear (and repeating) gradients from a single base color or explicit color stops; accepts hex, rgb(), hsl(), named CSS colors, and CSS variables; CSS Color Level 4 interpolation with in oklch / lab / hsl
  • createRadialGradient — radial gradients in auto-brightness, explicit stops, multi-layer, or color-harmony mode; circle / ellipse, custom size and position
  • createConicGradient — conic gradients with hue-rotation, color-scale, harmony, or explicit stops; createRainbowConicGradient for a full-spectrum rainbow in one call
  • Color harmony generatorscreateComplementaryGradient, createTriadicGradient, createAnalogousGradient, createTetradicGradient, createSplitComplementaryGradient — all backed by color-value-tools for perceptually uniform interpolation
  • Palette generatorscreateTintGradient, createShadeGradient, createToneGradient — Oklab-based tints, shades, and tones
  • 15 gradient presetssunsetGradient, oceanGradient, auroraGradient, and 12 more ready-to-use gradient strings
  • Accessibility (WCAG)bestGradientTextColor, gradientContrastRatio (11-point sampling), gradientWcagLevel, createAccessibleGradient — auto-adjust stops to meet AA / AAA
  • CSS variable utilitiesextractGradientVariables, resolveGradientVariables
  • Canvas & image exportgradientToCanvasGradient, gradientToImageData, gradientToDataURL; works with any CanvasRenderingContext2D or server-side canvas library
  • Vue 3 integrationVueGradientPlugin + 15 reactive use* hooks returning ComputedRef<string>; SSR-safe
  • React integration — same 15 hooks in css-magic-gradient/react; plain string via useMemo; no Vue dependency; SSR-safe
  • Full TypeScript — exported types for all options, return shapes, and discriminated unions
  • Single runtime dependencycolor-value-tools for color math; Vue and React are optional peer deps

Installation

npm install css-magic-gradient

Optional peer dependencies — install only what you need:

npm install vue@>=3.0.0    # required for Vue hooks
npm install react@>=17.0.0 # required for React hooks

Quick start

Vanilla TypeScript:

import { createLinearGradient, sunsetGradient } from 'css-magic-gradient'

const gradient = createLinearGradient('#3498db', { direction: 'to right' })
// → 'linear-gradient(to right, #5faee3, #3498db)'

document.body.style.background = sunsetGradient

Vue 3:

<script setup lang="ts">
import { ref } from 'vue'
import { useLinearGradient } from 'css-magic-gradient'

const color = ref('#3498db')
const gradient = useLinearGradient(color, { direction: 'to right', offsetPercent: 20 })
</script>

<template>
  <div :style="{ background: gradient }">Hello</div>
</template>

React:

import { useState } from 'react'
import { useLinearGradient } from 'css-magic-gradient/react'

export function Demo() {
  const [color, setColor] = useState('#3498db')
  const gradient = useLinearGradient(color, { direction: 'to right' })

  return <div style={{ background: gradient }}>Hello</div>
}

createLinearGradient

From a base color (auto-generates stops)

Accepts any color format: hex, rgb(), hsl(), named CSS color, or CSS variable.

import { createLinearGradient } from 'css-magic-gradient'

// Hex
createLinearGradient('#3498db')
// → 'linear-gradient(to bottom, #5faee3, #3498db)'

// Named color
createLinearGradient('cornflowerblue', { direction: 'to right', offsetPercent: 20 })

// CSS variable (uses fallback for brightness calculation)
createLinearGradient('var(--brand-color)', { fallbackColor: '#3498db' })

// Angle instead of direction keyword
createLinearGradient('#e74c3c', { angle: 135 })

// CSS Color Level 4 interpolation (oklch, lab, hsl, srgb, oklab, lch)
createLinearGradient('#9b59b6', { direction: 'to right', interpolation: 'oklch' })
// → 'linear-gradient(to right in oklch, …)'

// Repeating variant
createLinearGradient('#2ecc71', { angle: 45, repeating: true })
// → 'repeating-linear-gradient(45deg, …)'

GradientOptions

| Option | Type | Default | Description | |---|---|---|---| | direction | string | 'to bottom' | CSS direction keyword | | angle | number | — | Angle in degrees. Overrides direction | | offsetPercent | number | 15 | Brightness offset (%) for the lighter start stop | | fallbackColor | string | '#f5e477' | Fallback for CSS variables or unknown formats | | interpolation | 'srgb' \| 'oklch' \| 'lab' \| 'hsl' \| 'oklab' \| 'lch' | — | CSS Color Level 4 interpolation space | | repeating | boolean | false | Use repeating-linear-gradient |


From explicit color stops

createLinearGradient(
  [
    { color: '#ff6b6b', position: '0%' },
    { color: '#feca57', position: '50%' },
    { color: '#48dbfb', position: '100%' },
  ],
  { direction: 'to right' },
)
// → 'linear-gradient(to right, #ff6b6b 0%, #feca57 50%, #48dbfb 100%)'

// With per-stop opacity
createLinearGradient(
  [
    { color: '#e74c3c', opacity: 1, position: '0%' },
    { color: '#e74c3c', opacity: 0, position: '100%' },
  ],
  { angle: 90 },
)
// → 'linear-gradient(90deg, #e74c3c 0%, rgba(231, 76, 60, 0) 100%)'

// opacity: 0 shorthand → 'transparent'
createLinearGradient([{ color: '#3498db' }, { color: '#3498db', opacity: 0 }])

ColorStop

| Field | Type | Description | |---|---|---| | color | string | Any CSS color value | | opacity | number | 0–1. 0transparent. Applies via RGBA conversion | | position | string \| number | e.g. '0%', '20px' |


createMultiStepLinearGradient

Generates multiple evenly spaced stops by interpolating brightness from light to the base color.

import { createMultiStepLinearGradient } from 'css-magic-gradient'

createMultiStepLinearGradient('#3498db', 5, { offsetPercent: 25, direction: 'to right' })

| Parameter | Type | Default | Description | |---|---|---|---| | baseColor | string | — | Any supported color format | | steps | number | 3 | Number of color stops | | options | GradientOptions | — | Same as createLinearGradient |


createMixedLinearGradient

Creates a gradient by HSL-interpolating between two arbitrary colors across steps stops.

import { createMixedLinearGradient } from 'css-magic-gradient'

createMixedLinearGradient('#ff6b6b', '#4ecdc4', 7, { direction: 'to right' })
createMixedLinearGradient('tomato', 'steelblue', 5)
createMixedLinearGradient('rgb(255, 100, 100)', 'hsl(200, 60%, 50%)', 6)

createRadialGradient

From a base color

import { createRadialGradient } from 'css-magic-gradient'

createRadialGradient('#e74c3c')
// → 'radial-gradient(ellipse farthest-corner at center, #ed7060, #e74c3c)'

createRadialGradient('#9b59b6', {
  shape: 'circle',
  size: 'closest-side',
  position: '30% 60%',
  offsetPercent: 30,
})

From explicit color stops

createRadialGradient('#000', {
  colors: [
    { color: '#f39c12', position: '0%' },
    { color: '#e74c3c', position: '50%' },
    { color: '#8e44ad', opacity: 0.5, position: '100%' },
  ],
})

Multiple layers

createRadialGradient('#000', {
  layers: [
    {
      shape: 'circle',
      size: '40%',
      position: '30% 40%',
      colors: [{ color: '#f39c12' }, { color: 'transparent' }],
    },
    {
      shape: 'circle',
      size: '30%',
      position: '70% 60%',
      colors: [{ color: '#3498db' }, { color: 'transparent' }],
    },
  ],
})

Color harmony mode

// Automatically derive stops from a color harmony
createRadialGradient('#3498db', {
  harmonyType: 'triadic',
  interpolationSpace: 'oklch',
})

createRadialGradient('#e74c3c', {
  harmonyType: 'analogous',
  shape: 'circle',
})

RadialGradientOptions

| Option | Type | Default | Description | |---|---|---|---| | shape | 'circle' \| 'ellipse' | 'ellipse' | Gradient shape | | size | string \| { width, height } | 'farthest-corner' | Size keyword or explicit dimensions | | position | string | 'center' | Center position | | offsetPercent | number | 15 | Brightness offset for auto-generated stops | | fallbackColor | string | '#f5e477' | Fallback for unsupported color formats | | colors | ColorStop[] | — | Explicit stops (overrides auto-generation) | | layers | RadialGradientLayer[] | — | Multiple stacked layers | | repeating | boolean | false | Use repeating-radial-gradient | | harmonyType | 'complementary' \| 'triadic' \| 'tetradic' \| 'analogous' | — | Auto-generate stops from a color harmony | | interpolationSpace | 'rgb' \| 'hsl' \| 'oklab' \| 'oklch' | 'oklch' | Color space for JS-side interpolation |


createRadialGradientLayers

Utility that generates a set of RadialGradientLayer objects with evenly distributed sizes and harmony-derived colors. Produces a nested multi-ring radial effect when passed to createRadialGradient.

import { createRadialGradientLayers, createRadialGradient } from 'css-magic-gradient'

const layers = createRadialGradientLayers('#3498db', {
  count: 4,
  harmonyType: 'triadic',
  interpolationSpace: 'oklch',
  minSizePercent: 20,
  maxSizePercent: 100,
})

const gradient = createRadialGradient('#3498db', { layers })

| Option | Type | Default | Description | |---|---|---|---| | count | number | 3 | Number of layers | | minSizePercent | number | 20 | Smallest layer size (%) | | maxSizePercent | number | 100 | Largest layer size (%) | | harmonyType | RadialHarmonyType | 'analogous' | Color distribution strategy | | interpolationSpace | 'rgb' \| 'hsl' \| 'oklab' \| 'oklch' | 'oklch' | Color space for JS-side interpolation | | position | string | 'center' | Shared center position |


createConicGradient

import { createConicGradient } from 'css-magic-gradient'

// Auto brightness steps (default)
createConicGradient('#3498db', { steps: 10, offsetPercent: 25 })

// Hue rotation across the circle
createConicGradient('#e74c3c', { hueRotation: true, steps: 12 })

// Custom starting angle and position
createConicGradient('#9b59b6', { fromAngle: 45, position: '30% 70%' })

// Explicit color stops
createConicGradient('#000', {
  colors: [
    { color: '#ff6b6b', position: '0%' },
    { color: '#feca57', position: '25%' },
    { color: '#48dbfb', position: '75%' },
    { color: '#ff6b6b', position: '100%' },
  ],
})

// Color harmony mode — interpolates harmony colors around the full circle
createConicGradient('#e74c3c', { harmonyType: 'triadic', steps: 24 })
createConicGradient('#3498db', { harmonyType: 'tetradic', interpolationSpace: 'oklab' })

// Color scale mode — interpolates through an arbitrary list of colors
createConicGradient('#000', {
  colorScale: ['#ff0000', '#00ff00', '#0000ff'],
  steps: 36,
})

// Repeating variant
createConicGradient('#2ecc71', { repeating: true, steps: 4, offsetPercent: 30 })

ConicGradientOptions

| Option | Type | Default | Description | |---|---|---|---| | fromAngle | number | 0 | Starting angle in degrees | | position | string | '50% 50%' | Gradient center | | hueRotation | boolean | false | Rotate hue instead of adjusting brightness | | harmonyType | 'complementary' \| 'triadic' \| 'tetradic' \| 'analogous' | — | Generate from a color harmony | | colorScale | string[] | — | Interpolate through arbitrary colors around the circle | | interpolationSpace | 'rgb' \| 'hsl' \| 'oklab' \| 'oklch' | 'oklch' | Color space for JS-side interpolation | | steps | number | 8 | Number of generated stops | | offsetPercent | number | 20 | Brightness offset for auto-generated stops | | colors | ColorStop[] | — | Explicit stops | | fallbackColor | string | '#f5e477' | Fallback color | | repeating | boolean | false | Use repeating-conic-gradient |


createRainbowConicGradient

Generates a full-spectrum rainbow by cycling through all hues in HSL space.

import { createRainbowConicGradient } from 'css-magic-gradient'

createRainbowConicGradient()
createRainbowConicGradient({ steps: 24, saturation: 90, lightness: 55, fromAngle: 90 })
createRainbowConicGradient({ repeating: true, steps: 6 })

Presets

Ready-to-use gradient strings and dynamic generators.

Fixed gradient strings

import {
  sunsetGradient, oceanGradient, auroraGradient, fireGradient,
  midnightGradient, peachGradient, mintGradient, rainbowGradient, glowGradient,
  forestGradient, goldenHourGradient, neonGradient,
  nordicGradient, pastelGradient, deepSpaceGradient,
} from 'css-magic-gradient'

element.style.background = sunsetGradient

| Export | Description | |---|---| | sunsetGradient | Orange → magenta, bottom-right | | oceanGradient | Cyan → dark navy, bottom | | auroraGradient | Violet → green → teal, right | | fireGradient | Yellow → orange → red, top | | midnightGradient | Dark indigo → near-black | | peachGradient | Soft pink → warm orange | | mintGradient | Light green → teal | | rainbowGradient | Full-spectrum conic (24 steps) | | glowGradient | Radial warm-gold glow | | forestGradient | Light green → deep forest green | | goldenHourGradient | Warm gold → pink → orange | | neonGradient | Electric green → vivid pink → bright cyan | | nordicGradient | Icy blue → cool gray → near-white | | pastelGradient | Soft lavender → blush pink → pale mint | | deepSpaceGradient | Near-black navy → deep indigo → violet |

Color harmony generators

These use interpolateColors / createColorScale from color-value-tools for smooth perceptual transitions.

import {
  createComplementaryGradient,
  createTriadicGradient,
  createAnalogousGradient,
  createTetradicGradient,
  createSplitComplementaryGradient,
  createMonochromaticGradient,
  createHueWheelGradient,
} from 'css-magic-gradient'

// Base color ↔ complement, interpolated in oklch (default)
createComplementaryGradient('#3498db', { steps: 7, interpolationSpace: 'oklch' })

// Triadic — 3 colors 120° apart; smoothness = total interpolated steps
createTriadicGradient('#e74c3c', { smoothness: 9, interpolationSpace: 'oklab' })

// Analogous — spread controls hue angle passed to analogous()
createAnalogousGradient('#2ecc71', { spread: 45, steps: 7 })

// Tetradic — 4 colors 90° apart; supports linear, radial, conic
createTetradicGradient('#9b59b6', { type: 'linear' })
createTetradicGradient('#9b59b6', { type: 'conic',  steps: 24 })
createTetradicGradient('#9b59b6', { type: 'radial', interpolationSpace: 'oklch' })

// Split-complementary — base + two colors at 150° and 210°
createSplitComplementaryGradient('#3498db', { steps: 5 })

// Monochromatic shades via colorShades()
createMonochromaticGradient('#9b59b6', 7, { direction: 'to right' })

// Hue-wheel conic from any base color
createHueWheelGradient('#3498db', { steps: 16, fromAngle: 45 })

HarmonyGradientOptions

| Option | Type | Default | Description | |---|---|---|---| | direction | string | 'to right' | CSS direction keyword | | angle | number | — | Angle in degrees | | steps | number | 5 | Interpolation steps (3 = only anchor colors) | | interpolationSpace | 'rgb' \| 'hsl' \| 'oklab' \| 'oklch' | 'oklch' | Color space for JS-side interpolation |

interpolationSpace vs interpolationinterpolationSpace controls how JavaScript mixes colors when building the stop list (via createColorScale / interpolateColors). interpolation adds in oklch to the CSS output and lets the browser interpolate between stops. Harmony generators produce pre-computed stop arrays, so only interpolationSpace applies to them.

'lab' and 'lch' are intentionally absent from interpolationSpacecreateColorScale does not support them. Use 'oklab' and 'oklch' instead (perceptually superior successors).

Palette generators

Generate gradients through tints, shades, or tones using Oklab-based interpolation from color-value-tools.

import {
  createTintGradient,
  createShadeGradient,
  createToneGradient,
} from 'css-magic-gradient'

// Base color → white (through Oklab tints)
createTintGradient('#3498db', 7, { direction: 'to right' })

// Base color → black (through Oklab shades)
createShadeGradient('#e74c3c', 5)

// Base color → gray (through Oklab tones)
createToneGradient('#9b59b6', 7, { gray: '#707070' })

| Function | Description | |---|---| | createTintGradient(color, steps?, opts?) | Gradient from base color toward white | | createShadeGradient(color, steps?, opts?) | Gradient from base color toward black | | createToneGradient(color, steps?, opts?) | Gradient from base color toward gray. Accepts optional gray color |


Accessibility (WCAG)

bestGradientTextColor

Returns '#000000' or '#ffffff' — whichever achieves the best minimum contrast across all gradient stops.

import { bestGradientTextColor } from 'css-magic-gradient'

// Two-color gradient (backward-compatible)
bestGradientTextColor('#1a1a2e', '#e94560')
// → '#ffffff'

// Multi-stop gradient
bestGradientTextColor(['#1a1a2e', '#c0357a', '#e94560'])
// → '#ffffff'

// Detailed result with per-color scores
const detail = bestGradientTextColor(['#1a1a2e', '#e94560'], { detailed: true })
// → { recommended: '#ffffff', black: { contrast: 1.8, wcag: 'fail' }, white: { contrast: 9.3, wcag: 'AAA' } }

gradientContrastRatio

Returns the minimum WCAG contrast ratio of a text color against the gradient. Samples 11 evenly distributed points along the gradient.

import { gradientContrastRatio } from 'css-magic-gradient'

// Two colors (backward-compatible)
gradientContrastRatio('#ffffff', '#1a1a2e', '#e94560')
// → minimum ratio across all sampled points

// Array of stops
gradientContrastRatio('#ffffff', ['#1a1a2e', '#c0357a', '#e94560'])

gradientWcagLevel

Returns a detailed GradientWcagReport with the worst-case WCAG level, minimum contrast, and positions that fail the AA threshold.

import { gradientWcagLevel } from 'css-magic-gradient'

const report = gradientWcagLevel('#ffffff', '#1a1a2e', '#e94560')
// → {
//     level: 'AAA',
//     minContrast: 8.4,
//     problematicStops: []   // positions (0–1) where contrast < 4.5
//   }

// With a gradient that has a weak midpoint:
const report2 = gradientWcagLevel('#ffffff', ['#ffffff', '#aaaaaa', '#3498db'])
// → { level: 'fail', minContrast: 1.07, problematicStops: [0, 0.09, 0.18, …] }

GradientWcagReport

| Field | Type | Description | |---|---|---| | level | WcagLevel | Worst WCAG level found across all sampled stops | | minContrast | number | Minimum contrast ratio along the gradient | | problematicStops | number[] | Fractional positions (0–1) where contrast < 4.5 |

createAccessibleGradient

Auto-adjusts gradient stops until textColor achieves the target WCAG level.

import { createAccessibleGradient } from 'css-magic-gradient'

// Default: adjusts lightness in 5% steps until AA is met
createAccessibleGradient('#3498db', '#ffffff', {
  targetLevel: 'AA',
})

// Adjust saturation instead
createAccessibleGradient('#3498db', '#ffffff', {
  targetLevel: 'AAA',
  adjustmentStrategy: 'saturation',
})

// Adjust both lightness and saturation
createAccessibleGradient('#c0357a', '#000000', {
  adjustmentStrategy: 'both',
  direction: 'to right',
})

AccessibleGradientOptions

| Option | Type | Default | Description | |---|---|---|---| | direction | string | 'to bottom' | CSS direction keyword | | angle | number | — | Angle in degrees | | targetLevel | 'AAA' \| 'AA' \| 'AA-large' | 'AA' | Minimum WCAG contrast level | | adjustmentStrategy | 'lightness' \| 'saturation' \| 'both' | 'lightness' | How color stops are adjusted | | interpolation | ColorInterpolation | — | CSS Color Level 4 interpolation | | repeating | boolean | false | Use repeating-linear-gradient |


CSS variable utilities

import { extractGradientVariables, resolveGradientVariables } from 'css-magic-gradient'

const gradient = 'linear-gradient(var(--start, #ff0000), var(--end))'

// Extract all CSS custom property names
extractGradientVariables(gradient)
// → ['--start', '--end']

// Substitute variables from a map; falls back to inline fallback or preserves var()
resolveGradientVariables(gradient, { '--end': '#0000ff' })
// → 'linear-gradient(#ff0000, #0000ff)'

Canvas & image export

Render gradients to canvas or image data — useful for Open Graph image generation, canvas-based UIs, or server-side rendering with a canvas library (e.g. the canvas npm package).

gradientToCanvasGradient

Creates a CanvasGradient object from the given parameters and applies all color stops.

import { gradientToCanvasGradient } from 'css-magic-gradient'

const gradient = gradientToCanvasGradient(
  {
    type: 'linear',
    stops: [
      { color: '#ff9a3c', offset: 0 },
      { color: '#c0357a', offset: 1 },
    ],
  },
  ctx,
)

ctx.fillStyle = gradient
ctx.fillRect(0, 0, canvas.width, canvas.height)

Gradient types:

// Linear (x0,y0) → (x1,y1); defaults: left-to-right across canvas
{ type: 'linear', stops, x0?, y0?, x1?, y1? }

// Radial — two circles; defaults: concentric circles centered in canvas
{ type: 'radial', stops, x0?, y0?, r0?, x1?, y1?, r1? }

// Conic — startAngle in radians; defaults: center of canvas, 0 rad
{ type: 'conic', stops, startAngle?, x?, y? }

gradientToImageData

Renders the gradient into an ImageData object of the given size.

import { gradientToImageData } from 'css-magic-gradient'

const imageData = gradientToImageData(
  {
    type: 'radial',
    stops: [{ color: '#ffffff', offset: 0 }, { color: '#3498db', offset: 1 }],
  },
  800, 600,
)

gradientToDataURL

Renders the gradient as a PNG data URL (e.g. for <img src> or CSS background).

import { gradientToDataURL } from 'css-magic-gradient'

const dataUrl = gradientToDataURL(
  {
    type: 'linear',
    stops: [{ color: '#ff9a3c', offset: 0 }, { color: '#c0357a', offset: 1 }],
  },
  400, 200,
)
// → 'data:image/png;base64,…'

Note: Canvas functions require a browser or a server-side canvas implementation. In environments without document or OffscreenCanvas, they throw a descriptive error.


Vue 3 integration

All hooks return a ComputedRef<string> that reacts to Ref<> inputs. All hooks are SSR-safe — no DOM access occurs during computation.

Setup

// main.ts
import { createApp } from 'vue'
import { VueGradientPlugin } from 'css-magic-gradient'
import App from './App.vue'

createApp(App).use(VueGradientPlugin).mount('#app')

Example

<script setup lang="ts">
import { ref } from 'vue'
import {
  useLinearGradient,
  useMixedLinearGradient,
  useConicGradient,
  useTetradicGradient,
  useTintGradient,
  useAccessibleGradient,
} from 'css-magic-gradient'

const color = ref('#3498db')

const linear     = useLinearGradient(color, { direction: 'to right', offsetPercent: 20 })
const mixed      = useMixedLinearGradient(color, ref('#e74c3c'), 7)
const conic      = useConicGradient(color, { hueRotation: true, steps: 12 })
const tetradic   = useTetradicGradient(color, { type: 'conic', steps: 24 })
const tint       = useTintGradient(color, 7)
const accessible = useAccessibleGradient(color, ref('#ffffff'), { targetLevel: 'AA' })
</script>

<template>
  <div :style="{ background: linear }">Linear</div>
  <div :style="{ background: tetradic }">Tetradic conic</div>
  <div :style="{ background: tint }">Tint</div>
  <div :style="{ background: accessible }">Accessible</div>
</template>

Vue hooks

| Hook | Returns | Description | |---|---|---| | useLinearGradient(first, options?) | ComputedRef<string> | Linear gradient from color or stops | | useMultiStepLinearGradient(color, steps?, options?) | ComputedRef<string> | Multi-stop brightness gradient | | useMixedLinearGradient(colorA, colorB, steps?, options?) | ComputedRef<string> | HSL-interpolated two-color gradient | | useRadialGradient(color, options?) | ComputedRef<string> | Radial gradient | | useConicGradient(color, options?) | ComputedRef<string> | Conic gradient | | useRainbowConicGradient(options?) | ComputedRef<string> | Full-spectrum rainbow conic | | useComplementaryGradient(color, options?) | ComputedRef<string> | Complementary harmony gradient | | useTriadicGradient(color, options?) | ComputedRef<string> | Triadic harmony gradient | | useAnalogousGradient(color, options?) | ComputedRef<string> | Analogous harmony gradient | | useTetradicGradient(color, options?) | ComputedRef<string> | Tetradic harmony gradient (linear/radial/conic) | | useSplitComplementaryGradient(color, options?) | ComputedRef<string> | Split-complementary harmony gradient | | useTintGradient(color, steps?, options?) | ComputedRef<string> | Tint gradient (base → white) | | useShadeGradient(color, steps?, options?) | ComputedRef<string> | Shade gradient (base → black) | | useToneGradient(color, steps?, options?) | ComputedRef<string> | Tone gradient (base → gray) | | useAccessibleGradient(color, textColor, options?) | ComputedRef<string> | Auto-adjusted WCAG-compliant gradient |

Global properties (after VueGradientPlugin install)

this.$useLinearGradient(color, options)
this.$useTetradicGradient(color, options)
this.$useTintGradient(color, steps, options)
this.$useAccessibleGradient(color, textColor, options)
// … all hooks available as $use* on the Vue instance

React integration

Import from css-magic-gradient/react. React is an optional peer dependency — the main bundle is unaffected. All hooks return a plain string memoized with useMemo, and are SSR-safe.

Example

import { useState } from 'react'
import {
  useLinearGradient,
  useTetradicGradient,
  useTintGradient,
  useAccessibleGradient,
} from 'css-magic-gradient/react'

export function GradientShowcase() {
  const [color, setColor] = useState('#3498db')

  const linear     = useLinearGradient(color, { direction: 'to right', offsetPercent: 20 })
  const tetradic   = useTetradicGradient(color, { type: 'conic', steps: 24 })
  const tint       = useTintGradient(color, 7)
  const accessible = useAccessibleGradient(color, '#ffffff', { targetLevel: 'AA' })

  return (
    <div>
      <input type="color" value={color} onChange={e => setColor(e.target.value)} />
      <div style={{ background: linear,     height: 80, borderRadius: 8 }} />
      <div style={{ background: tetradic,   height: 80, borderRadius: 8 }} />
      <div style={{ background: tint,       height: 80, borderRadius: 8 }} />
      <div style={{ background: accessible, height: 80, borderRadius: 8 }} />
    </div>
  )
}

React hooks

| Hook | Returns | Description | |---|---|---| | useLinearGradient(first, options?) | string | Linear gradient from color or stops | | useMultiStepLinearGradient(color, steps?, options?) | string | Multi-stop brightness gradient | | useMixedLinearGradient(colorA, colorB, steps?, options?) | string | HSL-interpolated two-color gradient | | useRadialGradient(color, options?) | string | Radial gradient | | useConicGradient(color, options?) | string | Conic gradient | | useRainbowConicGradient(options?) | string | Full-spectrum rainbow conic | | useComplementaryGradient(color, options?) | string | Complementary harmony gradient | | useTriadicGradient(color, options?) | string | Triadic harmony gradient | | useAnalogousGradient(color, options?) | string | Analogous harmony gradient | | useTetradicGradient(color, options?) | string | Tetradic harmony gradient (linear/radial/conic) | | useSplitComplementaryGradient(color, options?) | string | Split-complementary harmony gradient | | useTintGradient(color, steps?, options?) | string | Tint gradient (base → white) | | useShadeGradient(color, steps?, options?) | string | Shade gradient (base → black) | | useToneGradient(color, steps?, options?) | string | Tone gradient (base → gray) | | useAccessibleGradient(color, textColor, options?) | string | Auto-adjusted WCAG-compliant gradient |


TypeScript types

All public types are exported from the package root:

import type {
  // Color stop
  ColorStop,

  // Linear gradient
  GradientOptions,
  ColorInterpolation,

  // Radial gradient
  RadialGradientOptions,
  RadialGradientLayer,
  RadialHarmonyType,

  // Conic gradient
  ConicGradientOptions,

  // Harmony generators
  HarmonyGradientOptions,

  // Accessibility
  AccessibleGradientOptions,
  GradientWcagReport,
  WcagLevel,

  // Canvas export
  CanvasGradientConfig,
  CanvasGradientStop,
} from 'css-magic-gradient'

WcagLevel values:

type WcagLevel = 'AAA' | 'AA' | 'AA-large' | 'fail'

ColorInterpolation values:

type ColorInterpolation = 'srgb' | 'oklch' | 'lab' | 'hsl' | 'oklab' | 'lch'

Custom serializer / color stop example:

import type { ColorStop, GradientOptions } from 'css-magic-gradient'

const stops: ColorStop[] = [
  { color: '#ff6b6b', position: '0%' },
  { color: '#feca57', opacity: 0.8, position: '100%' },
]

const opts: GradientOptions = {
  direction: 'to right',
  interpolation: 'oklch',
}

Architecture

css-magic-gradient
│
├── createLinearGradient      — linear-gradient / repeating-linear-gradient
│     Auto-brightness mode    — lighter start stop derived from base color
│     ColorStop[] mode        — explicit stop array; per-stop opacity → rgba()
│     CSS Color Level 4       — appends `in <space>` to the gradient declaration
│
├── createRadialGradient      — radial-gradient / repeating-radial-gradient
│     Auto / explicit / layers / harmony modes
│     createRadialGradientLayers — generates multi-ring layer arrays
│
├── createConicGradient       — conic-gradient / repeating-conic-gradient
│     createRainbowConicGradient — full HSL hue cycle
│
├── Color harmony generators
│     createComplementaryGradient / createTriadicGradient
│     createAnalogousGradient / createTetradicGradient
│     createSplitComplementaryGradient / createMonochromaticGradient
│     createHueWheelGradient
│     — all use interpolateColors / createColorScale from color-value-tools
│
├── Palette generators
│     createTintGradient / createShadeGradient / createToneGradient
│     — use Oklab-based tints / shades / tones from color-value-tools
│
├── Presets (src/presets.ts)
│     15 fixed gradient strings
│
├── Accessibility (src/accessibility.ts)
│     bestGradientTextColor    — pick #000 or #fff for best contrast
│     gradientContrastRatio    — minimum contrast across 11 sample points
│     gradientWcagLevel        — detailed GradientWcagReport
│     createAccessibleGradient — iterate adjustments until target level is met
│
├── CSS variable utilities (src/css-variables.ts)
│     extractGradientVariables — parse var() names from a gradient string
│     resolveGradientVariables — substitute variable values with a map
│
├── Canvas export (src/canvas-export.ts)
│     gradientToCanvasGradient — applies stops to a CanvasGradient
│     gradientToImageData      — renders to ImageData at given dimensions
│     gradientToDataURL        — renders to PNG data URL
│
├── Vue 3 integration (src/vue-gradient-plugin.ts)
│     VueGradientPlugin        — registers $use* on the Vue instance
│     useLinearGradient / useRadialGradient / useConicGradient
│     use*Gradient hooks       — ComputedRef<string>; SSR-safe; no DOM access
│
└── React integration (src/react-gradient-plugin.ts)
      useLinearGradient / useRadialGradient / useConicGradient
      use*Gradient hooks       — string via useMemo; SSR-safe; no Vue dependency

Bundle size & peer dependencies

| Entry point | Peer deps | Notes | |---|---|---| | css-magic-gradient | vue ^3.0.0 (optional) | Core functions, presets, accessibility, CSS variable utils, canvas export, Vue hooks | | css-magic-gradient/vue | vue ^3.0.0 | Vue hooks only (subpath alias for the main entry) | | css-magic-gradient/react | react ^17.0.0 (optional) | React hooks only — no Vue dependency |

The package ships as ESM + CommonJS (dist/*.js). Vue and React are optional peer dependencies — the main bundle is fully usable without either. The only runtime dependency is color-value-tools (color math for harmony generators and palette functions).

// Core
import {
  createLinearGradient,
  createTetradicGradient,
  sunsetGradient,
  createAccessibleGradient,
  extractGradientVariables,
  gradientToDataURL,
} from 'css-magic-gradient'

// Vue hooks (subpath alias)
import { useTetradicGradient } from 'css-magic-gradient/vue'

// React hooks
import { useTintGradient } from 'css-magic-gradient/react'

License

MIT


Author

Danil Lisin Vladimirovich aka Macrulez

GitHub: macrulezru · Website: macrulez.ru/en

Bugs and questions — issues


💖 Support the project

Open source takes time and effort. If my work saves you time or brings value, consider supporting further development.

Thank you for being part of this journey. ❤️