# Dark mode support for HTML pictures Sizing native HTML images is easier compared to CSS backgrounds thanks to flexbox and Bootstrap-style grid layouts. HTML's `<picture>` elements allowing for various `<source srcset="">` children is great for supporting modern (avif, webp) as well as fallback image standards (png). It even supports media queries. Unfortunately, the media queries for `prefers-color-scheme: dark` is not enough to allow the browser to choose light-vs-dark mode versions of an image. This is due this value expressing the UserAgent's current preference, instead of the actual selected Theme. **Declaring the image with dark/light mode and various formats:** ```HTML <picture> <source srcset="image-dark.png" media="none and (prefers-color-scheme: dark)" /> <source srcset="image-light.png" media="none and (prefers-color-scheme: light)" /> <img src="light-image.png" alt="" /> </picture> ``` **Note:** including `none and` prevents flickering where the foreground and background color are momentarily out of sync. **Custom JS that shows/hides sources depending on current theme:** ```js /**  * Make <picture> <source> elements with media="(prefers-color-scheme:)"  * respect custom theme preference overrides.  * Otherwise the `media` preference will only respond to the OS-level setting  */ const updateSourceMedia = (theme) => {     const pictures = document.querySelectorAll('picture')     pictures.forEach((picture) => {       const sources =         picture.querySelectorAll(`           source[media*="prefers-color-scheme"],           source[data-media*="prefers-color-scheme"]         `);       sources.forEach((source) => {         // Preserve the source `media` as a data-attribute         // to be able to switch between preferences         if (source?.media.includes('prefers-color-scheme')) {           source.dataset.media = source.media         }         // If the source element `media` target is the `preference`,         // override it to 'all' to show         // or set it to 'none' to hide         if (source?.dataset.media.includes(theme)) {           source.media = 'all'         } else if (source) {           source.media = 'none'         }       })     })   } ``` This needs to be called onload (`<body onload="foo()">`) and added to the Theme Button. **To get the new theme value:** ```js /**  * Gets the new theme based on the current theme.  * @returns {string} The new theme.  */ const getNewTheme = () => {     let currentTheme = document.documentElement.getAttribute("data-theme");     return currentTheme === "light" ? "dark" : "light"; } ``` Source: https://larsmagnus.co/blog/how-to-make-images-react-to-light-and-dark-mode #webdev #darkmode #html5 #image