Découvrez « le bon HTML » et économisez du JS et du CSS

Retrouvez les slides en ligne sur ffoodd.fr/paris-web.2022/.

Le principe de moindre pouvoir

C’est un des axiomes du web, proposés par Tim Berners-Lee en 1998 — à côté de kiss, du design modulaire, de la tolérance ou de la décentralisation.

Le mantra de l’amélioration progressive, en somme…

L’arbre de décision

  1. HTML
  2. CSS
  3. JavaScript
  4. ARIA
  5. Polyfill
  6. Framework

Le support et le bon sens

Suivez les spécifications, les ajouts ou retraits de fonctionnalités — mais aussi les implémentations dans les navigateurs. hgroup n’a jamais eu d’implémentation sémantique, :is() et :where() vous font gagner quelques octets au détriment du support navigateur…

Validez votre HTML, aussi.

JavaScript est notre ami

JavaScript est indispensable, tant pour l’accessibilité que pour une expérience utilisateur optimale.

Mais il ne faut l’utiliser qu’en cas de nécessité, à l’instar d’ARIA. L’objectif est seulement de vous faire découvrir du HTML que vous ne connaissez peut-être pas.

Opinion : l’écosystème no-js est peuplé de démonstration CSS only, ce qui est littéralement impossible.

Dans le web, rien de nouveau

JavaScript a toujours poussé CSS dans ses retranchements.

Tous ces usages, implémentés en JavaScript faute de mieux, ont fini par aboutir à une standardisation dans HTML ou CSS.

Pensez un peu à l’impact de jQuery.

Liste de suggestions

Vous voulez proposer une liste de valeurs à l’utilisateur, en permettant aussi la saisie libre ?

Pas besoin d’une bibliothèque, ni même d’un composant riche !

Exemple de suggestion : pour du texte

<label for="language">
  Quel est le meilleur langage de programmation ?
</label>
<input id="language" type="text" list="languages">
<datalist id="languages">
  <option>HTML</option>
  <option>CSS</option>
  <option>SVG</option>
</datalist>
            
          

Exemple de suggestion : pour une couleur

<label for="color">
  Vous mettrez bien un peu de couleur ?
</label>
<input id="color" type="color" list="colors">
<datalist id="colors">
  <option value="#ff00dd">
  <option value="#991111">
  <option value="#bada55">
</datalist>
            
          

Accessibilité et compatibilité

Compatibilité

Le support de datalist est très bon, avec une nuance pour Firefox qui ne supporte que le type="text".

Vous pouvez tester les différents types de champs sur cette page de démonstration, réalisée par Eiji Kitamura.

Accessibilité

Le support par les technologies d’assistance est excellent — avec une limite : pas d’annonce lorsque la liste de suggestions est modifiée. Dans ce cas, il faudra recourir à une live region ARIA pour restituer le changement.

Auto-remplissage

Votre formulaire demande des données personnelles relatives à l’identité, l’adresse ou encore une carte de crédit ?

Attendez un peu avant de dégainer une bibliothèque JavaScript pour « faciliter » la saisie à coup de masques ou de déduction — voire d’appels API : l’utilisateur — et son navigateur — ont déjà l’information.

Exemple d’auto-remplissage

<input type="password" autocomplete="new-password">
<input type="email" autocomplete="email">
<input autocomplete="one-time-code">
            
          

Compatibilité et accessibilité

Compatibilité

Le support d’autocomplete est excellent — même si les navigateurs n’implémentent que partiellement la valeur off (volontairement).

Accessibilité

Non seulement autocomplete est pleinement accessible, mais est même requis par le critère 1.3.5 des WCAG 2.1 et le critère 11.13 du RGAA 4.1.

Formater la saisie

Vous n’autorisez que certains caractères, ou avez besoin de normaliser les valeurs ?

Traiter la valeur fournie après soumission génère du risque et engendre un décalage malvenu — « Bonjour Ga%c3%abl ».

Des écouteurs d’événements pour annuler la saisie si elle ne nous convient pas n’est pas une meilleure expérience pour l’utilisateur, causant des comportements inattendus.

Vous êtes-vous déjà demandé comment étaient restitués des masques de saisie, sur un lecteur d’écran ?

HTML à la rescousse !

Exemple de gestion du format

<label for="pattern">
  Mot de passe
  <small>(obligatoire)</small>
</label>
<input id="pattern" type="password"
  required
  pattern="[a-z]{4,8}"
  spellcheck="false"
  autocorrect="off"
  autocapitalize="none">
            
          

Votre mot de passe doit contenir quatre à huit minuscules uniquement.

Accessibilité

L’attribut pattern n’est pas restitué par les technologies d’assistance : il est donc de bon aloi de mentionner les contraintes avant la soumission du formulaire, à l’aide d’un passage de texte visible — mais également de fournir un exemple de saisie correcte, en cas d’erreur.

Sécurité

L’attribut spellcheck="false" est utile pour désactiver la vérification de l’orthographe — ce qui a pour effet secondaire de ne pas exfiltrer la saisie de l’utilisateur pour « vérification ».

Note : vous connaissez l’API HTML de validation des contraintes ?

D’autres bonus pour formulaires

De nombreux autres attributs sont drôlement pratiques — certains récents, et d’autres… non :

Stéphanie Walter a publié un guide extrêmement complet pour aider vos utilisateurs à remplir vos formulaires, sur Smashing Magazine , et Alex Holacheck a créé un configurateur de champs de formulaires pour mobile.

Un bloc dépliant

Un contenu supplémentaire à afficher, caché derrière un bouton ?

Vous pouvez implémenter le motif de conception ARIA disclosure, évidemment — mais nous avons déjà parlé de la première règle d’ARIA !

Exemple de bloc dépliant

<details>
  <summary>Découvrez mes secrets…</summary>
  Hé, à quoi vous vous attendiez !
</details>
            
          
Découvrez mes secrets… Hé, à quoi vous vous attendiez !

Accessibilité

L’implémentation par les différents navigateurs est complète et le support par les technologies d’assistance est excellent. Alors pourquoi faire un slide dédié ?

Adrian Roselli a explicité les détournements de details potentiellement inaccessibles — en résumé, details n’est pas : un accordéon, un onglet, un menu de navigation, une fenêtre de dialogue

Les principaux défauts sont l’impossibilité de mettre un titre dans un summary (ce dernier ayant un role="button" implicite) et l’absence de gestion d’Échap pour fermer le détail — mais est une fondation solide pour de l’amélioration progressive.

Il reste quelques disparités entre navigateurs et technologies d’assistance : Scott O’Hara détaille tout dans The details and summary elements, again.

Une fenêtre modale

Vous devez exiger une interaction de l’utilisateur, pour confirmer une action ?

Vous me voyez venir : pourquoi utiliser du JavaScript ?

Exemple de fenêtre modale

<dialog id="dialog">
<form method="dialog">
    <p>Bonjour, fenêtre !</p>
    <button>OK</button>
  </form>
</dialog>
<button onclick="dialog.showModal()">Aérer</button>
<!-- → Ouvrir la fenêtre -->
            
          

Bonjour, fenêtre !

Compatibilité et accessibilité

Compatibilité

Le support navigateur est quelque peu récent :

Mais pour la note positive, sachez que le support de dialog fait partie d’Interop 2022.

Accessibilité

Scott O'Hara a fait le point sur l’accessibilité de dialog et Kitty Giraudel liste les défauts restants dans la doc de son (excellente) bibliothèque a11y-dialog.

Afficher un résultat

Mettre à jour un total dans un panier ou un tableau, ou ajuster le résultat d’un calcul après un changement de paramètre ?

Encore une fois, HTML est là pour vous aider !

Exemple d’output

<fieldset>
  <legend>Addition</legend>
  <p>
    <label for="un">Chiffre</label>
    <input id="un" type="number" value="0"/>
  </p>
  <p>
    <label for="deux">Autre chiffre</label>
    <input id="deux" type="number" value="0"/>
  <p>
  <output id="resultat" for="un deux" role="status"></output>
</fieldset>
            
          
Addition

Compatibilité et accessibilité

Compatibilité

output est très bien supporté par les navigateurs et est bien exposé aux technologies d’assistance.

Accessibilité

Il y a tout de même quelques questionnements à avoir sur l’utilisation d’output. Scott O’Hara a rédigé un article détaillé sur l’accessibilité de l’élément output  — en résumé, pensez à expliciter le role="status".

Mettre une colonne en avant

Un tableau de données peut rapidement devenir illisible : mettre en avant une donnée peut s’avérer crucial pour l’utilisateur.

Manuel Matuzovic a partagé une technique de mise en avant de colonne de tableau sur son blog , basée sur HTML et CSS — notamment :target.

Certains superpouvoirs de HTML ont besoin de CSS pour devenir visibles.

Exemple de colonne mise en avant

<table>
  <caption>Tableau bidon</caption>
  <colgroup>
    <col id="col-un">
  </colgroup>
  <thead>
    <tr>
      <th scope="col"><a href="#col-un">Un</a></th>
    </tr>
  </thead>
</table>
            
          
Tableau bidon
Un Deux Trois
Un truc Deux trucs Et non !

Exemple de ligne mise en avant

<table>
  <caption>Tableau bidon 2, le retour</caption>
  <tbody>
    <tr id="row-un">
      <th scope="row"><a href="#row-un">Un truc</a></th>
    </tr>
  </tbody>
</table>
            
          
Tableau bidon 2, le retour
Un truc Un autre truc Un machin !
Deux trucs Encore un truc Un bidule !
Trois trucs Un nouveau truc Une chose !

Du live coding grâce à contenteditable

Vous montrez du CSS et voulez faire une démonstration interactive ?

Stephanie Eckles partage une solution outrageusement simple pour implémenter de la modification en direct, en HTML .

L’aperçu en direct ne fonctionne qu’avec CSS, mais on peut saupoudrer un peu de JavaScript pour gérer le HTML !

Exemple de live coding

container

Compatibilité

Le support navigateur est excellent.

Mais… pourquoi ?

Cet attribut est la porte ouverte à tout un tas d’idées saugrenues, dont mon exemple favori est Awfice, une suite bureautique minimaliste.

Un exemple ? Voici le bloc-notes : data:text/html,<html contenteditable>.

C’est aussi un socle d’amélioration progressive pour wyg ou Quill, des éditeurs wysiwyg légers et viables.

Cela dit, modifier in situ est amusant, mais non persistant. Comment faire pour enregistrer les modifications ?

Stocker, exporter et importer du JSON

<a href="data:text/json,…" download="export.json">Exporter</a>
<form>
  <p>
    <label for="import">Importer</label>
    <input id="import" type="file" accept="json"/>
  </p>
</form>
            
          
Exporter

Mais… il y a du JavaScript !

Oui, très exactement 22 lignes pour cette démonstration — sans minification.

On s’appuie sur trois mécaniques très simples :

  1. localStorage pour gérer les données : setItem et removeItem ;
  2. l’objet global JSON : les méthodes stringify et parse ;
  3. l’API FileReader pour interpréter le fichier au téléversement.

Sur les 22 lignes, 6 sont dédiées uniquement à la démonstration et non nécessaires à la fonctionnalité.

D’autres nouveautés

J’ai pas eu le temps de faire les démos !

Et les perfs

Merci

Et à bientôt

Crédits