4 points par GN⁺ 2024-02-25 | 1 commentaires | Partager sur WhatsApp
  • Dans les tableaux comportant de nombreuses lignes, plus on fait défiler, plus il devient facile d’oublier le sens des colonnes, ce qui rend la lecture des données moins pratique
  • Il suffit d’ajouter position: sticky; et top: 0; à thead pour mettre en place un en-tête fixe
  • sticky bénéficie d’une prise en charge par environ 96 % des navigateurs dans le monde, ce n’est donc pas vraiment une fonctionnalité expérimentale
  • Même lorsqu’on consulte des lignes plus bas, comme le 300e élément, les titres de colonnes restent visibles, ce qui améliore l’expérience de navigation dans le tableau
  • La mise en œuvre est minime mais l’effet est important ; pour une page web qui propose de longs tableaux, cela mérite d’être appliqué comme amélioration de base de l’utilisabilité

Le problème des en-têtes qui disparaissent dans les longs tableaux

  • Dans les grands jeux de données ou les tableaux de plusieurs centaines de lignes, après défilement, l’en-tête du tableau disparaît hors de l’écran
  • Si l’on descend jusqu’au 300e élément, il peut devenir difficile de vérifier à nouveau ce que signifient les données de chaque colonne
  • Plus un tableau est nouveau pour l’utilisateur, plus il doit garder en mémoire le sens des colonnes pendant sa lecture, ce qui alourdit la navigation

Appliquer sticky à thead

  • La solution consiste à ajouter deux propriétés CSS à thead
position: sticky;
top: 0;
  • En utilisant ensemble position: sticky et top: 0, l’en-tête peut être fixé en haut de l’écran pendant le défilement
  • sticky dispose d’un taux de prise en charge mondial d’environ 96 %, ce qui permet de l’utiliser dans de nombreux navigateurs
  • Le comportement réel peut être vérifié dans l’exemple CodePen

1 commentaires

 
GN⁺ 2024-02-25
Avis sur Hacker News
  • Je veux bien admettre les en-têtes fixes sur un axe, mais j’attends encore le jour où CSS les prendra en charge sur les deux axes : https://github.com/w3c/csswg-drafts/issues/8286

    • L’une des missions les plus difficiles que j’aie eues consistait à figer à la fois des colonnes et des en-têtes. Avec une table standard, c’est facile, mais là c’était une table dynamique tierce VueJS complexe qui utilisait du CSS-as-JS généré ; il m’a fallu longtemps rien que pour comprendre d’où venaient le CSS et le JS, et j’ai fini par devoir surcharger des fonctions de classes JS et le CSS généré. J’étais désolé auprès du client que ça prenne autant de temps, et ça m’a rendu beaucoup plus prudent dans le choix de bibliothèques pour des bases de code Vue/React. Les tables sont des éléments HTML de base ; je ne comprends pas pourquoi une opération simple nécessite trois couches de classes JS et du CSS importé en JSON.
    • Je suis probablement depuis 8 ans l’issue d’origine qui a engendré celle-ci, et c’est l’une des parties les plus agaçantes de la spécification CSS. Parfois, on a besoin d’un énorme tableau de données, et on veut garder le haut fixe tout en utilisant overflow-x: auto, mais on nous dit de choisir l’un ou l’autre.
  • J’avoue que je connais très peu CSS, mais je construis quand même des applis web qui fonctionnent à peu près. Récemment, j’ai essayé de figer l’en-tête d’un tableau monstre d’environ 20 000 lignes : https://www.datasciencemeta.com/rpackages Au début, je m’attendais à trouver quelque chose comme class="table table-header-sticky" dans les classes de table Bootstrap, mais il n’y avait rien ; après une vingtaine de minutes à bricoler des suggestions de Stack Overflow, GPT et CodePen, j’obtenais des effets de bord bizarres. Mais avec le CodePen de cet article, ça a fonctionné en 2 minutes, et je suis en train de le déployer en production.

  • Figer l’en-tête d’un tableau semble simple avec un seul position: sticky;, mais dès qu’on commence à ajouter quelque chose au contenu du tableau, ça se complique vite. Sur un tableau avec en-tête fixe, j’avais ajouté une fonctionnalité qui, lorsque l’utilisateur fait défiler le corps puis quitte la page, enregistre l’index de la première ligne visible et le restaure à son retour ; mais la restauration se faisait toujours environ une ligne trop bas. En fait, la ligne 5 était bien tout en haut du tableau, mais comme thead la recouvrait, la ligne 6 semblait être la première. J’ai donc ajusté la position de défilement en tenant compte de la hauteur de thead, mais il y avait parfois quelques pixels de décalage ; comme le tableau était grand, avec du chargement différé sur les événements de scroll et la mise en page automatique par défaut des tableaux, les cellules d’en-tête passaient à la ligne et la hauteur totale de l’en-tête changeait. Au final, j’ai attaché un ResizeObserver à thead pour ajuster dynamiquement la position de défilement quand sa hauteur changeait. [1] https://developer.mozilla.org/en-US/docs/Web/API/ResizeObser...

  • En implémentant ça, si vous voulez que la bordure de l’en-tête reste elle aussi fixe, vous pouvez le faire en mettant position: absolute, width: 100%, top: 0/bottom: 0, border-top/border-bottom sur table thead:before et table thead:after.

  • J’aimerais que les en-têtes de tableau se comportent automatiquement comme ça. Si un développeur a pris la peine d’utiliser les balises correspondantes et d’ajouter du travail, il y a de fortes chances que ce soit déjà le comportement souhaité.

    • Il suffit d’installer une extension de navigateur capable de charger une feuille de style personnalisée sur toutes les pages. Cela dit, de nos jours, de plus en plus de sites construisent des tableaux avec 500 au lieu de et 45 niveaux de `` imbriqués dans chacun d’eux, donc je doute que ça fonctionne sur ces sites.
    • Ce genre de changement semble très susceptible de casser des choses de manière inattendue. La raison principale est sans doute qu’avant l’arrivée de CSS Grid, beaucoup de sites utilisaient des tableaux pour faire des mises en page en grille. Si l’en-tête devient fixe, ces mises en page peuvent se casser. Le grand échec de la sémantique HTML, c’est que les tables ont été perçues non pas comme « une manière d’afficher des données tabulaires », mais comme « une grille arbitraire d’éléments ».
  • En ligne de commande, il suffit d’envoyer l’en-tête vers stderr et le corps vers stdout. Sinon, le résultat de heights | sort -k2 -nr sera dans l’ordre George 186, Wally 173, NAME HEIGHT, mais si l’en-tête contourne stdout, on obtient NAME HEIGHT, George 186, Wally 173.

    • heights | (sed -u 1q; sort -k2 -nr) fonctionne correctement. Source : https://stackoverflow.com/a/56151840
    • Si on écrit dans un fichier, il faut essayer encore quelques variantes et avoir une meilleure compréhension du shell. C’est une limite persistante du modèle texte in-band uniquement, mais détourner STDERR de cette façon me semble plus source de confusion qu’utile. Si heights est un fichier, on peut faire % head -1 heights ; sed 1,1d heights | sort -k2 -nr, et si heights est un exécutable coûteux à lancer deux fois, on peut faire % heights > /tmp/heights ; head -1 /tmp/heights ; sed 1,1d /tmp/heights | sort -k2 -nr. On peut aussi le passer à awk. Les autres options sont moins pratiques, mais moins surprenantes, et elles fonctionnent même si l’auteur de l’exécutable avait une autre idée en tête.
    • Qu’est-ce qui serait mieux ici ? Envoyer l’en-tête vers stderr, ou n’afficher l’en-tête que lorsque stdout est un TTY ?
  • Ça n’a pas fonctionné pendant longtemps. Chrome avait auparavant désactivé position: sticky sur les éléments thead et tr : https://issues.chromium.org/issues/41303743 Je me souviens que les tableaux de compatibilité des navigateurs étaient presque entièrement verts, mais que ça ne marchait justement pas dans les tables de Chrome.

    • C’est surprenant que ce soit devenu aussi simple maintenant. Quand j’en avais eu besoin à l’époque, il fallait mettre tout un tas de bricolages dans le HTML et le CSS pour que ça marche selon les navigateurs. Mais ce n’était pas vraiment surprenant non plus, parce que le développement web fonctionne généralement comme ça.
  • Il y a aussi un point de vue qui consisterait plutôt à dire « pitié, ne faites pas ça » : https://news.ycombinator.com/item?id=32998091

    • Pour une page web classique, je suis entièrement d’accord. Comme c’est plus rapide que d’écrire un style Stylus, je supprime souvent les éléments fixes avec uBlock Origin, et des styles génériques appliqués à tout le site fonctionnent assez bien. Mais l’article d’origine parle d’un tableau de données avec colonnes d’en-tête fixes, donc cette proposition est en fait assez utile.
    • Ça concerne les en-têtes fixes de toute une page web. Dans un tableau, c’est complètement différent. Je déteste vraiment regarder un tableau avec une douzaine de colonnes numériques et, dès qu’on fait défiler un peu vers le bas, ne plus savoir ce qui correspond à quoi.
    • Qu’y a-t-il de mal avec la propriété sticky ?
  • Le CodePen rend mieux si on décale top de l’épaisseur de la bordure. Par exemple, en mettant -1px au lieu de 0, on évite que le corps du tableau transparaisse au-dessus de l’en-tête. Comparaison : https://codepen.io/bradleytaunt/pen/bGZyJBj Version modifiée : https://codepen.io/alokmenghrajani/pen/ExMBQow

  • Je suggère d’utiliser une hauteur de viewport limitée à la place d’un en-tête fixe, afin que l’en-tête soit toujours visible. On peut faire comme DataGridXL(https://datagridxl.com). À noter : c’est moi qui l’ai créé.

    • Simple réflexion, mais cette approche est très difficile à naviguer sans dispositif de pointage, par exemple uniquement au clavier.
    • Ce n’est pas une critique, mais je n’ai jamais aimé cette approche sur mobile. Je pense que le contenu devrait défiler avec la page.