Embedded CSS in SVG can break your design

May 8, 2015·
Dennis
Dennis
· 3 min read
Image credit: DALL-E

You probably heard about embedding CSS into SVG, but have you ever tried that yourself? Recently I faced a rather strange design issue.

Issue

Some days ago I started to integrate mermaid – a JavaScript framework for diagrams and graphs – into middleman-presentation – a presentation builder framework based on reveal.js.

I created a new plugin for middleman-presentation and everything looked fine – at first. But every time I loaded the presentation, all headlines – h1, h2 etc. – lost their styles. After some debugging I found out, that mermaid captures the CSS from linked stylesheets and adds them as inline CSS to the SVG diagram via JavaScript. The resulting SVG image looks like the SVG code you find below.

<svg>
<style type="text/css">
  h1 { font-size: 1rem; }
</style>
[...]
</svg>

The reason for the behaviour of mermaid is this: It makes it easier to give away generated diagrams, because all relevant styles are part of the SVG. Unfortunately it breaks my presentation design: The reset styles of reveal.js are applied again; and this deletes all other styles.

Setup

If you want to get your hands dirty and reproduce the problem yourself, please save the HTML files you find below to your hard disk and open them with a browser. I tested both files with Firefox 37.0.1, Chromium 41, Internet Explorer 11 and the result was always the same.

Result

The first one will show “This is a H1 headline” with a font size of “5rem”; the second one with “1rem”. There’s only one difference between the files: The later makes use of some embedded stylesheet within the SVG image.

“h1” with font-size 5rem

Input

<html>
  <head>
    <style type="text/css">
      h1 {
        font-size: 5rem;
      }
    </style>
  </head>
  <body>
    <h1>This is a H1 headline</h1>
    <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="56.766983mm" height="34.995556mm" viewBox="0 0 201.14285 124" id="svg2" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="drawing.svg">
      <defs id="defs4" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.35" inkscape:cx="-180.14285" inkscape:cy="-78.000013" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="796" inkscape:window-height="853" inkscape:window-x="800" inkscape:window-y="24" inkscape:window-maximized="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-226.57143,-336.07648)"> <ellipse style="fill:#ececec;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" id="path3336" cx="327.14285" cy="398.07648" rx="98.571426" ry="60" /> </g>
    </svg>
  </body>
</html>

Output

This is a H1 headline

“h1” with font-size 1rem

Input

<html>
  <head>
    <style type="text/css">
      h1 {
        font-size: 5rem;
      }
    </style>
  </head>
  <body>
    <h1>This is a H1 headline</h1>
    <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="56.766983mm" height="34.995556mm" viewBox="0 0 201.14285 124" id="svg2" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="drawing.svg">
      <style type="text/css">
        h1 { font-size: 1rem; }
      </style>
      <defs id="defs4" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.35" inkscape:cx="-180.14285" inkscape:cy="-78.000013" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="796" inkscape:window-height="853" inkscape:window-x="800" inkscape:window-y="24" inkscape:window-maximized="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-226.57143,-336.07648)"> <ellipse style="fill:#ececec;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" id="path3336" cx="327.14285" cy="398.07648" rx="98.571426" ry="60" /> </g>
    </svg>
  </body>
</html>

Output

This is a H1 headline

Conclusion

Be careful, if you’re going to embed CSS into an SVG image.

The end

Thanks for reading.

Dennis
Authors
Technology Enthusiast
My interests include IT automation, continous delivery, data visualization, software development and photography