Les articles de la catégorie « Non classé »

Résoudre les problèmes de mode sombre de Gmail avec les modes de fusion en CSS

Depuis ses débuts en octobre 2019, le mode sombre (« dark mode ») de Gmail cause pas mal d’arrachage de cheveux. Les choses se sont améliorées et uniformisées au fil du temps, mais il reste encore des différences majeures entre le mode sombre de Gmail sur iOS contre celui sur Android.

Un des plus gros problèmes sur iOS est que Gmail insiste pour changer n’importe quelle couleur de texte clair en une couleur de texte sombre. Donc un email déjà sombre avec du texte blanc sur un fond noir sera transformé en texte noir sur fond blanc. Non seulement ça me semble un peu contre productif, mais ça créé aussi de vrais problèmes de lisibilité et d’accessibilité.

Voici par exemple un email de Nest.

Ça fait un moment que je réfléchis à comment on pourrait résoudre ça. Et les modes de fusion en CSS (Blend Modes) me sont restés en tête depuis qu’ils sont supportés dans Gmail. Voici donc comment résoudre certains problèmes du mode sombre de Gmail avec des modes de fusion en CSS.

1. Le code de base

Pour cet exemple, on va commencer en utilisant une seule <div> avec un fond noir et un texte blanc.

<div style="background:#000; color:#fff;">
    Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
</div>

2. Comment Gmail transforme les couleurs

Si vous ouvrez un email avec le code ci-dessus dans Gmail sur iOS en mode sombre, vous verrez que les couleurs auront changé. Je n’ai jamais vraiment compris comment Gmail fait pour modifier les couleurs. (On garde toujours notre code d’origine si on copie/colle l’email ou si on le transfère.) Mais le résultat final est similaire à ce que donnerait le code suivant.

<div style="background:#fff; color:#000;">
    Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
</div>

3. Ajout des modes de fusion

Revenons à notre code initial et commençons à faire de la magie avec les modes de fusion. On va ajouter deux <div> internes à notre code, chacune avec un fond noir et un mode de fusion différent.

<div style="background:#000; color:#fff;">
    <div style="background:#000; mix-blend-mode:screen;">
        <div style="background:#000; mix-blend-mode:difference;">
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

Et pour notre tour final, on va utiliser une image de fond créée par un dégradé linear-gradient en CSS pour maintenir notre couleur de fond souhaitée. (J’ai appris cette technique grâce à Annett Forcier pendant sa présentation sur le mode sombre avec Anne Tomlin l’an dernier.)

<div style="background:#000; background-image:linear-gradient(#000,#000); color:#fff;">
    <div style="background:#000; mix-blend-mode:screen;">
        <div style="background:#000; mix-blend-mode:difference;">
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

Regardons petit à petit comment ce code est interprété dans Gmail iOS et pourquoi ça fonctionne.

3.1 Comment Gmail transforme ce code

Premièrement, Gmail va changer les couleurs. Le texte blanc va devenir noir, et les fonds noirs vont devenir blancs, à l’exception du dégradé linear-gradient. Notre code finira donc par ressembler à ça.

<div style="background:#fff; background-image:linear-gradient(#000,#000); color:#000;">
    <div style="background:#fff; mix-blend-mode:screen;">
        <div style="background:#fff; mix-blend-mode:difference;">
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

3.2 Les modes de fusion

Parlons maintenant des modes de fusion. Si on prend la définition de MDN :

Un mode de fusion est une méthode de calcul permettant de déterminer la couleur finale d’un pixel lorsque plusieurs couches sont empilées.

Une opération de fusion nécessite une « couleur source » et la fusionne avec une « couleur d’arrière plan ». Le résultat exact dépend du type de mode de fusion qu’on utilise.

On peut utiliser des modes de fusion dans Photoshop. Et on peut utiliser des modes de fusion en CSS grâce à deux propriétés : background-blend-mode et mix-blend-mode. Les deux ont le même support dans Gmail. Mais comme notre objectif ici est de maintenir la couleur d’un texte, on va utiliser uniquement la propriété mix-blend-mode.

Can I email… mix-blend-mode

Si vous voulez en savoir plus sur les modes de fusion en CSS, je vous recommande très chaudement les articles suivants (en anglais) :

3.3 La première fusion : difference

La première fusion qui a lieu dans notre code est une difference. D’après la définition de la spécification du W3C, une fusion par différence « soustrait la plus sombre des deux couleurs de la couleur la plus claire ». Mathématiquement, le résultat est la valeur absolue de la différence entre notre couleur source (Cs) et notre couleur d’arrière-plan (Cb).

B(Cb, Cs) = |Cb - Cs|

Si on revient à notre code, ce mode de fusion va se passer entre notre texte noir sur fond blanc (suite à la transformation de Gmail) et son parent avec un fond blanc.

<div style="background:#fff;">
    <div style="background:#fff; mix-blend-mode:difference;">
        Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
    </div>
</div>

Mathématiquement, ça signifie que notre texte noir de la source devient…

|Cb - Cs| = |rgb(255,255,255) - rgb(0,0,0)|
          = rgb(255,255,255)

… blanc ! Et le fond blanc de cette source fusionné avec le fond blanc de l’arrière-plan devient…

|Cb - Cs| = |rgb(255,255,255) - rgb(255,255,255)|
          = rgb(0,0,0)

… noir !

Parfait ! Mais attendez, que se passe-t-il si on applique ça dans Gmail en mode clair ? Notre code de base serait comme le suivant.

<div style="background:#000;">
    <div style="background:#000; color:#fff; mix-blend-mode:difference;">
        Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
    </div>
</div>

Notre texte blanc de la source fusionné avec l’arrière-plan noir devient…

|Cb - Cs| = |rgb(0,0,0) - rgb(255,255,255)|
          = rgb(255,255,255)

… blanc ! Et notre fond noir en source fusionné avec le fond noir de l’arrière-plan devient…

|Cb - Cs| = |rgb(0,0,0) - rgb(0,0,0)|
          = rgb(0,0,0)

… noir ! Ça fonctionne toujours !

Mais attendez, on n’aurait pas fini là ? Si vous avez seulement besoin d’un texte blanc sur un fond noir, alors vous pouvez en effet vous arrêter ici. Mais si vous avez besoin d’un texte blanc sur un fond coloré, on va avoir besoin de ce deuxième mode de fusion.

3.4 La deuxième fusion : screen

Revenons un peu en arrière et recommençons avec un texte blanc sur un fond violet (#639).

<div style="background:#639; background-image:linear-gradient(#639,#639); color:#fff;">
    <div style="background:#000; mix-blend-mode:screen;">
        <div style="background:#000; mix-blend-mode:difference;">
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

Premièrement, Gmail va modifier ces couleurs. Le noir devient blanc, le blanc devient noir, et le violet devient légèrement plus clair.

<div style="background:#c7a4ef; background-image:linear-gradient(#639,#639); color:#000;">
    <div style="background:#fff; mix-blend-mode:screen;">
        <div style="background:#fff; mix-blend-mode:difference;">
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

Ensuite, la première fusion (difference) s’applique. Mais à ce stade, on obtient exactement le même résultat qu’avant : un texte blanc sur fond noir.

Entre alors en scène notre deuxième fusion : screen. D’après la définition de la spécification du W3C, un mode de fusion screen « multiplie le complément des valeurs de l’arrière-plan et de la couleur source, puis complémente le résultat ». Oui, alors, moi aussi j’ai rien compris. Mais les formules de maths m’ont aidé à comprendre.

B(Cb, Cs) = 1 - [(1 - Cb) * (1 - Cs)]
          = Cb + Cs - (Cb * Cs)

Voyons voir ce qui se passe. À ce stade, c’est comme si on faisait une fusion d’un texte blanc sur un fond noir avec notre arrière-plan violet.

<div style="background:#639;">
    <div style="background:#000; color:#fff; mix-blend-mode:screen;">
        <div>
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

Notre texte blanc en source (Cs) fusionné avec le fond violet (Cb) devient…

B(Cb, Cs) = Cb + Cs - (Cb * Cs)
          = rgb(102, 51, 153) + rgb(255,255,255) - (rgb(102, 51, 153) * rgb(255,255,255))
          = rgb(102, 51, 153) + rgb(255,255,255) - rgb(102, 51, 153)
          = rgb(255,255,255)

… blanc ! Et notre fond noir en source (Cs) fusionné avec l’arrière-plan violet (Cb) devient…

B(Cb, Cs) = Cb + Cs - (Cb * Cs)
          = rgb(102, 51, 153) + rgb(0,0,0) - (rgb(102, 51, 153) * rgb(0,0,0))
          = rgb(102, 51, 153) + rgb(0,0,0) - rgb(0,0,0)
          = rgb(102, 51, 153)

… violet ! Et voilà, c’est comme ça qu’on maintient un texte blanc sur un fond de n’importe quel couleur. Et ça fonctionne aussi avec des images de fond.

<div style="background:#6db6b0; background-image:url(https://i.imgur.com/F7S1NGq.jpg); background-size:cover; color:#fff;">
    <div style="background:#000; mix-blend-mode:screen;">
        <div style="background:#000; mix-blend-mode:difference;">
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

Le seul problème ici est que ce code s’applique sur n’importe quel client mail. Et pour ceux qui ne supportent pas mix-blend-mode, seul un fond noir s’affiche. On doit donc faire en sorte que ce code ne s’applique que sur Gmail.

4. Cibler Gmail

La méthode pour cibler Gmail est bien connue depuis plusieurs années (et est même référencée sur HowToTarget.email). Il y a deux pré-requis pour que ça fonctionne :

  1. Avoir un doctype au début de votre code HTML (par exemple : <!DOCTYPE html>)
  2. Ajouter une classe dédiée sur l’élément <body> (par exemple : <body class="body">)

Ensuite on peut cibler n’importe quelle classe dans notre code (par exemple : .foo) avec le sélecteur suivant :

u + .body .foo { }

La raison pour laquelle cela fonctionne est parce que Gmail remplace le doctype d’un email avec un élément <u></u>. Donc le code de base d’un email ci-dessous…

<!DOCTYPE html>
<html lang="en">
<head>
    <title>An HTML email</title>
    <style>u + .body .text { color:green; }</style>
</head>
<body class="body">
    <p class="text">ELO world!</p>
</body>
</html>

… devient :

<div id=":8p" class="a3s aiL msg4142466614215349360">
    <u></u>
    <div class="m_4142466614215349360body">
        <p class="m_4142466614215349360text">
            ELO world!
        </p>
    </div>
</div>

Et le sélecteur CSS utilisé est bien correctement préfixé par Gmail en :

.msg6240499631687324626 u+.m_6240499631687324626body .m_6240499631687324626text { color:green }

Donc, si on revient à notre code, on va déplacer les deux modes de fusion et les styles de background en ligne dans une balise <style> dédiée. (Et on s’assurera bien d’avoir un doctype et une classe .body.)

<style>
    u + .body .gmail-blend-screen { background:#000; mix-blend-mode:screen; }
    u + .body .gmail-blend-difference { background:#000; mix-blend-mode:difference; }
</style>
<div style="background:#639; background-image:linear-gradient(#639,#639); color:#fff;">
    <div class="gmail-blend-screen">
        <div class="gmail-blend-difference">
            Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
        </div>
    </div>
</div>

Un effet de bord imprévu mais bienvenu quand même de cette séparation des styles de mode de fusion est que le code va gracieusement se dégrader dans les applications Gmail avec des comptes non Google. Dans GANGA (comme les emailgeeks aiment bien dire), mix-blend-mode n’est pas supporté. Mais les éléments <style> non plus. Dans ce cas, Gmail appliquera alors simplement ses ajustements de couleurs.

5. Le code final

Voici un exemple complet de code avec tout ce qu’il faut bien en place.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fixing Gmail’s dark mode issues with CSS Blend Modes</title>
    <style>
        u + .body .gmail-blend-screen { background:#000; mix-blend-mode:screen; }
        u + .body .gmail-blend-difference { background:#000; mix-blend-mode:difference; }
    </style>
</head>
<body class="body">
    <div style="background:#639; background-image:linear-gradient(#639,#639); color:#fff;">
        <div class="gmail-blend-screen">
            <div class="gmail-blend-difference">
                <!-- Votre contenu commence ici -->
                Lorem ipsum dolor, sit amet, consectetur adipisicing elit.
                <!-- Votre contenu se termine ici -->
            </div>
        </div>
    </div>
</body>
</html>

J’ai fait une sorte de mire pour tester différentes couleurs de fond. Vous pouvez trouver le code ici.

Capture d’écran d’un test de mire dans Gmail iOS en mode sombre. En haut, avec le correctif, le texte blanc et la couleur de fond sont toujours conservés. En bas, sans le correctif, les couleurs sont changées par Gmail.

Conclusion

Je pense que le modes sombre est une avancée majeure en terme d’accessibilité et de préférences utilisateur. Et comme je le disais il y a déjà deux ans, « le mieux que vous puissiez faire est d’accepter ce choix plutôt que d’essayer de luttre contre ». Mais c’est aussi important de reconnaître quand les clients mail font n’importe quoi.

Je suis tout excité d’avoir réussi à trouver cette solution. Et même si ça reste limité (l’utilisation de mode de fusions limite ça a du texte blanc), j’espère que ce sera bien utile pour quiconque rencontre des difficultés avec le mode sombre de Gmail.

Email Camera

Cet article est la retranscription d’une présentation donnée à Litmus Live 2017 à Londres le 29 août lors de la session #EmailHacks présentée par Kevin Mandeville. Vous pouvez trouver mes slides ici et la démo de « l’Email Camera » ici. Une version en anglais de cet article est disponible.

J’aime beaucoup les jeux vidéo. Je suis un grand fan de Nintendo, en particulier du Game Boy. (Oui, on dit un Game Boy.) J’adore le Game Boy. C’était ma première console quand j’étais petit. Et maintenant j’en collectionne plein.

En 1998, Nintendo sort le Game Boy Camera. C’est une caméra numérique montée sur une cartouche de jeu. Elle peut prendre des photos en quatre niveaux de gris dans une résolution de 128 × 112 pixels. Et elle comprenait des jeux, filtres et était compatible avec le Game Boy Printer. Le Game Boy Camera transformait le Game Boy en machine à selfie ultime.

Il y a quelques mois, je trainais sur le Slack des #emailgeeks. À un moment, Kevin Mandeville a mentionné le Game Boy Camera. Et Jacques Corby-Tuech a répondu quelque chose du genre : « Un Game Boy Camera dans un e-mail. »

Ça a immédiatement fait tilt. Il fallait que je fasse ça. Si quelqu’un devait faire un e-mail inspiré par le Game Boy Camera, il fallait que ce soit moi. En plus, j’avais déjà le sentiment qu’utiliser la caméra dans un e-mail était possible depuis que j’avais vu cette démo sur CodePen.

C’est une démo de colorisation d’image dynamique qui utilise la pipette colorimétrique système et qui permet de changer la couleur de la voiture dans la photo. Et ça n’utilise pas du tout de JavaScript. C’est juste du HTML et CSS. C’est possible en grande partie grâce à l’élément suivant.

<input type="color" />

Ce qui est bien avec un <input type="color">, c’est que ça utilise la pipette colorimétrique système. Et les navigateurs compatibles affichent généralement un aperçu de la couleur sélectionnée.

Un exemple de pipette colorimétrique dans Chrome sur macOS

En utilisant un peu de CSS et des sélecteurs propriétaires comme ::-webkit-color-swatch et ::-webkit-color-swatch-wrapper, on peut retirer les bordures et marges intérieures de l’élément. Puis, en appliquant encore quelques styles, on peut redimensionner cet élément en plein écran. Et puis on peut placer une photo en dessous. Et en utilisant la propriété CSS mix-blend-mode:hue, on arrive au résultat souhaité.

Qu’est-ce que ça a à voir avec des e-mails et le Game Boy Camera ?

Et bien, il s’avère qu’on peut faire quelque chose d’équivalent avec l’élément suivant.

<input type="file" />

Un champ de type file permet de déposer des fichiers sur le Web. Et il y a deux choses particulièrement chouette à son égard :

1. Sur iOS ou Android, on peut importer un fichier directement depuis son appareil, ou utiliser l’appareil photo directement depuis là où on est pour prendre une photo.
2. Sur iOS, après avoir pris une photo, on obtient une toute petite miniature de 18 × 18 px.

À nouveau, en utilisant des sélecteurs propriétaires comme ::-webkit-file-upload-button, on peut masquer le bouton « Choisir un fichier ». On peut aussi tronquer l’élément pour ne laisser visible que l’image, et l’agrandir en utilisant une transformation CSS.

Un peu plus tard, le jour où le Game Boy Camera a été mentionné sur Slack, j’ai posté la vidéo suivante.

Voici la démo complète disponible sur CodePen. Ça fonctionne bien dans Apple Mail sur iOS. Essayez et amusez-vous bien !

Accessibility in Email

Mark Robbins a commencé à écrire une série d’article sur l’accessibilité dans les e-mails. Il y a pour l’instant une introduction et un article sur la sémantique. Mark a également donné une conférence sur l’accessibilité lors d’un meetup Email On Acid Insights en début de mois. C’est un sujet important, et c’est bien qu’on commence à entendre parler comme ça.

Super Mail Forward, cinq mois après

J’ai publié une traduction en anglais de mon retour sur la création de Super Mail Forward, un e-mail transférable évolutif. Cinq mois après, il y a deux changements principaux.

AOL a corrigé le bug de remplacement des images en background dans une balise <style>. J’ai donc trouvé une autre bidouille pour activer des styles sur AOL. Ou plus précisément, pour ne pas que des styles s’activent sur AOL. En fait, une balise <style> contenant une image de fond à l’URL non supportée (par exemple background:url('#');) sera totalement supprimée. Dans l’exemple suivant, ces styles s’appliqueront donc partout (ou presque), sauf sur AOL.

<style type="text/css">
   .step1 { background:url('#'); }
   .step1 .W { background:#fff!important; }
   .step1 .X { background:#f8d81f!important; }
   .step1 .Y { background:#d89f37!important; }
   .step1 .Z { background:#000!important; }
</style>

Microsoft a commencé à remplacer Outlook.com par le même webmail qu’Office 365 (aussi appelé Outlook Web App). Ce webmail ne supporte pas les sélecteurs d’attributs. Pour cibler des styles uniquement sur ce webmail, on peut donc écrire le sélecteur suivant…

<style type="text/css">
   [owa] .toto { … }
</style>

…qui sera interprété comme :

<style type="text/css">
   .rps_123a .x_toto { … }
</style>

Comment masquer une checkbox et un bouton radio dans un e‑mail

Justin Khoo chez FreshInbox explique comment masquer une checkbox et un bouton radio dans un e‑mail. En résumé : il faut un display:none en ligne dans un attribut style. Mais il faut ajouter un !important sinon Gmail le filtre. Mais Yahoo filtre la propriété dès qu’il y a un !important. Donc il faut rajouter une classe et une règle dans une balise <style>.

C’est pour moi une illustration parfaite du jeu de la taupe qu’est l’intégration d’e‑mails. Du coup j’ai fait ce GIF animé.

L'intégration d'e-mails vu comme un jeu de la taupe avec des chatons.

The Hidden Talents of Email

Wistia a mis en ligne une conférence de Justine Jordan, directrice marketing chez Litmus : « The Hidden Talents of Email ». Je ne connaissais Justine que de nom, mais je suis conquis. Elle est drôle, intelligente, et elle livre une tonne de contenus et d’exemples intéressants en à peine une demi-heure. Et je suis émerveillé par la qualité des introductions des orateurs des conférences de Wistia.

Yahoo ne supporte plus la propriété display:none en ligne

Dans la série « tout peut changer du jour au lendemain », cette semaine Yahoo.com a décidé d’arrêter de supporter la propriété display:none lorsqu’elle est appliquée directement en ligne via l’attribut style d’une balise HTML. C’est Mark Robbins qui l’a remonté sur les forums de Litmus. La propriété n’est cependant pas filtrée si elle est utilisée dans une balise <style> dans le <head>, ou si elle a comme valeur block. Ce changement ne concerne que le webmail desktop de Yahoo, et pas par exemple l’application mobile sur iOS.

Office 365 et ses nombreux caprices pour les designers d’e-mails

James White fait le tour des points vraiment pénibles de Office 365 (Outlook Web Access) pour l’intégration d’e-mails. Sa phrase d’introduction résume bien le sujet :

Après avoir creusé le sujet, j’en arrive à la conclusion que l’application Office 365 OWA est pire que Outlook 2007 ou 2013 en terme de support des standards.

Bonjour tout le monde !

Bonjour à tous ! J’ai le sentiment que l’intégration d’e-mails est une tâche conspuée, traitée comme un sous-domaine de l’intégration.  Et pour cause : les applications mails et les webmails n’ont pas beaucoup évolué depuis le début des années 2000. Ou pire : ils ont évolué dans le mauvais sens.

Mais ce n’est pas une raison pour mal intégrer ses e-mails. Ce blog est une tentative d’expliquer le savoir-faire nécessaire à l’intégration d’e-mails, les horreurs obligatoires, les atrocités imposées par les webmails, … Mais aussi les choses qui m’amusent.