Vous n’avez pas besoin de JavaScript pour ça
(htmhell.dev)- Pour implémenter une fonctionnalité web, il est préférable d’examiner d’abord les technologies les moins puissantes dans l’ordre HTML, CSS, JavaScript, afin de réduire les échecs de chargement et les problèmes d’accessibilité
- JavaScript permet de contrôler directement le comportement du navigateur, mais à cause des ressources supplémentaires requises et des risques d’erreur, il tend aussi à exclure plus facilement les utilisateurs au clavier et des technologies d’assistance
- Des fonctionnalités qui nécessitaient autrefois JavaScript, comme les interrupteurs à base de cases à cocher,
datalist,input type="color",details/summaryoudialog, sont désormais en grande partie possibles avec les fonctionnalités natives de HTML/CSS - Les fonctionnalités déclaratives de HTML et CSS permettent au navigateur de prendre en charge le comportement natif, les préférences utilisateur et l’accessibilité, ce qui offre de meilleurs réglages par défaut
- Même si une implémentation JavaScript familière continue de fonctionner, il faut vérifier régulièrement les alternatives modernes en HTML/CSS et, lors d’un remplacement, effectuer aussi des tests d’accessibilité
Règle du moindre pouvoir
- La règle du moindre pouvoir est un principe du développement web qui consiste à choisir le langage le moins puissant capable d’atteindre l’objectif
- Sur le web, cela s’applique généralement en envisageant d’abord HTML avant CSS, puis CSS avant JavaScript
- JavaScript est la plus polyvalente des trois technologies, mais c’est aussi la plus coûteuse
- Elle peut casser
- Elle peut échouer au chargement
- Elle exige des ressources supplémentaires pour le téléchargement, le parsing et l’exécution
- Elle peut facilement exclure les utilisateurs au clavier et ceux des technologies d’assistance
- HTML et CSS fonctionnent de manière déclarative, contrairement à JavaScript impératif
- Le développeur indique au navigateur ce qu’il veut, et le navigateur choisit comment l’implémenter
- Le navigateur peut choisir un mode de traitement plus efficace
- Quand le navigateur prend en charge une fonctionnalité HTML/CSS, cela peut être avantageux en matière de performances, de comportement natif, de prise en compte des préférences utilisateur et d’accessibilité
- Cela ne garantit toutefois pas automatiquement l’accessibilité dans tous les cas
Des fonctionnalités qui nécessitaient autrefois JavaScript
- Les fabricants de navigateurs et les rédacteurs de spécifications ont progressivement déplacé vers CSS et HTML des fonctionnalités qui demandaient encore JavaScript il y a quelques années
- Le web conserve la rétrocompatibilité, donc une méthode d’implémentation apprise une fois a tendance à rester dans la boîte à outils et à être réutilisée
- Même si vous pensez qu’une fonctionnalité nécessite JavaScript, vérifier de temps en temps si c’est toujours vrai permet de créer de meilleurs sites web
Un interrupteur personnalisé construit avec une case à cocher
- Un interrupteur personnalisé peut être implémenté avec une case à cocher native et du CSS, au lieu d’un
div, d’un gestionnaireonclicket d’un état interne - En plaçant
<input type="checkbox">dans un<label>, le navigateur associe automatiquement les deux- Un clic n’importe où sur le libellé bascule la case à cocher
- Aucun gestionnaire
onclickséparé n’est nécessaire
appearance: nonedésactive le rendu natif du contrôle de formulaire du navigateur pour permettre un style personnalisé- On peut styliser directement l’
inputcomme arrière-plan de l’interrupteur ::beforepeut servir de point interne qui se déplace lors du basculement
- On peut styliser directement l’
- La pseudo-classe
:checkedpermet de modifier la couleur de fond et la position de::beforeselon l’état coché - Une indication de focus est nécessaire pour les utilisateurs au clavier
- Masquer le focus avec
outline: nonen’est pas une bonne pratique :focus-visiblepermet d’afficher un anneau de focus élégant uniquement lors d’une interaction au clavieroutline-offsetpermet d’ajuster le contour de focus à l’extérieur ou à l’intérieur de l’élément
- Masquer le focus avec
input:focus { outline-color: transparent; }peut rendre le contour transparent en situation normale, tout en le laissant réapparaître avec la couleur choisie par l’utilisateur en mode contraste forcé- Vous pouvez en savoir plus sur le mode couleurs forcées dans forced colors explained
Autocomplétion native avec datalist
datalistest une fonctionnalité native du navigateur de suggestion automatique qui affiche une liste d’options pendant que l’utilisateur saisit du texte- La structure est simple
- On place un
idet plusieursoptiondans l’élémentdatalist - On l’associe à l’
inputvia l’attributlist
- On place un
- Quand l’utilisateur saisit, le navigateur affiche une liste déroulante et filtre automatiquement les options selon la saisie
- Comme il s’agit d’un champ de saisie standard, l’utilisateur peut aussi entrer directement une valeur absente de la liste
- Après avoir sélectionné le champ, il est possible de parcourir la liste avec les touches fléchées, ou de voir toutes les options en cliquant sur l’icône de liste déroulante ajoutée par le navigateur
Le sélecteur de couleur natif de input type="color"
- Une seule ligne avec
<input type="color">permet d’utiliser le sélecteur de couleur natif du navigateur - Cela peut remplacer de nombreuses interfaces en canvas et curseurs construits en JavaScript
- Le sélecteur de couleur natif des navigateurs Chromium permet de choisir une couleur non seulement dans le site, mais aussi n’importe où à l’écran
- Comme tous les utilisateurs ne peuvent pas forcément utiliser le sélecteur de couleur du navigateur, il est préférable de proposer aussi une autre manière de choisir une couleur, par exemple via une saisie texte classique
Un accordéon avec details et summary
- Les éléments
detailsetsummaryfournissent nativement dans le navigateur un accordéon pour replier et déplier du contenu - Le comportement par défaut est simple
- Le contenu dans
details, à l’exception desummary, est masqué - Quand l’utilisateur clique sur
summary, le reste du contenu s’affiche
- Le contenu dans
- L’attribut
opendéfinit l’état initial ouvert- Ce n’est pas une valeur figée après interaction : l’état change quand l’utilisateur ouvre ou ferme l’élément
summary::markerpermet de styliser le marqueur triangulaire par défaut- Son contenu peut être remplacé par un emoji, par exemple
- On peut ajuster la couleur de fond, l’image de fond, la taille de police, etc.
- De nombreuses propriétés CSS ne fonctionnent pas, et le style reste limité pour des repositionnements complètement différents
- Dans Safari, le pseudo-élément
::-webkit-details-markerest nécessaire - Modifier le contenu du marqueur peut influer sur la manière dont les technologies d’assistance annoncent l’accordéon ; vous pouvez consulter details/summary inconsistencies
summaryest cliquable, mais n’affiche pas par défaut un curseur de pointeur comme un lien et ne ressemble pas non plus à un bouton ; il faut donc ajouter des états hover et focus pour signaler qu’il est interactif
Une modale avec dialog
alert(),prompt()etconfirm()permettent d’informer l’utilisateur ou de lui demander une confirmation, mais ils bloquent le thread principal et sont difficiles à styliser selon le design souhaité- Construire soi-même une boîte de dialogue rend l’accessibilité complexe
- Il faut maintenir le focus à l’intérieur de la boîte de dialogue
- Il faut indiquer qu’elle est modale
- Il faut empêcher l’utilisateur d’en sortir par erreur
- Elle peut entrer en conflit avec des widgets ayant un
z-indextrès élevé
- L’élément
dialogdu navigateur fournit une boîte de dialogue native - À l’heure actuelle, JavaScript reste nécessaire pour ouvrir la boîte de dialogue
- Une évolution permettant de l’ouvrir sans JavaScript est en cours, mais n’est pas encore entièrement spécifiée ni implémentée
- La fonction
showModal()permet d’ouvrir la boîte de dialogue
dialogs’ouvre dans la top layer- La top layer est une nouvelle couche séparée du HTML
- Les éléments dans cette couche s’affichent toujours au-dessus, indépendamment du
z-indexet de l’imbrication des contextes d’empilement - Pour comprendre ce concept, vous pouvez consulter Top layer sur MDN
dialogne fournit pas d’interface de fermeture par défaut, il faut donc l’ajouter soi-même- Quand un
form method="dialog"est soumis, le navigateur ferme la boîte de dialogue - En donnant des
valuedifférentes à deux boutons de soumission, on peut l’utiliser comme une boîte de confirmation - Dans l’événement
close, on peut liredialog.returnValuepour savoir sur quel bouton l’utilisateur a cliqué - Les données de formulaire supplémentaires peuvent être lues avec FormData
- Quand un
dialog::backdropest la couche située entre la boîte de dialogue et le reste de la page- On peut assombrir ou flouter l’arrière-plan pour attirer l’attention de l’utilisateur sur la boîte de dialogue
- Comme c’est le navigateur qui gère son placement, il n’est pas nécessaire de gérer soi-même le défilement, les éléments fixes ou les changements de taille de la fenêtre
D’autres fonctionnalités possibles avec moins de JavaScript
- Il existe encore beaucoup d’autres fonctionnalités pour lesquelles on peut réduire l’usage de JavaScript
- Le défilement fluide natif avec
scroll-behavior: smooth- À utiliser uniquement sous condition quand
prefers-reduced-motion: no preferenceest respecté
- À utiliser uniquement sous condition quand
- Les carrousels natifs avec
scroll-snap - Les éléments “in-view” avec
position: sticky - Les container queries
- Le défilement fluide natif avec
- D’autres fonctionnalités sont aussi à venir
- Les animations basées sur le défilement
- Une mise en page Masonry avec
grid-template-rows: masonrysansmasonry.js - Un
selectentièrement stylisable via le nouvel élémentselectlist - Le sélecteur
:has()qui peut réduire toute une catégorie de code de sélection en JavaScript
- Vous pouvez en voir davantage dans la vidéo de présentation Stop Using JavaScript for That: Moving Features from JS to CSS and HTML.
- Lorsque vous remplacez une implémentation existante et éprouvée par une nouvelle approche, il faut particulièrement tester l’accessibilité pour n’exclure personne
1 commentaires
Commentaires Hacker News
Ce qui manque dans cet article, c’est que la raison d’utiliser JavaScript dans ce genre de cas est une meilleure compatibilité.
Le JavaScript récent peut être transpilé, mais polyfiller des fonctionnalités CSS ou HTML manquantes est bien plus difficile, voire impossible dans certains cas. Et ces polyfills finissent de toute façon par utiliser JavaScript.
appearances’accompagne aussi sur MDN de nombreux avertissements recommandant de tester rigoureusement, même pourappearance: none. Si vous ne ciblez que les navigateurs récents, c’est peut-être moins important, mais les anciennes versions de Safari restent en circulation plus longtemps qu’on ne le pense.datalistne fait absolument rien sur Firefox Android, et chez moi cela ressemble juste à un champ de saisie sans même des suggestions.Le sélecteur de couleur est sympa, mais il est extrêmement peu standardisé, ce qui est rédhibitoire pour la plupart des entreprises. Ce ne sont pas seulement les designers qui vont se plaindre : le support client aura aussi du mal à aider les utilisateurs. Chromium permet même de prélever une couleur sur la page ou d’en choisir une arbitraire, alors que Firefox Android ne propose guère qu’un arc-en-ciel, des gris et du noir et blanc.
L’article lui-même reconnaît aussi les incohérences de
detailsetdialog. J’espère qu’un jour les navigateurs qui ne prennent pas en charge ces fonctionnalités, ou qui le font de manière incohérente, ne seront plus utilisés, mais pour l’instant j’ai l’impression que ces éléments ne servent que dans des side projects où l’on contrôle totalement les navigateurs pris en charge.Sur iPhone, quand on appuie sur le bouton, c’est le véritable sélecteur de couleur natif du système qui apparaît. C’est exactement le contrôle fourni par l’OS et visible dans plusieurs apps, et je le préfère largement à une version personnalisée.
Je préfère de loin un web sans JavaScript, et cela peut même jouer sur l’autonomie d’un ordinateur portable à l’échelle de plusieurs heures. Certains sites sont incompatibles avec cela et n’affichent qu’une page vide, ou se plaignent qu’il faut JavaScript pour voir du texte.
À l’inverse, Amazon a aussi une version miroir de son site e-commerce sans JavaScript, ce qui montre qu’une opération aussi énorme peut fonctionner sans JavaScript.
dialoga désormais une prise en charge assez large, et même un polyfill pour les quelques pourcents d’utilisateurs encore sur Firefox ou Safari des années 2021 est tout à fait acceptable.Si vous créez une modale, je le recommande vivement, et les améliorations en accessibilité sont excellentes.
Dans mon ancien travail, on a discuté activement de ce problème et décidé d’utiliser une implémentation JS au lieu de choses comme
datalist. On a notamment essayédatalist, mais les résultats étaient trop incohérents et il a fallu l’abandonner.Au final, on a même cessé le support en dehors de Chrome à cause des différences entre navigateurs.
Les exemples HTML peuvent avoir un rendu incorrect sur les anciens navigateurs, mais le contenu réel reste là. Avec du JS, il n’y a tout simplement rien. Cela casse complètement l’accessibilité.
Avec du HTML, un lecteur d’écran peut au moins lire le contenu, mais du contenu généré en JS l’en empêche. Quand JS ne peut pas exécuter JS, aucun polyfill ni autre JS ne peut venir sauver JS. Il faut que cela « fonctionne » dès le départ pour que l’accessibilité soit correcte, et dans ce cas l’argument initial perd tout son sens.
Je ne connaissais pas
Datalist, mais au moins sur Chrome Android, ça ne semble pas vraiment fonctionner correctement.Les options apparaissent bien dans la zone du clavier où s’affichent les suggestions d’autocomplétion : https://imgur.com/a/Ecb4503
C’est la première fois que je vois des contrôles de formulaire d’UI web mobile fonctionner de cette manière, en dehors des cas où une app d’autocomplétion de mots de passe utilise le même espace.
Ce n’est pas mauvais. C’est bien mieux que de faire défiler maladroitement une liste déroulante JS personnalisée bricolée, mais je ne suis pas convaincu qu’un utilisateur ordinaire comprenne comment s’en servir. Du coup, sur mobile, je pense que c’est pratiquement sans espoir.
Sur Firefox Android, ce n’est tout simplement pas pris en charge : https://caniuse.com/?search=datalist
datalist?Référence : https://adrianroselli.com/2023/06/under-engineered-comboboxe...
JavaScript est plutôt bien standardisé, mais HTML et CSS le sont relativement moins.
autocomplete="off"à l’élémentinputchange le comportement.En tout cas, c’est nécessaire pour utiliser
datalistcorrectement. Sinon, l’historique des valeurs sélectionnées vient s’ajouter à la liste déroulante. Observé dans Chromium.De plus, dans certaines situations, par exemple lorsqu’une valeur par défaut est définie,
datalistnécessite encore du JS. J’ai rassemblé des contournements et des notes sur des comportements spécifiques aux navigateurs dans le code du nouveau site web de LibreOffice : https://git.libreoffice.org/infra/libreofficeorg/+/835a5cc59...La bonne nouvelle, c’est que des développeurs Firefox prévoient d’examiner des améliorations du comportement de
datalist, ce qui pourrait permettre d’afficher la liste en un seul clic.Chez moi, les options apparaissent généralement dans la zone au-dessus du clavier où s’affichent normalement les suggestions de mots.
datalistapparaissent dans le clavier est un changement apparu ces derniers mois.Avant, c’était « normal », mais on dirait que quelqu’un a voulu changer quelque chose juste pour le principe.
Il faut vraiment limiter l’usage de
scroll-behavior: smoothpour le défilement fluide natifCe n’est pas une bonne idée dans la plupart des cas d’usage, plus souvent qu’on ne le pense, et cela provoque fréquemment des effets de bord indésirables
On peut certes créer des carrousels natifs avec
scroll-snap, mais les carrousels restent une mauvaise idée, donc le champ d’application légitime descroll-snapreste extrêmement limitéLes pages qui utilisent des animations basées sur le défilement sont généralement meilleures si on les supprime
Le défilement fluide en est un bon exemple. L’API native permet à l’utilisateur de l’interrompre à tout moment. La plupart des implémentations JS saccadent affreusement et font souffrir l’utilisateur
On peut critiquer autant qu’on veut les choix de design, mais il est difficile d’espérer être écouté si l’on ne donne pas de vraies raisons pour lesquelles « les carrousels restent mauvais »
Mais la page d’accueil d’Amazon utilise visiblement des carrousels, et Amazon est réputé pour A/B tester sans pitié les variantes de sa page d’accueil. Dans ce cas, il est possible que les carrousels aient bien performé dans les tests, et il devient difficile d’affirmer qu’ils sont vraiment « mauvais » dans un sens universel et objectif
En général, j’en ajoute au moins juste après avoir implémenté des ancres façon table des matières
Il est surprenant qu’en 2023 on se dispute encore à propos des formulaires et de l’UX générale de la saisie de données par les utilisateurs
Il suffit de voir les commentaires sur
datalistet le sélecteur de couleur, et je ne comprends pas pourquoi ce domaine n’est toujours pas considéré comme résoluIl y a eu autrefois une tentative de tout régler d’un coup avec XForms, mais cela n’a jamais été implémenté dans les navigateurs
À la place, presque tous les frameworks de composants CSS/JS proposent chacun leur propre ensemble limité d’éléments de formulaire avec des sémantiques différentes
On dirait qu’on va passer notre vie à implémenter nous-mêmes les contrôles UI de base
Si cela semble « non résolu », c’est seulement parce que certaines personnes ont une étrange obsession à éviter JavaScript et essaient de forcer des alternatives à moitié abouties
Si on reste sur des techniques ennuyeuses et basiques, c’est déjà résolu. Mais si on insiste pour le résoudre à nouveau avec React, puis encore avec les React hooks, puis sans fin, alors cela devient forcément un problème non résolu
L’intention n’est pas quelque chose qu’on peut déterminer programmatiquement, donc dans certaines situations on ne peut pas avoir des fonctionnalités sophistiquées
Sur le dernier formulaire complexe sur lequel j’ai travaillé, il a fallu faire en sorte qu’un événement de clic déclenche la soumission du formulaire de manière assez directe pour que le navigateur l’autorise
Je n’ai jamais demandé un moyen de soumettre une couleur via une page web
Si on utilise
detailsau lieu de JavaScript, Ctrl+F peut rechercher à l’intérieur et ouvrir la sectionCe n’est pas possible avec un accordéon JavaScript
hidden="until-found", c’est aussi possible dans les accordéons basés sur JS ou d’autres contenus cachés, mais malheureusement cela n’existe pour l’instant que dans les navigateurs basés sur Chromium : https://developer.chrome.com/articles/hidden-until-found/Je suis d’accord avec l’essentiel, mais je n’ai pas assez utilisé
dialogpour avoir un avis, et je considère quedatalistn’est pas une option valable en dehors des outils internesC’est moche, ses possibilités sont limitées, et on ne peut pas le styliser. C’est le problème de la plupart des arguments du type « utilisez simplement les fonctions intégrées ». Même chose pour le
date pickerNon seulement le rendu par défaut laisse à désirer, mais on ne peut rien y changer même si on le souhaite. Dès qu’on se heurte à l’un des innombrables murs en voulant modifier le style ou le comportement — par exemple si l’on veut que la semaine commence le lundi — on n’a généralement plus d’autre choix qu’une bibliothèque de remplacement complète en JS
Je suis favorable aux options plus légères et d’accord avec la hiérarchie HTML > CSS > JS, mais si l’on veut à la fois une belle UI et les fonctionnalités souhaitées, JS est parfois la seule réponse
datalistpourrait être utileCela fonctionne bien jusqu’au moment où l’on veut afficher des options qui ne commencent pas strictement par ce qui a été saisi. Par exemple, s’il y a une faute de frappe dans la saisie, aucune option n’apparaît
Comme il n’y avait aucun moyen de forcer l’affichage de tous les éléments, j’ai fini par choisir une liste ordonnée
Quand j’ai commencé le développement web, chaque évolution pouvait prendre jusqu’à 10 ans. IE6 nous bloquait tous, et le W3C de l’époque n’était pas très influent non plus. Aujourd’hui, les changements vont plus vite
L’an prochain, il est possible que le style de
datalistsoit disponible sans préfixe dans les trois grands navigateurs, mais si l’on est prisonnier d’une solution JS sur mesure, l’entreprise ne paiera probablement pas les coûts de reconstructionSi l’on étend une fonctionnalité native avec du JS, on peut retirer ce JS à moindre coût quand le support devient suffisant. Là où les contrôles natifs sont acceptables, on peut les utiliser dès maintenant et appliquer le JS comme un polyfill
input[type=date], la plupart des personnalisations souvent demandées sont en réalité mieux laissées hors du contrôle du développeurLe calendrier approprié à afficher devrait être dépendant de la locale. La plateforme de l’utilisateur dispose déjà des capacités nécessaires pour le configurer et l’afficher de la manière qu’il a le plus de chances d’utiliser efficacement
Le sélecteur de date de la plateforme vaut mieux qu’une bizarrerie bricolée maison
Ce bouton de bascule est vraiment bien
On dirait que les développeurs frontend adeptes des mèmes s’énervent contre cet article, mais le fond est juste. Pourquoi autant de sites absurdes sont-ils faits en JS ? Si les gens suivaient un seul standard comme HTML, tout pourrait être cohérent, et des choses comme l’accessibilité ou la traduction seraient aussi plus faciles à gérer
Quand on visite des sites aujourd’hui, tout est chargé dynamiquement sur une seule page, au point que même le bouton retour ne fonctionne plus
Et il reste toujours le problème du « il faut attendre que les gens fassent les mises à jour », sachant qu’après l’introduction d’une nouvelle fonctionnalité, il peut falloir des années avant qu’elle soit suffisamment prise en charge pour être réellement utile
Je suis globalement d’accord sur le fait qu’il y a beaucoup de mauvaises implémentations et d’usines à gaz en JavaScript. Il existe déjà pas mal de solutions standardisées pour conserver le fonctionnement du bouton retour avec du contenu dynamique, et il me semble que les frameworks web populaires les prennent en charge par défaut
J’ai lu les premiers commentaires, mais je n’y vois pas grand-chose qui mérite d’être appelé de la colère ; je vois surtout des gens qui soulèvent des points valables sur la compatibilité navigateur
C’est un pas dans la bonne direction, mais le CSS est aussi un autre outil dont abusent les « artistes » dont parlait Philip Greenspun pour fabriquer des pages pénibles à lire
Je ne suis pas partisan de Gemini, mais fondamentalement, tous les aspects de la mise en page et de la typographie devraient revenir au navigateur et être sous le contrôle de l’utilisateur. Les designers ont montré sans fin qu’on ne peut pas leur faire confiance là-dessus
J’aime bien l’idée générale, le switch est élégant, et
summary/detailssont parfois utilesMais l’élément
datalistn’est pratiquement pas une option réaliste au-delà des gadgets ou des prototypesParmi les choses que j’aime bien dans la catégorie « assez bien en CSS sans JS », il y a les sidebars en tiroir et les carrousels
DaisyUI, une bibliothèque de composants TailwindCSS, propose aussi des composants prêts à l’emploi
https://daisyui.com/components/drawer/
https://daisyui.com/components/carousel/
Le tiroir et les autres contenus qui apparaissent sur la page doivent être annoncés, et il devrait y avoir un état
aria-expandedà côté du contrôle concernéC’est toujours une vraie question. Il existe peut-être une solution, ou peut-être que les développeurs estiment collectivement que ce n’est pas important. Les auditeurs accessibilité ne seraient sans doute pas d’accord
Les auteurs de ces frameworks semblent fortement sous-estimer la quantité de tests nécessaire pour que cela fonctionne réellement sur l’ensemble des navigateurs
Avec autant de composants, et en plus la possibilité de thèmes, il est difficile de garantir qu’on pourra corriger les problèmes sans casser les thèmes et applications existants
components/carousel/Au juste, qu’est-ce que le snap, et comment ça fonctionne ? Mon écran ne réagit pas aux clics du doigt
Un mode d’interaction inconnu n’est pas, à mon avis, un bon argument en faveur d’une bibliothèque de composants d’interface utilisateur