Le 17 octobre dernier, j’animais au devFest Nantes un atelier intitulé « L’Invasion du HTML mutant ».
Un atelier devant par définition impliquer les participants, j’ai fait le choix de créer un mini-jeu en guise de support. C’est — pour que vous puissiez l’améliorer !
Quand je dis statique, c’est statique : le dépôt a une unique dépendance, puis », , et d’invoquer .
C’est drôlement pratique, non ? Figurez-vous que c’est aussi un vecteur d’attaque méconnu faisant partie d’un groupe sobrement intitulé .
Accessibilité
La méthode showModal() permet d’ouvrir une fenêtre modale, pas une simple boîte de dialogue — en respectant les exigences en matière d’accessibilité : la focus est mécaniquement piégé dedans, la fermeture est possible avec la touche Échap, etc.
L’arrière-plan
Une fois la fenêtre modale ouverte, on peut s’appliquer à la styler. Là où moult bibliothèques de composants imposent une <div> (voire plusieurs) pour servir d’arrière-plan à la fenêtre, la version native est livrée avec pour appliquer un effet de flou grisé sur l’arrière-plan.
dialog::backdrop {
backdrop-filter: grayscale(50%) blur(.25rem);
}
Les dimensions
Ne maîtrisant pas le mode de consultation du jeu, j’ai utilisé un peu de CSS moderne pour la largeur de la fenêtre modale afin qu’elle ait une largeur fluide, mais avec des valeurs minimum et maximum.
dialog {
max-inline-size: clamp(50vw, 100%, 67.5rem);
}
La propriété max-inline-size est la est un petit bijou, dont j’abuse déjà copieusement dans donnée au et de soumission d’un formulaire. Elle ne correspond pas à une méthode HTTP comme get ou post, mais bien à un contexte HTML, et permet de fermer directement la fenêtre modale parente. L’utilisation est fort simple :
<form id="fermer" method="dialog">
Et, pour revenir à du HTML à l’ancienne : saviez-vous qu’un bouton à l’autre bout du DOM peut soumettre un formulaire ? Il suffit de lui indiquer le formulaire à soumettre :
<button form="fermer">Fermer la fenêtre</button>
Et voilà : c’est un bouton de type submit qui soumettra le formulaire avec l’identifiant fermer, qui lui-même fermera la fenêtre de dialogue. C’est beau, non ? Et .
Le formulaire n’est composé que de deux groupes de bouton radio, chacun ayant une valeur correspondant au point Unicode concerné.
<fieldset>
<legend>Genre</legend>
<input type="radio" name="genre" id="feminin" value="♀️">
<label for="feminin">Féminin</label>
<input type="radio" name="genre" id="masculin" value="♂️">
<label for="masculin">Masculin</label>
<input type="radio" name="genre" id="neutre" value="" checked>
<label for="neutre">Neutre</label>
</fieldset>
Lors de la soumission, les deux valeurs sélectionnées sont poussées dans le localStorage et ré-employées dès que possible dans la suite du jeu. Pour certains méchants, il suffit de concaténer le caractère du méchant avec les deux sélections : voilà comme un Mage 🧙 devient une Mage au teint sombre 🧙🏿♀️.
Les décors
J’ai un peu lutté avec les décors, demandant même de l’aide à mon camarade Clément Étienne. Et finalement, je suis revenu aux émojis : certains ont un caractère paysager intéressant, il suffit de les agrandir un peu…
Les navigateurs
Les navigateurs et systèmes d’exploitation ont leur propre livrée d’émojis, avec des supports disparates et des rendus variés. Pour palier cet écueil, j’ai opté pour une solution très simple technologiquement parlant : une typographie. Et à ce jeu-là, j’avais déjà ma préférée :
WebKit
Comme souvent quand je prépare un sujet, je me suis heurté à quelques limites des navigateurs. En l’occurrence, WebKit, le moteur de Safari et Epiphany, a des problèmes avec les variantes de teinte de la Twemoji-COLR. J’ai pu ouvrir ou . C’est à mon sens, une petite révolution : une typographie tirant parti des fonctionnalités OpenType et notamment la table COLR. Fini les tartines de <span>, place à un code lisible et propre !
Si les détails d’implémentation OpenType vous intéressent, je vous encourage à lire l’article. De mon côté, je me suis focalisé sur la personnalisation de la palette, rendues possibles en CSS avec .
Voilà ce que ça donne pour le jeu, dans lequel je profite de l’utilisation de propriétés personnalisées CSS pour la gestion des couleurs :
@font-palette-values --syntaxHighlighter {
font-family: 'FontWithASyntaxHighlighter';
override-colors:
0 var(--foreground),
4 rebeccapurple,
5 var(--accent),
7 var(--muted);
}
Le rendu est pas mal, non ?
. Notre score correspondra simplement au nombre d’aliens présents.
Cependant, si notre compteur commence à 1 et peut monter jusqu’à 100 — et sachant que le jeu original disposait d’un compteur sur cinq chiffres — le rendu ne sera ni élégant ni une belle citation. Heureusement, qui a ouvert pour atteindre la bonne couleur.
C’est un exercice compliqué, et je remercie Barrett Sonntag pour son
Les Web Components
Et dire que je n’ai parlé que de HTML et CSS, pour le moment… Je ne m’étendrai pas autant, mais côté JavaScript, je me suis (un peu trop) amusé avec les Web Components. En résumé :
<mu-tant>est le composant qui affiche un mutant, et gère sa mutation : un changement d’attribut, de valeur d’attribut, de contenu, de descendance, etc. Le tout à intervalle irrégulier, et de façon désordonnée.
<code-runner>étend la fonctionnalité du formulaire pour normaliser les réponses et les envoyer au<play-ground>. Pour le clin d’œil, l’événement qui permet de diffuser les réponses est intitulévoightkampff.
<play-ground>est le composant le plus critique : il déclenche l’invasion, surveille l’événementvoightkampff, exécute le code soumis, et donne le verdict (en ouvrant la fenêtre modale appropriée).
Dans tout ça, j’ai énormément joué avec les mutationObserver, les intervalles et les minuteurs, les émojis, et la génération de valeurs aléatoires.
Conclusion
Si tout ce fatras vous rend curieux, je vous invite à visiter
Et si vous vous lancez dans le jeu, je vous invite à consulter pour patienter jusqu’à Noël.
Voir tous les articles du Advent of Tech 2024.
SOCIAL SHARE CARD GENERATOR