Tutorials

Figma SVG Gradient Fix: Keep Gradients, Masks, and Shadows Working

SVG Genie TeamSVG Design Expert & Technical Writer at SVG Genie
||10 min read

Reviewed by SVG Genie Editorial Team

Your Figma export looks perfect on the canvas. Then the SVG lands in a browser, React component, CMS, or CSS background and the gradient disappears. Sometimes it turns black. Sometimes only the mask vanishes. Sometimes one logo looks right until another SVG appears on the same page.

The fast rule:

If a Figma SVG gradient breaks, do not start by redrawing the artwork. First check the defs block, every url(#...) reference, duplicate IDs, optimizer settings, and the way the SVG is embedded. Most gradient failures are reference failures, not design failures.

If the whole export is blank or clipped, start with the broader Figma SVG export troubleshooting guide. If the file renders correctly but the markup is messy, use the Figma SVG clean code guide after this gradient check.

Figma gradient SVG repair workflow showing a design frame, SVG defs block, and browser preview

Why do Figma SVG gradients break after export?

Figma SVG gradients break when the visible shape and its paint definition stop matching. In SVG, a gradient is usually stored in <defs> and applied by reference, such as fill="url(#paint0_linear)". If the referenced definition is missing, renamed, duplicated, sanitized, or optimized incorrectly, the shape can render black, transparent, or flat.

An SVG gradient is a reusable paint definition inside SVG markup. The shape does not contain every color stop directly. It points to a linearGradient or radialGradient by ID, which means the ID is part of the artwork.

This is the simple pattern:

<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
  <path d="M20 20h80v80H20z" fill="url(#paint0_linear)" />
  <defs>
    <linearGradient id="paint0_linear" x1="20" y1="20" x2="100" y2="100">
      <stop offset="0%" stop-color="#7c3aed" />
      <stop offset="100%" stop-color="#06b6d4" />
    </linearGradient>
  </defs>
</svg>

The visible path depends on paint0_linear. Delete or rename that ID and the path still exists, but the browser no longer knows which paint to use.

Useful references when checking standard behavior:

What is the fastest way to diagnose a broken SVG gradient?

The fastest diagnosis is to separate export, markup, and embed problems. Open the exported SVG directly in a browser first. If the gradient is already broken there, inspect the Figma export and SVG markup. If it works as a file but breaks inside your app, inspect IDs, CSS, React conversion, sanitizers, and optimization.

Use this decision table:

SymptomMost Likely CauseFirst Fix
Gradient missing in the standalone SVG fileMissing or invalid defsRe-export from Figma and preserve gradient definitions
Gradient works alone but fails in ReactDuplicate IDs across inline SVGsPrefix IDs per component and update url(#...) references
Gradient turns black after minificationOptimizer removed or renamed defsUse conservative optimization and keep referenced IDs
Gradient disappears in CMS or upload previewSanitizer strips defs, style, or referencesUse a safer embed method or simplify the effect
Masked gradient vanishesMask, clip path, or filter reference brokeCheck every mask, clip-path, filter, and fill URL
Gradient looks wrong in CSS backgroundEncoding or external styling mismatchUse a normal .svg file or encode carefully

The quick search inside the SVG is:

url(#
linearGradient
radialGradient
mask
clipPath
filter
id=

If url(#paint0_linear) exists but id="paint0_linear" does not, you found the bug. If the ID exists more than once on the same page, you found the other common bug.

How do I fix Figma SVG gradients that turn black?

Fix a black Figma SVG gradient by restoring the missing definition, making the referenced ID unique, and confirming every fill, stroke, mask, clip-path, and filter reference points to a real ID. A black fallback is often the browser telling you it could not resolve the original paint.

Start with the broken reference:

<path d="..." fill="url(#paint0_linear)" />

Then confirm the matching definition exists:

<linearGradient id="paint0_linear" x1="0" y1="0" x2="120" y2="120">
  <stop offset="0%" stop-color="#8b5cf6" />
  <stop offset="100%" stop-color="#14b8a6" />
</linearGradient>

If you inline several Figma SVGs into the same HTML or React page, prefix IDs before shipping:

<!-- Before -->
<path fill="url(#paint0_linear)" />
<linearGradient id="paint0_linear">...</linearGradient>

<!-- After -->
<path fill="url(#pricingCard_paint0_linear)" />
<linearGradient id="pricingCard_paint0_linear">...</linearGradient>

Do the same for:

  • linearGradient
  • radialGradient
  • mask
  • clipPath
  • filter
  • pattern
  • marker

For React components, use SVG to React after the asset renders correctly, then inspect IDs manually if the component will appear more than once on a page.

Should I keep or flatten Figma gradients in SVG?

Keep normal Figma linear and radial gradients when the SVG needs to stay vector, editable, themeable, and sharp at every size. Flatten effects only when the visual depends on raster-like blur, complex shadows, blend modes, or a CMS/email/app environment that strips the SVG definitions required for reliable rendering.

Use this choice:

Figma EffectKeep as SVG?Flatten or Rebuild?Why
Simple linear gradient logoYesNoCompact, scalable, and editable
Simple radial gradient iconYesNoStandard SVG support is good
Gradient plus maskUsuallyOnly if the target strips masksThe references must stay intact
Heavy blur or drop shadowMaybeOftenSVG filters can be large and inconsistent
Blend modes and layered effectsTest firstOftenFigma's visual model may not map cleanly
Photo-like gradient meshNoYesBetter as PNG/WebP or rebuilt as simpler vector art

For brand logos and UI icons, clean vector gradients are usually worth preserving. For complex marketing illustrations, a raster image can be the better production asset if fidelity matters more than editability.

If the source was never a clean vector, use Image to SVG or PNG to SVG to rebuild the asset instead of trying to rescue a noisy Figma export.

How do I stop optimizers from breaking Figma SVG gradients?

Stop optimizers from breaking gradients by optimizing only after the file renders correctly, using conservative settings, preserving the viewBox, and keeping IDs that are referenced by url(#...). Minification should remove noise; it should not make creative decisions about paint, masks, filters, or accessibility labels.

Before running an optimizer, ask:

  • Does the SVG render correctly as a standalone file?
  • Does every url(#...) reference have a matching id?
  • Are there duplicate IDs after combining assets?
  • Are title and desc needed for accessibility?
  • Is the gradient part of the brand mark or only decorative?
  • Will the final asset be inline SVG, an <img>, a CSS background, or a React component?

Then optimize in this order:

  1. Save the original export.
  2. Remove obvious hidden layers or accidental backgrounds in Figma.
  3. Export the smallest correct selection.
  4. Open the raw SVG directly in a browser.
  5. Run SVG Optimizer or SVG Minify with conservative settings.
  6. Compare raw and optimized files side by side.
  7. Test in the real embed location.

Avoid cleanup that blindly removes unused IDs if the optimizer cannot understand your final page. An ID may look unused inside one isolated file but matter when CSS, React props, animation, or a mask reference touches it.

Why do gradients break after converting Figma SVG to React?

Gradients break in React when raw SVG attributes are converted incompletely, IDs collide across component instances, or defs are separated from the shape that references them. React itself can render SVG gradients, but JSX attribute names and component reuse make hidden SVG reference bugs more obvious.

Raw export:

<svg viewBox="0 0 64 64">
  <path fill="url(#paint0_linear)" d="M8 8h48v48H8z" />
  <defs>
    <linearGradient id="paint0_linear" x1="8" y1="8" x2="56" y2="56">
      <stop stop-color="#7c3aed" />
      <stop offset="1" stop-color="#06b6d4" />
    </linearGradient>
  </defs>
</svg>

Safer React component:

export function GradientMark({ title = "Gradient mark" }: { title?: string }) {
  const gradientId = "gradientMark_paint0_linear";

  return (
    <svg viewBox="0 0 64 64" role="img" aria-label={title}>
      <path fill={`url(#${gradientId})`} d="M8 8h48v48H8z" />
      <defs>
        <linearGradient id={gradientId} x1="8" y1="8" x2="56" y2="56">
          <stop stopColor="#7c3aed" />
          <stop offset="1" stopColor="#06b6d4" />
        </linearGradient>
      </defs>
    </svg>
  );
}

What changed:

  • The ID became unique to the component.
  • stop-color became stopColor.
  • The viewBox stayed.
  • The defs stayed inside the same SVG.
  • The component has a meaningful accessible label.

If the same component appears many times on one page and the ID is hardcoded, modern browsers usually resolve IDs inside the current SVG, but collisions still happen in sprites, portals, CMS transforms, testing snapshots, and mixed inline markup. Unique IDs are cheap insurance.

Can I use gradient SVGs in CSS backgrounds and data URIs?

Yes, gradient SVGs can work as CSS backgrounds and data URIs, but they are harder to debug because the SVG markup is hidden inside a URL string. Use a normal .svg file for reusable gradient logos, meaningful illustrations, and anything with masks or filters. Use data URIs only for tiny decorative assets.

The biggest data URI mistake is leaving # unescaped:

/* Broken risk: # starts a URL fragment */
background-image: url("data:image/svg+xml,<svg><path fill='#7c3aed'/></svg>");

/* Safer: # becomes %23 */
background-image: url("data:image/svg+xml,%3Csvg%3E%3Cpath fill='%237c3aed'/%3E%3C/svg%3E");

If your Figma SVG has multiple gradients, masks, and filters, do not bury it inside CSS unless there is a strong reason. Keep it as /logo.svg, load it with <img>, or inline it as SVG when CSS control is required.

For the encoding details, use the SVG data URI encoder guide. For placement choices, use the SVG as image guide.

What is the safest Figma SVG gradient checklist?

The safest checklist is to preserve references first, optimize second, and test in the final rendering environment last. A gradient that works in Figma but fails on a website is usually not mysterious. Something in the export, cleanup, conversion, or embed pipeline changed how IDs and definitions resolve.

Use this before shipping:

  • Export the smallest correct Figma frame or selection.
  • Open the raw SVG directly in a browser.
  • Confirm the root <svg> has xmlns and viewBox.
  • Search for url(#.
  • Confirm every referenced ID exists exactly where expected.
  • Prefix duplicate gradient, mask, clip path, and filter IDs.
  • Keep defs until the asset renders correctly without them.
  • Convert JSX attributes such as stop-color to stopColor.
  • Avoid aggressive minification before visual testing.
  • Test as the final embed type: file, inline SVG, React component, CMS upload, or CSS background.

If the file is visually right but too heavy, clean it with SVG Optimizer. If the gradient needs manual repair, inspect it in SVG Editor. If the file is valid but still does not render in the browser, the SVG not showing in browser guide covers MIME type, paths, CSS, dimensions, and embed issues.

FAQ

Why does a Figma SVG gradient disappear?

A Figma SVG gradient usually disappears because the shape still points to url(#gradientId), but the matching linearGradient or radialGradient inside defs was deleted, renamed, duplicated, optimized away, or blocked by the final embed context.

Why does my Figma SVG gradient turn black?

A gradient can turn black when the browser cannot resolve its referenced ID, when duplicate IDs collide with another inline SVG, or when an optimizer rewrites defs without updating every fill or stroke reference. Prefix IDs and preserve referenced definitions.

Should I flatten Figma gradients before SVG export?

Flatten only when the effect is too complex for reliable SVG rendering or when exact editability no longer matters. Keep normal linear and radial gradients as SVG definitions when the asset should stay scalable, editable, and small.

How do I fix duplicate gradient IDs in React?

Prefix each SVG's gradient, mask, clip path, and filter IDs, then update every url(#...) reference to the new names. This prevents one inline component from stealing another component's paint or clip definition.

Can SVG Genie help fix Figma gradient SVGs?

Yes. Use SVG Validator to inspect broken references, SVG Editor to preview visual changes, SVG Optimizer with conservative settings after the image renders correctly, and SVG to React when the final asset is an inline component.

Next step

Open the broken Figma SVG in SVG Validator, search for url(#, and confirm every referenced gradient, mask, clip path, and filter still exists. Then preview the repaired file in SVG Editor before minifying or converting it to React.

Create your own SVG graphics with AI

Describe what you need, get a production-ready vector in seconds. No design skills required.

Try SVG Genie Freearrow_forward

About This Article

This article was written by SVG Genie Team based on hands-on testing with SVG Genie's tools and years of experience in vector design and web graphics. All recommendations reflect real-world usage and are reviewed by the SVG Genie editorial team for accuracy.

About the Author

SVG Genie Team

SVG Design Expert & Technical Writer at SVG Genie

SVG Genie Team is a vector design specialist and technical writer at SVG Genie with years of hands-on experience in SVG tooling, AI-assisted design workflows, and web graphics optimization. Their work focuses on making professional vector design accessible to everyone.

More articles by SVG Genie Teamarrow_forward

Ready to Create Your Own Vectors?

Start designing with AI-powered precision today.

Get Started Freearrow_forward