designdebt.club
Menu
Design Debt Club

Styling SVGs with CSS

When utilising SVGs in your HTML, you may find yourself inserting them using the img tag. This is nice and clean and keeps them formatted and styled in the same way as your other images…

However, this adds a limitation to your ability to dynamically style them.

Html:

<img
    ...other properties
    src = "tractor.svg"
/>

If you’re working in a Javascript framework (In my case, React), you might also choose to do it by parsing the file directly into a data string within the image tag. This can help you turn a multi-file project into a single output file, but it still runs into the same drawback as above.

React:

<img
    ...other properties
    src = {`data:image/svg+xml;utf8,${encodeURIComponent(tractor.svg)}`}
/>

The drawback

The problem with the above methods is that while you can use CSS to style the image tag as a whole (like with any other image), your CSS can’t reach inside your SVG and style it’s components.

This may be fine some of the time, but SVGs are standard XML markup and can support many styling properties as well as ids and classnames, all of which are inaccessible if embedded through an img tag.

The solution

To avoid this, you need to insert the SVG markup directly into the HTML.

Instead of this:

<div>
    <h1>heading</h1>
    <img src="shapes.svg"/>
</div>

You want something like this:

<div>
    <h1>heading</h1>
    <svg
        width="50"
        height="100"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        >
        <rect
            id="my-id"
            x="10"
            y="10"
            width="30"
            height="30"
            stroke="black"
            fill="transparent"
            stroke-width="5"
        />
        <circle
            class="my-class-name"
            cx="25"
            cy="75"
            r="20"
            stroke="red"
            fill="transparent"
            stroke-width="5"
        />
    </svg>
</div>

In React, this can be done using dangerouslySetInnerHtml or, you can use the npm package react-inlinesvg.

When embedded in this way, you can now use CSS or Javascript to style any of the objects within the SVG.

#my-id {
    fill: aqua;
    stroke: green;
}
.my-class-name {
    transform-box: fill-box;
    transform-origin: 50% 50%;
    rotate: 45deg;
}

That’s it!