Close up of a white man's hand, drawing a picture on an iPad with an Apple Pencil.

Working with SVGs (Scalable Vector Graphics) come with their own “gotchas” and nuances. This is a common issue, and it mainly boils down to how different browsers handle styling in SVGs.

The prefers-color-scheme media query enables an SVG switch between light and dark mode depending on the user’s settings. Dark mode is an accessibility feature that has gone mainstream. Safari doesn’t fully support styles inside external SVGs, there’s currently a webkit bug report for this issue.

Take this example pseudo code, you might expect the browser to respect the media query but you’d be wrong. This approach has the benefit of keeping all the image styles contained in the SVG.

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
  <defs>
    <style type="text/css">
      :root {
        --color: red;
        color-scheme: light dark;
      }

      @media (prefers-color-scheme: dark) {
        :root {
          --color: green;
        }
      }
      </style>
  </defs>
  <rect fill="var(--color)" width="100" height="100" />
</svg>

The simplest solution is to swap the images depending on the colour scheme. It’s not the most elegant fix, it means duplicate files, but it ensures your images look right across all browsers, including iOS.

In Svelte this code looks something like this:

<MediaQuery query="(prefers-color-scheme: dark)" let:matches>
	{#if matches}
	<img class="image--svg" src="{image--dark}" alt="image" />
	{:else}
	<img class="image--svg" src="{image}" alt="image" />
	{/if}
</MediaQuery>

In native, it could look something like this

<style>
  @media (prefers-color-scheme: dark) {
    .light-mode { display: none; }
    .dark-mode { display: block; }
  }
  @media (prefers-color-scheme: light) {
    .light-mode { display: block; }
    .dark-mode { display: none; }
  }
</style>

<img src="image-light.svg" class="light-mode">
<img src="image-dark.svg" class="dark-mode">