Design

CSS GRADIENT

Create beautiful CSS gradients visually. Linear, radial, and conic types with presets.

deg
Color Stops
CSS Output
Presets
Developer Reference

Core Algorithm & Standalone Script

Standalone, zero-dependency JavaScript implementation powering this tool. Free to inspect, copy, and build upon.

let gradType = 'linear';
let stops = [
  { color: '#ff2200', pos: 0 },
  { color: '#0088ff', pos: 100 }
];

const presets = [
  [{ color:'#667eea',pos:0 },{ color:'#764ba2',pos:100 }],
  [{ color:'#f093fb',pos:0 },{ color:'#f5576c',pos:100 }],
  [{ color:'#4facfe',pos:0 },{ color:'#00f2fe',pos:100 }],
  [{ color:'#43e97b',pos:0 },{ color:'#38f9d7',pos:100 }],
  [{ color:'#fa709a',pos:0 },{ color:'#fee140',pos:100 }],
  [{ color:'#a18cd1',pos:0 },{ color:'#fbc2eb',pos:100 }],
  [{ color:'#fad0c4',pos:0 },{ color:'#ffd1ff',pos:100 }],
  [{ color:'#ff9a9e',pos:0 },{ color:'#fecfef',pos:100 }],
  [{ color:'#f6d365',pos:0 },{ color:'#fda085',pos:100 }],
  [{ color:'#0c3483',pos:0 },{ color:'#a2b6df',pos:50 },{ color:'#6b8cce',pos:100 }]
];

function setType(t) {
  gradType = t;
  document.querySelectorAll('.type-tab').forEach(b => b.classList.toggle('active', b.dataset.type === t));
  document.getElementById('angleRow').style.display = (t === 'linear' || t === 'conic') ? 'flex' : 'none';
  document.getElementById('positionRow').style.display = (t === 'radial' || t === 'conic') ? 'flex' : 'none';
  update();
}

function renderStops() {
  const list = document.getElementById('stopsList');
  list.innerHTML = stops.map((s, i) => `
    <div class="stop-row">
      <input type="color" class="stop-color" value="${s.color}" oninput="stops[${i}].color=this.value;update()" />
      <input type="range" class="stop-pos" min="0" max="100" value="${s.pos}" oninput="stops[${i}].pos=+this.value;update()" />
      <span class="text-small text-muted" style="width:30px">${s.pos}%</span>
      ${stops.length > 2 ? `<button class="stop-remove" onclick="removeStop(${i})">×</button>` : ''}
    </div>
  `).join('');
}

function addStop() {
  if (stops.length >= 8) return;
  const lastPos = stops[stops.length - 1].pos;
  const color = '#' + Math.floor(Math.random()*16777215).toString(16).padStart(6,'0');
  stops.push({ color, pos: Math.min(100, lastPos + 10) });
  renderStops(); update();
}

function removeStop(i) {
  if (stops.length <= 2) return;
  stops.splice(i, 1);
  renderStops(); update();
}

function getCSS() {
  const stopsStr = stops.map(s => `${s.color} ${s.pos}%`).join(', ');
  const angle = document.getElementById('angleSlider').value;
  const pos = document.getElementById('positionSelect').value;

  if (gradType === 'linear') return `linear-gradient(${angle}deg, ${stopsStr})`;
  if (gradType === 'radial') return `radial-gradient(circle at ${pos}, ${stopsStr})`;
  return `conic-gradient(from ${angle}deg at ${pos}, ${stopsStr})`;
}

function update() {
  const css = getCSS();
  document.getElementById('preview').style.background = css;
  document.getElementById('codeOutput').textContent = `background: ${css};`;
  document.getElementById('angleInput').value = document.getElementById('angleSlider').value;
  // Update position labels
  document.querySelectorAll('.stop-row').forEach((row, i) => {
    const span = row.querySelector('span');
    if (span) span.textContent = stops[i].pos + '%';
  });
}

function copyCSS() {
  navigator.clipboard.writeText(`background: ${getCSS()};`).catch(()=>{});
  showToast('CSS copied');
}

function randomGradient() {
  const n = 2 + Math.floor(Math.random() * 2);
  stops = [];
  for (let i = 0; i < n; i++) {
    stops.push({
      color: '#' + Math.floor(Math.random()*16777215).toString(16).padStart(6,'0'),
      pos: Math.round((i / (n - 1)) * 100)
    });
  }
  document.getElementById('angleSlider').value = Math.floor(Math.random() * 360);
  renderStops(); update();
}

function showToast(msg) {
  const t = document.getElementById('toast');
  t.textContent = msg; t.classList.add('show');
  setTimeout(() => t.classList.remove('show'), 2000);
}

// Presets
const presetsGrid = document.getElementById('presetsGrid');
presets.forEach(p => {
  const el = document.createElement('div');
  el.className = 'preset-swatch';
  const css = `linear-gradient(135deg, ${p.map(s=>`${s.color} ${s.pos}%`).join(', ')})`;
  el.style.background = css;
  el.onclick = () => {
    stops = p.map(s => ({ ...s }));
    gradType = 'linear';
    document.querySelectorAll('.type-tab').forEach(b => b.classList.toggle('active', b.dataset.type === 'linear'));
    document.getElementById('angleSlider').value = 135;
    document.getElementById('angleRow').style.display = 'flex';
    document.getElementById('positionRow').style.display = 'none';
    renderStops(); update();
  };
  presetsGrid.appendChild(el);
});

renderStops();
update();