HervéRenault.fr

Logo de CSS3

Les images et le mode sombre en 2023

La règle CSS @media (prefers-color-scheme: dark) permet, par exemple, d'inverser facilement texte noir sur fond blanc en texte blanc sur fond noir. Mais pour les images, c'est plus compliqué.

Un logo à fond transparent avec du noir

Tout va bien en mode clair mais en mode sombre on a du noir sur noir :
Un simple logo en SVG

Si ce logo est en SVG, on peut en théorie inclure dans son fichier les styles qui vont bien :

<?xml version="1.0" encoding="UTF-8"?>
<svg width="355.67" height="112.8" version="1.1" viewBox="0 0 94.103 29.844" xmlns="http://www.w3.org/2000/svg">
 <style>
      @media (prefers-color-scheme:dark) {
        #ellipse148 {
          fill: purple;
        }
        #text154 {
          fill: lightblue;
        }
      }
 </style>
 <g id="g156" transform="translate(-30.088 -90.318)">
  <ellipse id="ellipse148" cx="45.009" cy="105.24" rx="14.921" ry="14.922" fill="#ff0" stop-color="#000000"/>
  etc..........

Ce qui donne :
Le même logo avec des styles pour le mode sombre dans le fichier SVG

Mais ce n'est toujours pas supporté par Safari en 2023 😬 Et puis si le logo est au format PNG, ou encore si c'est une photo de ciel bleu qu'on veut remplacer par un ciel de nuit, on ne peut pas utiliser cette méthode. Donc il faut ruser avec l'une de ces deux méthodes ci-dessous.

Méthode CSS

On écrase l'image dans son emplacement et on met l'image pour le mode sombre en image de fond.

@media (prefers-color-scheme: dark) {
  #logo1 {
    display: inline-block;
    box-sizing: border-box;
    background: url("logo-pour-mode-sombre.svg") no-repeat;
    height: 113px;
    width: 356px;
    padding-left: 356px; /* on l'écrase par la gauche (jouer sur ce param dans les devtools pour voir) */
  }
}

Résultat :
Le logo pour le mode clair

Méthode JavaScript

Simple remplacement en passant par la propriété src de l'image, en fonction de la valeur de la media query.

const logo = document.querySelector('#logo2');
const mq = matchMedia('(prefers-color-scheme: dark)');

changeLogo();
mq.addEventListener('change', changeLogo);

function changeLogo() {
  if (mq.matches) {
    logo.src = 'logo-pour-mode-sombre.svg';
  } else {
    logo.src = 'logo-pour-mode-clair.svg';
  }
}

Résultat :
Le logo pour le mode clair