Issue with Embedded Svg Images in Dark Mode

Need dark/light mode change in OS to force refresh of external SVG files

This does the trick, a few lines of javascript. First, on page load, identify all SVG images and determine the current prefers-color-scheme theme. Then, detect when that theme changes and append a dynamic cachebreaker to those filenames, which forces SVGs to reload.

// Dark mode changes needs cache refresh for external SVG file CSS.
allImg = document.querySelectorAll('img[src$=".svg"');
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
thisMode = 'dark';
} else {
thisMode = 'light';
}
window.matchMedia('(prefers-color-scheme: '+ thisMode + ')').addEventListener('change', e => {
allImg.forEach(img => {
imgTime = Date.now();
newImgSrc = img.src + '?' + imgTime;
img.src = newImgSrc;
});
});

Updated original answer 12/13/21. Now cachebuster, which forces reload of SVGs, is only called after mode change, not at every page load.

Update 12/19/21: This solution does not work with Safari (there's a known bug whereby Safari doesn't respect the prefers-color-scheme media query within SVG file CSS). For Safari, I wrote extra JS that detects Safari on page load, uses the prefers-color-scheme conditional above, and, if OS is dark mode, replaces all SVG filenames from "image.svg" to "image-dark.svg", calling light or dark versions of each SVG. It also reloads page in Safari when OS dark/light theme changed. If Apple ever fixes the bug, I can go with the simpler solution above.

Light mode dark mode toggle

You don't seem to have code that changes themeToggleLight.style.visibility. Does this help?

if (themeToggleLight.style.visibility == "hidden") {
themeToggleLight.style.visibility = "visible";
themeToggleDark.style.visibility = "hidden";
} else {
themeToggleLight.style.visibility = "hidden";
themeToggleDark.style.visibility = "visible";
}

My background-image doesn't show when I toggle dark mode with Chrome Lite Mode

I didn't find a specific solution for this issue, but I managed to solve my problem doing the pre-load image: Preloading CSS Images

Thank you all for being helpful and understanding!



Related Topics



Leave a reply



Submit