Safari-compatible SVG with dark mode support

SVG images can support light and dark mode in CSS. But Safari browser has a problem, that requires a bit of a trick.

Visitors to our websites can indicate that they’d prefer to view things in light mode (generally the default) or dark mode. That’s usually done through the operating system of their computers, phones, or tablets. Using CSS, we can honour their wishes and set appropriate colours by using a media query for prefers-color-scheme. Like this:

<style>
    .letter {
        fill:#231f20;
    }
    @media (prefers-color-scheme: dark) {
        .letter {
            fill:#ffffff
        }
    }
</style>

This works even inside an SVG image — generally! If we embed the whole SVG image into the HTML of a page, it works pretty reliably. If we load the image from an image tag instead, however, the Safari browser just doesn’t want to know about it.

Why not just embed all SVG images? Well, they can sometimes get pretty big, and they can vary depending on content conditions, so it’s often more convenient to load them as external images.

So, to the trick. The image tag “img” isn’t the only way to pull an external image onto a page; the object tag can do that too! The trick is to tell the object tag that its content is an image by supplying its MIME type, and setting a role to tell the browser that it’s an image. Also a good idea to get it to ignore pointer events so that any link wrapped around it will work. As seen below!

<object type="image/svg+xml"
    title="Example SVG image with dark mode support"
    data="https://example.com/images/light-and-dark.svg"
    role="img"
    style="pointer-events:none"></object>

And job is done, even in the new IE6 (Safari).