Maison > interface Web > tutoriel CSS > Les astuces derrière « l'Invasion du HTML mutant »

Les astuces derrière « l'Invasion du HTML mutant »

Linda Hamilton
Libérer: 2024-12-04 00:42:09
original
421 Les gens l'ont consulté

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 un site statique disponible en ligne, open-sourcé sur GitHub — pour que vous puissiez l’améliorer !

Quand je dis statique, c’est statique : le dépôt a une unique dépendance, servor, chargée de fournir un serveur HTTP basique pour travailler en local  et servor n’a elle-même aucune dépendance. Le reste n’est que HTML, CSS et JavaScript.

Ça m’a permis de revenir aux fondamentaux, considérablement gagner en efficience ; mais surtout… découvrir tout un tas de trucs et astuces !

La mécanique du jeu

En démarrant le jeu, vous commencerez par personnaliser votre personnage. Le seul objectif de cette étape est de découvrir la structure visuelle d’un niveau, en vous permettant de vous impliquer personnellement dans le jeu. Les valeurs choisies seront appliquées dès que possible à tous les personnages du jeu, dans une sorte de représentation en miroir.

Après avoir choisi votre personnage, un niveau d’entraînement vous familiarise avec la mécanique très simple du jeu : une portion de code à compléter et soumettre, exécutée en direct, qui affecte la zone envahie progressivement par des mutants ! Ce code est dans la plupart des niveaux les options passées à un mutationObserver, mais parfois aussi dans la fonction de rappel.

En cas d’échec comme en cas de réussite, une fenêtre modale vous informera. Parlons-en, de cette fenêtre modale !

Les particularités de

J’en parlais en 2022 à Paris Web puis au devFest Nantes dans mon sujet « Découvrez " le bon HTML " et économisez du JS et du CSS », l’élément

est extrêmement intéressant et devrait à terme supplanter toutes les implémentations de fenêtres modales dans les différentes bibliothèques de composants.

Dans l’atelier, je m’en sers en plusieurs endroits :

  1. pour afficher les règles du jeu dans l’écran d’accueil ;
  2. pour interrompre un niveau, quand le nombre de mutants dépasse la centaine ;
  3. pour informer d’un échec lors d’une soumission de code qui ne fonctionne pas ;
  4. pour informer de la réussite, dans le cas contraire — et permettre de passer au niveau suivant.

Ouvrir la fenêtre

La plupart sont ouvertes programmatiquement, en réaction à un événement. Rien de plus simple : il suffit de récupérer une référence à l’élément

à l’aide de querySelector() ou une référence à un identifiant via l’accès aux propriétés nommées, ou named properties access (en anglais), et d’invoquer la méthode showModal() (sur MDN, en anglais).

document.querySelector('dialog').showModal();
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Sans JavaScript externe

Une exception toutefois, pour éviter d’ajouter un écouteur d’événement inutile : la fenêtre des règles du jeu est invoquée grâce à un gestionnaire d’événement HTML onclick :

<button type="button" onclick="rules.showModal()">Règles du jeu</button>
<dialog>



<h5>
  
  
  Aparté : la projection des identifiants HTML en objets globaux
</h5>

<p>Dans cet exemple, j’invoque l’ouverture de la fenêtre modale avec rules.showModal(), sans avoir défini la variable rules. Comment est-ce possible ? En résumé, tout élément porteur d’un attribut id devient mécaniquement une propriété globale de l’objet window, et devient donc accessible directement par son nom. C’est spécifié sous le joli nom de Named Access on Window Object (en anglais).</p>

<p>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é DOM clobbering (en anglais). Je vous encourage à parcourir les recommandations de l’OWASP pour mitiger le DOM clobbering (en anglais).</p>

<h4>
  
  
  Accessibilité
</h4>

<p>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 <kbd>Échap</kbd>, etc.</p>

<h3>
  
  
  L’arrière-plan
</h3>

<p>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 un pseudo-élément ::backdrop qui s’étend naturellement sur tout le viewport et est promue, avec la fenêtre modale, par-dessus le reste de la page dans ce qui est spécifié sous le nom de top layer.

<p>Vous n’avez plus qu’à lui appliquer une couleur, une opacité ou que sais-je encore. Dans le jeu, j’ai utilisé une propriété au nom évocateur de backdrop-filter pour appliquer un effet de flou grisé sur l’arrière-plan.<br>
</p>

<pre class="brush:php;toolbar:false">dialog::backdrop {
    backdrop-filter: grayscale(50%) blur(.25rem);
}
Copier après la connexion
Copier après la connexion

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);
}
Copier après la connexion

La propriété max-inline-size est la propriété logique correspondant à max-width dans le cas du Français. Et la fonction clamp() est un petit bijou, dont j’abuse déjà copieusement dans chaarts (en anglais) pour obtenir un pseudo-booléen en CSS en fonction d’une valeur, comme expliqué slide 27 de ma conférence « Dessine-moi un graphique (en CSS) » donnée au devFest Nantes 2023, TNT #24 et DevQuest 2024.

Fermer la fenêtre

J’ai évoqué la capacité de fermer la modale avec la touche Échap, mais l’élément

tire d’autres super-pouvoirs du fait d’être natif, et notamment son association avec un élément
. C’est parfaitement naturel, puisqu’une fenêtre modale permet généralement de valider ou annuler une action associée à une saisie.

C’est pourquoi la valeur dialog est ajoutée à la method 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>



<p>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 :<br>
</p>

<pre class="brush:php;toolbar:false"><button form="fermer">Fermer la fenêtre</button>
Copier après la connexion

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 cet attribut date (au moins) de 2006, dans les spécifications W3C des Web Forms (en anglais) dont les premiers brouillons remontent à 2004..

Les émojis

Pour cet atelier, j’avais besoin de méchants envahisseurs, et de décors. Clairement pas le temps de faire des illustrations à la main, ni les moyens d’acheter des visuels. Une quête sur les internets m’a appris que le type de visuels que je cherchais se nomme les top down tileset, ces petits décors et personnages généralement en 8-bit avec une perspective écrasée.

À force de regarder des visuels en 8-bit, j’ai fini par faire le lien avec une vieille habitude dans mes supports de conférences : les émojis décoratifs en fin de titre. Bon sang, mais c’est bien sûr ! Des émojis !

Les émojis sont formidables. Ce sont des points Unicode, purement textuels, et extrêmement nombreux désormais avec des pelletées de nouveautés dans chaque version d’Unicode. Il y a même des variantes, composées en séquence !

Les personnages

Le meilleur exemple de séquence Unicode à mon avis sont les personnages : le neutre Personne ? peut devenir un homme ? ou une femme ? en y ajoutant le point unicode du genre masculin ♂️ ou féminin ♀️, séparé par une jointure de largeur zéro (zero-width joiner, ‍).

Pour obtenir un pompier ?‍?, on ajoute simplement un camion de pompier ? à une personne ? ! N’est-ce pas génial, franchement ? Et on peut évidemment y ajouter le genre et le teint.

La personnalisation

Ainsi le premier palier permet de personnaliser le genre et le teint du héros.

Le formulaire n’est composé que de deux groupes de bouton radio, chacun ayant une valeur correspondant au point Unicode concerné.

document.querySelector('dialog').showModal();
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Et le tour est joué : les utilisateurs de Firefox ne chargeront rien, et les autres téléchargeront une typographie pour afficher la même chose que Firefox. Choisissez mieux votre navigateur, la prochaine fois !

Les astuces derrière « l’Invasion du HTML mutant »

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 un ticket sur leur Bugzilla (en anglais).

La coloration syntaxique sans JS

Dans la mécanique du jeu, des portions de code sont affichées (pour faire un « code à trous ») et du code est saisi des éléments et