3

I am new svg learner and try to animate svg file with external style sheet but fail fail to style my object 'Cube'.

[index.html file]

      <head>
        <link rel="stylesheet" type="text/css" href="cube.css">
      </head>
      <body>
        <img src="cube-motion.svg" height="350px" />
        <div class="logo">
          <h1>SVG Cube Animation</h>
        </div>

[cube-motion.svg file]

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="cube.css" ?>

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">

<g>
    <polygon id="l1" class="st0" points="105.3,92.7 86.3,103.3 67.3,92.9 67.1,71.9 86,61.2 105.1,71.6   "/>
    <polyline id="l2" class="st1" points="67.1,71.9 86.2,82.5 86.3,103.3 67.1,93.1 66.9,71.9    "/>

    <animateTransform
        attributeName="transform"
        type="translate"
        from="0 0"
        to="0 75"
        begin="0s"
        dur="3s"
        repeatCount="indefinite"
        />
</g>

</svg>

[external stylesheet file cube.css]

 .st0 {
        fill:#FF00FF;
        stroke:#000000;
        stroke-miterlimit:10;
    }

.st1 {
        fill:#23D83C;
        stroke:#000000;
        stroke-miterlimit:10;
    }

.logo {
    position: absolute;
    left: 400;
    top: 150;
  }
2

1 Answer 1

7

You are on the right track with the inclusion of the external stylesheet inside the SVG:

<?xml-stylesheet type="text/css" href="cube.css" ?>

The reason it doesn't work is because the SVG is loaded in the HTML as an <img> which - rightfully - does not allow additional external assets to be processed.

If you're adamant on having the CSS from an external file, you have two options, either embed the SVG inside the html or use <object data=file.svg type=image/xml+svg></object>.

Depending on your use case, you basically have three ways to use CSS for styling:

<img src="my.svg">

Images are not interactive and are not allowed to load any other assets within themselves. Simple presentation of the referenced image file only. It does allow to use CSS, but only from a <style>-element inside the SVG.

<object data="my.svg" type="image/svg+xml"></object>

Objects can do more than images, such as loading additional assets and even include isolated (within the loaded SVG) interactions (e.g. the CSS :hover-pseudoclass) Loading an external CSS file is done as you have it in the example code, the <?xml-stylesheet...?>-instruction goes before the <svg>-tag

<svg...>...</svg>

Fully embedded in the HTML document, this is allows for full integration within the page (this may have benefits on the interaction side and downsides on the CSS side, as you'll then have to take style isolation into consideration), but also the least re-usable as you'd basically have to repeat the entire SVG, which doesn't matter if used once on a page. Note that in order to embed the SVG inside the HTML document, you cannot put any of the SVG doctype and/or xml declarations in the HTML (<?xml...?>, <!DOCTYPE svg...> and <?xml-stylesheet...?>). With embedded SVG, you can simply import (or inline) the style using the usual HTML <link> or <style> nodes, where the <style> element may also still be inside the <svg>-element.

Here's a quick sample of the difference between <img> and <object>

5
  • The type attribute of SVGStyleElement is not mandatory, it will fallback to 'text/css' if unset. HTML5 doesn't know namespace attributes, so you don't need xmlns when inlined. Standalone svg loaded in a framed element (<embed>, <iframe> <object>) are as powerful as inline ones, they can also run js, with the added value that they won't pollute your main doc (e.g when inlined, stylesheets apply on the whole doc, and you must ensure ids are all unique accross the whole doc).
    – Kaiido
    Commented May 11, 2018 at 6:39
  • @Kaiido Updated the answer, removing both the mention of the type being mandatory and the xmlns on the inline <svg..> sample. Thanks for pointing it out! Clarified the portion about why I consider inline svg the most powerful option. Commented May 11, 2018 at 6:57
  • I still disagree on "by far the most powerful one": if served from the same domain you can just access it from the main doc's js almost as easily as if it were in the main doc, but that becomes opinions and the main issue being the limitations that come with <img>, you still got my upvote.
    – Kaiido
    Commented May 11, 2018 at 7:08
  • I see your point, it is opinionated, so removed that from the answer. Commented May 11, 2018 at 7:23
  • Thanks @Rogier, I replaced img tag to object tag as your suggest, problem solved quickly and styles can apply to my objects. Really appreciated.
    – Thein Htut
    Commented May 11, 2018 at 14:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.