CSS Gradient Generator: From Linear Interpolation to Conic Gradients Algorithm Implementation
CSS Gradient Generator: From Linear Interpolation to Conic Gradients Algorithm Implementation#
Author: JsonKit Team Date: 2026-05-06 14:41 Keywords: CSS gradient, gradient generator, linear gradient, radial gradient, conic gradient, color interpolation
What Are CSS Gradients?#
CSS gradients are native browser image types that don’t require external image resources. They create visual effects by smoothly transitioning between two or more colors. The three common gradient types are:
- Linear gradient: Transitions along a straight line
- Radial gradient: Radiates outward from a center point
- Conic gradient: Rotates around a center point
The gradient generator tool (https://jsokit.com/tools/css-gradient) helps developers visually configure these parameters.
Core Algorithm: Color Interpolation#
RGB Linear Interpolation#
The core of CSS gradients is the color interpolation algorithm. Browsers default to interpolating in RGB color space:
// RGB linear interpolation formula
function interpolateColor(color1, color2, ratio) {
const r = Math.round(color1.r + (color2.r - color1.r) * ratio)
const g = Math.round(color1.g + (color2.g - color1.g) * ratio)
const b = Math.round(color1.b + (color2.b - color1.b) * ratio)
return { r, g, b }
}
// Example: Middle color from red (#ff0000) to blue (#0000ff)
const red = { r: 255, g: 0, b: 0 }
const blue = { r: 0, g: 0, b: 255 }
const purple = interpolateColor(red, blue, 0.5) // { r: 127, g: 0, b: 127 }
The “Dirty Color” Problem in RGB Interpolation#
RGB linear interpolation produces unnatural grayish colors in the middle transition zone. For example, yellow to blue interpolation passes through gray instead of bright green. The solution is using HSL color space:
// RGB to HSL conversion
function rgbToHsl(r, g, b) {
r /= 255; g /= 255; b /= 255
const max = Math.max(r, g, b), min = Math.min(r, g, b)
let h, s, l = (max + min) / 2
if (max === min) {
h = s = 0
} else {
const d = max - min
s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
switch (max) {
case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break
case g: h = ((b - r) / d + 2) / 6; break
case b: h = ((r - g) / d + 4) / 6; break
}
}
return { h: h * 360, s: s * 100, l: l * 100 }
}
// Convert HSL back to RGB after interpolation
function hslToRgb(h, s, l) {
h /= 360; s /= 100; l /= 100
let r, g, b
if (s === 0) {
r = g = b = l
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1
if (t > 1) t -= 1
if (t < 1/6) return p + (q - p) * 6 * t
if (t < 1/2) return q
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6
return p
}
const q = l < 0.5 ? l * (1 + s) : l + s - l * s
const p = 2 * l - q
r = hue2rgb(p, q, h + 1/3)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1/3)
}
return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) }
}
CSS specifications allow specifying interpolation color space via color-interpolation property, but browser support is limited.
Three Gradient Types Implementation#
1. Linear Gradient#
Linear gradient is the most commonly used type, with parameters including angle and color stops:
/* Angle syntax */
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
/* Direction keywords */
background: linear-gradient(to right top, #667eea, #764ba2);
/* Multiple color stops */
background: linear-gradient(90deg, red, yellow 30%, green 70%, blue);
Angle Calculation Principle:
// Convert angle to direction vector
function angleToDirection(degrees) {
const radians = (degrees - 90) * Math.PI / 180 // CSS angle starts from top clockwise
return {
x: Math.cos(radians),
y: Math.sin(radians)
}
}
// Calculate pixel position color
function getPixelColor(gradientLine, position) {
// gradientLine is the length of gradient line
const ratio = position / gradientLine
return interpolateColorsAt(ratio)
}
2. Radial Gradient#
Radial gradient radiates outward from a center point, supporting circles and ellipses:
/* Circular radial gradient */
background: radial-gradient(circle, #667eea, #764ba2);
/* Ellipse */
background: radial-gradient(ellipse at top left, #667eea, #764ba2);
/* Specified radius */
background: radial-gradient(circle closest-side, #667eea, #764ba2);
background: radial-gradient(circle farthest-corner, #667eea, #764ba2);
Distance Calculation Algorithm:
// Calculate distance from point to center
function radialDistance(px, py, cx, cy) {
const dx = px - cx
const dy = py - cy
return Math.sqrt(dx * dx + dy * dy)
}
// closest-side: distance to nearest edge
function closestSideDistance(cx, cy, width, height) {
return Math.min(cx, width - cx, cy, height - cy)
}
// farthest-corner: distance to farthest corner
function farthestCornerDistance(cx, cy, width, height) {
return Math.max(
Math.sqrt(cx * cx + cy * cy),
Math.sqrt((width - cx) ** 2 + cy ** 2),
Math.sqrt(cx ** 2 + (height - cy) ** 2),
Math.sqrt((width - cx) ** 2 + (height - cy) ** 2)
)
}
3. Conic Gradient#
Conic gradient rotates around a center point, commonly used for pie charts and color wheels:
/* Basic conic gradient */
background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
/* Specify starting angle */
background: conic-gradient(from 45deg, #667eea, #764ba2);
/* Specify center point */
background: conic-gradient(from 0deg at 25% 25%, red, blue);
Angle Mapping Algorithm:
// Calculate pixel point angle
function getAngle(px, py, cx, cy) {
const dx = px - cx
const dy = py - cy
let angle = Math.atan2(dy, dx) * 180 / Math.PI
angle = (angle + 90 + 360) % 360 // CSS spec starts from top clockwise
return angle
}
// Get color based on angle
function getConicColor(angle, startAngle, colors) {
const normalizedAngle = (angle - startAngle + 360) % 360
const ratio = normalizedAngle / 360
return interpolateColorsAt(colors, ratio)
}
Color Stop Parsing and Validation#
Gradient generators need to parse user-input color values:
// Color format validation
function isValidColor(color) {
const hexPattern = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/
const rgbPattern = /^rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/
const rgbaPattern = /^rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)$/
const hslPattern = /^hsl\(\s*\d+\s*,\s*\d+%?\s*,\s*\d+%?\s*\)$/
const namedColors = ['red', 'blue', 'green', 'white', 'black', /* ... */]
return hexPattern.test(color) ||
rgbPattern.test(color) ||
rgbaPattern.test(color) ||
hslPattern.test(color) ||
namedColors.includes(color.toLowerCase())
}
// HEX to RGB conversion
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null
}
Performance Optimization Tips#
1. Avoid Repaints#
Gradient background changes trigger repaints, so use carefully in animation scenarios:
/* Recommended: Use transform and opacity animations */
.gradient-box {
background: linear-gradient(135deg, #667eea, #764ba2);
transform: scale(1);
transition: transform 0.3s ease;
}
.gradient-box:hover {
transform: scale(1.05); /* No repaint */
}
/* Avoid: Changing background color */
.bad-practice {
background: linear-gradient(135deg, #667eea, #764ba2);
transition: background 0.3s; /* Triggers repaint */
}
.bad-practice:hover {
background: linear-gradient(135deg, #764ba2, #667eea);
}
2. Use CSS Variables#
:root {
--gradient-start: #667eea;
--gradient-end: #764ba2;
}
.dynamic-gradient {
background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
}
/* JavaScript dynamic modification */
document.documentElement.style.setProperty('--gradient-start', '#ff6b6b')
3. Gradient Preloading#
For gradients that need dynamic switching, pre-generate multiple classes:
.gradient-1 { background: linear-gradient(135deg, #667eea, #764ba2); }
.gradient-2 { background: linear-gradient(135deg, #ff6b6b, #feca57); }
.gradient-3 { background: linear-gradient(135deg, #48dbfb, #0abde3); }
/* Switch class names instead of inline styles */
element.className = 'gradient-2'
Real-world Application Scenarios#
1. Gradient Buttons#
.gradient-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 12px 24px;
border-radius: 8px;
color: white;
font-weight: 600;
transition: transform 0.2s, box-shadow 0.2s;
}
.gradient-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
2. Gradient Text#
.gradient-text {
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-size: 3rem;
font-weight: bold;
}
3. Gradient Borders#
.gradient-border {
position: relative;
background: white;
border-radius: 8px;
}
.gradient-border::before {
content: '';
position: absolute;
inset: -2px;
background: linear-gradient(135deg, #667eea, #764ba2);
border-radius: inherit;
z-index: -1;
}
Summary#
The algorithms behind CSS gradient generators involve multiple technical points including color space conversion, interpolation calculation, and geometric distance. Understanding these principles helps with:
- Performance optimization: Knowing which operations trigger repaints and choosing appropriate animation strategies
- Debugging issues: Knowing how to switch to HSL space when RGB interpolation produces dirty colors
- Feature extension: Implementing advanced features like gradient preview, color extraction, and reverse gradients
Using online tools (https://jsokit.com/tools/css-gradient) can quickly generate and preview CSS gradient code, improving development efficiency.
Related Tools#
- CSS Animation Generator - Create complex CSS animation sequences
- Color Shades Generator - Generate light and dark variations of color schemes
- Button Generator - Design buttons with gradient effects