Un-Encoded SVG Backgrounds in CSS (Also, Writing CSS in CSS lolz)

I found this little aside in a Charlotte Dann article interesting:

Historically you’d have to URL-encode the SVG but I found that in all modern browsers encoding is unnecessary as long as it’s free of #s (HSL for the win!). Encode your files with this tool for extra safety.

So you can put the SVG syntax like directly into CSS as a data URL:

.cool-circle {
  height: 100px;
  width: 100px;

  background: url('data:image/svg+xml,<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="m49.941 10.035c52.539 0 52.539 79.93 0 79.93-52.539 0-52.539-79.93 0-79.93z" /></svg>');
}Code language: CSS (css)

That’s cool, angle brackets and all!

Did you know use can use backslashes (\) in a CSS string to break lines visually? Let’s use that to clean up a little:

.circle {
  height: 100px;
  width: 100px;

  background: url('data:image/svg+xml,\
    <svg\
      width="100" height="100"\
      viewBox="0 0 100 100"\
      xmlns="http://www.w3.org/2000/svg">\
        <path\
          fill="orange"\
          d="m49.941 10.035c52.539 0 52.539 79.93 0 79.93-52.539 0-52.539-79.93 0-79.93z" />\
    </svg>');
}Code language: CSS (css)

See the fill="orange" there? What Charlotte is saying is that like #f06d06 would totally break this. And indeed it does. Use a %23 instead for the # and you get %23f06d06 and that’ll work. But even better, use a color format that doesn’t need the octothorpe. Say HSL:

        <path\
          fill="hsl(322.64 100% 50%)"\Code language: HTML, XML (xml)

or even better, OKLCH.

This got me thinking though… The <svg> syntax allows for a <style> tag, meaning… we can put CSS in our SVG in our CSS, which is just weird.

If the CSS is on the page in a <style> tag of its own, the closing </style> in the SVG will break it though, so it is safest to escape just those tags I think. Here’s that weirdness:

.leaf {
  height: 100px;
  width: 100px;

  background-image: url("data:image/svg+xml,\
    <svg width='100' height='100'\
      viewBox='0 0 100 100'\
      xmlns='http://www.w3.org/2000/svg'>\
    %3Cstyle%3E\
      :root { --fill: hsl(33, 93%, 56%); }\
    %3C/style%3E\
    <path\
      fill='var(--fill)'\
      d='m66.086 38.801c-20.461 17.012-38.746 33.113-43.863 60.52 19.883-13.727 46.191-16.98 60.129-33.574 14.383-17.121 11.832-40.801 12.617-64.77-16.738 7.8633-33.316 12.223-50.281 16.078-32.465 7.3789-46.199 42.324-29.734 74.801 18.242-32.629 31.477-46.832 51.133-53.055z'/>\
    </svg>");
}
Code language: CSS (css)

I think OKLCH is the most baller new color format though, so let’s go full weird and make that work with a proper fallback:

.leaf {
  height: 100px;
  width: 100px;

  background-image: url("data:image/svg+xml,\
    <svg width='100' height='100'\
      viewBox='0 0 100 100'\
      xmlns='http://www.w3.org/2000/svg'>\
    %3Cstyle%3E\
      :root { \
        --fill: hsl(133.31 100% 49%)\
      }\
      @media (color-gamut: p3) {\
        :root {\
          --fill: oklch(85.88% 0.37 144);\
        }\
      }\
    %3C/style%3E\
    <path\
      style='fill: var(--fill);'\
      d='m66.086 38.801c-20.461 17.012-38.746 33.113-43.863 60.52 19.883-13.727 46.191-16.98 60.129-33.574 14.383-17.121 11.832-40.801 12.617-64.77-16.738 7.8633-33.316 12.223-50.281 16.078-32.465 7.3789-46.199 42.324-29.734 74.801 18.242-32.629 31.477-46.832 51.133-53.055z'/>\
    </svg>");
}
Code language: CSS (css)
Screenshot of CodePen showing the code above rendering a green leaf in SVG.

Thoughts? Email me or comment below. Also CodePen PRO is quite a deal. 🙏

4 responses to “Un-Encoded SVG Backgrounds in CSS (Also, Writing CSS in CSS lolz)”

  1. Harmon says:

    What I like even more is that there now is support for link-tags for favicons that I also use this” encoding lite” for!

  2. Brad Kemper says:

    I’m wondering why you needed to encode the angle brackets of the tags. Are they different from the other tags of the SVG somehow?

    • Chris Coyier says:

      I encoded those because it’s safer when the CSS I’m showing there was put into an HTML document within a <style> tag of its own. Otherwise the closing </style> tag within the SVG (even though it is within a string) will close the first style tag and chaos ensues.

  3. Brad Kemper says:

    That was supposed be “angle brackets of the ‘style’ tags”

Leave a Reply

Your email address will not be published. Required fields are marked *