Advertisement

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

image/svg+xml

“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

image/svg+xml

Conclusion

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

The end

Thanks for reading.

Discussion

If you found a mistake in this article or would like to contribute some content to it, please file an issue in this Git Repository

Disclaimer

The contents of this article are put together to the best of the authors' knowledge, but it cannot be guaranteed that it's always accurate in any environment. It is up to the reader to make sure that all information found in this article, does not do any damage to the reader's working environment or wherever this information is applied to. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, arising from, out of or in connection with this article. Please also note the information given on the Imprint' page.