SVG Fill Attribute vs CSS: Which Takes Priority?

When styling Scalable Vector Graphics (SVG), conflicts often arise when a fill is defined as an SVG attribute directly on an element while also being styled by a CSS rule. In almost all circumstances, CSS rules take precedence over native SVG presentation attributes due to the way the SVG and CSS specifications handle cascade specificity. Understanding this hierarchy is essential for managing dynamic styling, themes, and interactive vector graphics on the web.

The Specificity Hierarchy

SVG attributes such as fill, stroke, and opacity are categorized as presentation attributes. The SVG specification dictates that presentation attributes are treated as low-level author style rules. As a result, CSS rules applied via stylesheets, internal <style> tags, or inline style attributes will consistently override native SVG presentation attributes.

The order of priority, from lowest to highest precedence, is as follows:

  1. SVG Presentation Attributes: An attribute written directly in XML (for example, <circle fill="red" />) has the lowest priority. It effectively has a specificity of zero and functions as a default fallback.
  2. External or Embedded CSS Rules: Standard CSS selectors targeting the SVG element (such as circle { fill: blue; } or .my-circle { fill: blue; }) will immediately override the SVG attribute. Even a low-specificity type selector (svg path) supersedes a presentation attribute.
  3. Inline CSS Styles: A CSS property defined within an inline style attribute (for example, <circle style="fill: green;" fill="red" />) carries standard inline specificity, overriding both external CSS and SVG presentation attributes.
  4. CSS with !important: Any CSS declaration marked with !important takes precedence over all other declarations, regardless of selector specificity or attribute placement.

Practical Example

Consider the following markup and stylesheet:

<svg viewBox="0 0 100 100">
  <circle class="icon" fill="red" cx="50" cy="50" r="40" />
</svg>
.icon {
  fill: blue;
}

In this scenario, the rendered circle will be blue. The .icon CSS class rule overrides the fill="red" presentation attribute because the CSS cascade treats the XML attribute as the baseline value.

If inline CSS is introduced:

<circle class="icon" fill="red" style="fill: green;" cx="50" cy="50" r="40" />

The rendered circle will be green, as inline CSS takes precedence over the external .icon class and the native fill="red" attribute.

Key Takeaway

To ensure reliable styling and avoid unexpected visual bugs: * Use native SVG fill attributes when you need default fallback colors that external CSS can easily override. * Use CSS classes or custom properties when building responsive or themeable SVGs, as CSS consistently commands higher priority over XML presentation attributes.