Search code examples
csssvgcss-variables

SVG radius or position with CSS variables


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>


Solution

  • 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>