4

Is it possible to use CSS Variables in SVG to manipulate values like radius or position in the "attribute styles" of an element?

For Example, in the below code, I have added a CSS color variable - --dark-text-clr and a radius variable --radius. When I use the color CSS variable in fill it renders fine - 1st circle, but using the radius variable doesn't render the element - 2nd circle.

:root{
--dark-text-clr: blue;
--radius: 12;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px" viewBox="0 0 300 100">
  <circle cx="9" cy="9" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=9 ></circle>
  <circle cx="36" cy="20" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r="var(--radius)" ></circle>
</svg>
Gangula
  • 5,193
  • 4
  • 30
  • 59

2 Answers2

5

Yes, but CSS must have units for non-zero values.

:root{
--dark-text-clr: blue;
--radius: 12px;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px" viewBox="0 0 300 100">
  <circle cx="9" cy="9" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=9 ></circle>
  <circle cx="36" cy="20" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r="var(--radius)" ></circle>
</svg>
Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • 1
    I don't see the second circle when I run this in my browser. Not sure if my browser doesn't support it - I'm using `Microsoft Edge Version 95.0.1020.30 (Official build) (64-bit)` – Gangula Oct 31 '21 at 21:09
  • I'm using Firefox and it certainly works there. – Robert Longson Oct 31 '21 at 22:06
  • Just checked in Firefox. Its working there. Do you happen to know why it doesn't work in Edge/Chrome? I couldn't find any resources online which mentions why edge/chrome doesn't support this. – Gangula Nov 01 '21 at 08:12
  • Chrome/Edge bugracker is [here](https://bugs.chromium.org/p/chromium/issues/list) if you want to look through it. If there's no bug for this already you can always add one. – Robert Longson Nov 01 '21 at 08:18
  • @RobertLongson Do you have source for the " CSS must have units" rule? – Corrl Nov 01 '21 at 11:26
  • 2
    https://www.w3.org/TR/css-values-4/#length-value "Lengths refer to distance measurements and are denoted by `` in the property definitions. A length is a **dimension**."; and https://www.w3.org/TR/css-values-4/#dimension "The general term dimension refers to a number with a unit attached to it". The only exception is the case of `0`, where units are optional. – Paul LeBeau Nov 01 '21 at 12:11
  • Added this as a bug in Chromium bugtracker: https://bugs.chromium.org/p/chromium/issues/detail?id=1265430 – Gangula Nov 01 '21 at 14:59
4

According to the MDN Docs "Starting with SVG2, r is a Geometry Property meaning this attribute can also be used as a CSS property for circles."

There are three ways to set the radius value

  • as attribute
<circle ... r=10>
  • via class and stylesheet
circle {
  r: 10px;
}

  • inline in 'style' attribute
  <circle... style="r: 10px;" ></circle>

The last way has the greates presedence. Take a look at this example where all circle elements have r set as attribute, which is overridden by the stylesheet (2nd circle), which is overridden again by the inline style attribute (3rd circle)
(These three ways don't have to be used together, but are only combined to demontrate which one has a higher presedence and overwrites the already set values)

:root {
  --dark-text-clr: purple;
  --radius: 20px;
}

.circle {
  r: 10px;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="300px" viewBox="0 0 300 300">
<circle cx="10" cy="10" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5></circle>
<circle cx="30" cy="30" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5 class="circle"></circle>
  <circle cx="60" cy="60" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5 class="circle" style="r: var(--radius);" ></circle>
</svg>

Setting r with the variable on the attribute seems to be working in firefox, but not in chrome/edge

<circle ... r="var(--radius);" ></circle>

so better set it on the style attribute

<circle ... style="r: var(--radius);" ></circle>
Corrl
  • 6,206
  • 1
  • 10
  • 36
  • Thank you @Corl. Although this is the answer that's supported in most browsers right now, [@Robert's answer](https://stackoverflow.com/a/69790400/6908282) is the ideal approach to do this and will most likely be fixed in all browsers eventually. – Gangula Nov 01 '21 at 11:10
  • @Gangula what's the argument that setting the variable inside the 'r=10' attribute is the "ideal approach"? Since it's supported in most browser, even if not working in Chrome? On which site can this information be looked up? – Corrl Nov 01 '21 at 11:17
  • 1
    What I meant by "ideal approach" was - having least maintenance. With this approach, we have 3 references - 1. Variable declaration(`--radius: 20px;`), 2. SVG value(`r=5`), 3. CSS Style(`r: 10px;`). And with [Robert's approach](https://stackoverflow.com/a/69790400/6908282), we don't have the 3rd reference Of CSS Style. If there are multiple SVG elements that we need to manage, I think having one less reference saves time. But, this is my opinion. Please do let me know if you think otherwise. – Gangula Nov 01 '21 at 11:31
  • 1
    @Gangula Thanks for explaining - having one less reference is defenitely an argument. But I'm not sure if there's a misunderstanding. There's no need for setting the r as attribute 'r=10' PLUS via the stylesheet 'r: 10px'. (Did this just for showing which one overwrites the others) In your case simply set the radius instead of 'r='var(--radius)' via 'style='r: var(--radius)' both directly inside the `` tag and you have 2 references but with a presumabely better browser support (at the moment) (Or is there a misunderstanding on my side..?) – Corrl Nov 01 '21 at 11:45
  • I agree that we can use `r` as placeholder inside SVG or completely remove it. But I think entirely omitting the radius `r` from the SVG element would be semantically incorrect. – Gangula Nov 01 '21 at 12:58
  • @Gangula that's a good question, if omitting the r value is no good practice and should be instead better kept plus additional styling via stylesheet or style attribute on top in case needed – Corrl Nov 01 '21 at 13:24
  • when is use `r` in CSS style, VS Code show a warning below the property. Is using `r` in CSS not recommended? – Gangula Nov 02 '21 at 20:36
  • 1
    The [MDN docs](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/r) say "Starting with SVG2, r is a Geometry Property meaning this attribute can also be used as a CSS property for circles." but I couldn't find any website displaying the current browser support for svg2 – Corrl Nov 02 '21 at 21:10
  • 1
    there's a question available in SO on [browser support for SVG2](https://stackoverflow.com/q/26088839/6908282). Looks like SVG2 is in [working draft](https://svgwg.org/svg2-draft) under W3C – Gangula Nov 03 '21 at 05:59