16 December 2025
I built this website with simplicity in mind, trying to keep complexity to a minimum while also keeping space for cool features such as dynamic theme switching according to the device settings. While implementing it, one of the main challenges was allowing the icons (SVGs) to change their colors accordingly.
A cool feature I stumbled upon is the <style> tag
of SVGs, which seems to be supported on all major
browser engines. Here is what a dynamic themed rect should look
like:
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 40 20" width="40" height="20">
<style>
@media (prefers-color-scheme: dark) {
.my-object { fill: #aaa; }
}
@media (prefers-color-scheme: light) {
.my-object { fill: #333; }
}
</style>
<rect class="my-object" width="40" height="20"/>
</svg>Here’s the same SVG, rendered:
You can try to switch the theme on your phone/laptop to see how the SVG responds; it should immediately change its color to one that matches the background.
I tried applying that to my icons and was happy with the result. For example here’s a flask icon that I made:
There was, however, one critical issue. Safari (or any browser using
the Webkit engine) was the only browser that ignored the
<style> tag when the SVG was referenced from an
external file.
This is quite sad as it is quite useful to keep the HTML code clean
and avoiding redundancy. You can try it by yourself by including an SVG
in a HTML page by using
<img src="/path/to/dynamic_icon.svg" width="128" height="128">
and then opening it in safari.
So I ended up applying CSS filters to the SVGs, turning them white
when a dark theme was detected. This is quite straightforward, you
generate a filter from a website like this
one and then apply it to the class of the <img>
tags that you will use to include the SVGs:
@media (prefers-color-scheme: dark) {
.icon {
filter: brightness(0) saturate(100%) invert(100%) sepia(3%) saturate(335%) hue-rotate(204deg) brightness(112%) contrast(87%);
}
}<img src="/path/to/dynamic_icon.svg" class="icon" width="128" height="128">The only drawback with this method is that as far as I know there is no way to use SVGs that contain multiple colors.
Here you can see my tests on Safari, Chrome and Firefox:
| Safari |
|---|
![]() |
| Chrome |
|---|
![]() |
| Firefox |
|---|
![]() |