# Défilement horizontal ergonomique des tableaux (#82) ## Problème Les tableaux de données (`DataTable` Dash) sont souvent plus larges que l'écran et **débordent vers la droite**. Aujourd'hui aucun `overflowX` n'est défini sur leur conteneur : le tableau étire la page entière, et le seul moyen de faire défiler horizontalement est la **barre de défilement de la fenêtre du navigateur**, tout en bas du viewport. Cette barre : - est discrète et fait défiler **toute la page** (pas seulement le tableau) ; - n'est pas comprise comme « le moyen de voir le reste du tableau ». De plus, les tableaux dépassent souvent du bas de l'écran : une barre placée en bas du tableau serait invisible sans scroller. ## Objectif Rendre le défilement horizontal **évident et toujours accessible**, et garder les **en-têtes de colonnes visibles** pendant le défilement vertical, sans introduire de zone scrollable imbriquée gênante. ## Approche retenue (option B — sticky au niveau page) Le tableau **reste dans le flux de la page** (pas de conteneur à hauteur fixe, pas de scroll imbriqué). On combine deux mécanismes : 1. **En-têtes collants** — `position: sticky; top: 0` sur la ligne d'en-tête du tableau. Quand l'utilisateur descend dans la page, les en-têtes se figent en haut de la fenêtre au lieu d'être « avalés ». 2. **Barre de défilement horizontale miroir en haut** — un petit élément placé juste au-dessus du tableau, lui aussi `sticky` en haut, dont le défilement horizontal est **synchronisé** avec celui du tableau. Elle est donc toujours visible dès qu'on voit le haut du tableau, et pilote le défilement horizontal sans devoir descendre en bas du tableau. La barre miroir et les en-têtes collants se figent ensemble en haut de la fenêtre : l'utilisateur garde en permanence le repère des colonnes **et** le contrôle du défilement horizontal. ### Pourquoi pas l'option A (tableau « fenêtré » à hauteur fixe) Écartée volontairement : un conteneur à hauteur fixe avec scroll interne crée un **scroll imbriqué** (la molette agit d'abord sur le tableau, pas sur la page), source de confusion. L'option B garde un comportement de défilement vertical unique (celui de la page) ; seul le défilement horizontal est « custom ». ## Contrainte technique CSS à gérer Un conteneur en `overflow-x: auto` devient automatiquement un conteneur de défilement **vertical** (règle CSS : `overflow-y: visible` recalculé en `auto` dès que l'autre axe n'est pas `visible`), ce qui **casse** le `position: sticky; top: 0` des en-têtes par rapport à la page. Conséquences pour l'implémentation : - Le **défilement horizontal réel** doit se faire dans un conteneur dédié en `overflow-x: auto` ; mais ce conteneur ne peut pas, en même temps, héberger des en-têtes sticky « page ». La barre miroir du haut résout ce conflit : c'est **elle** qui porte le `overflow-x: auto`, séparée du tableau, et synchronisée par JS. - Il faudra **vérifier et neutraliser au besoin l'`overflow` interne** que Dash DataTable applique à ses propres conteneurs (`.dash-spreadsheet-container`, `.dash-spreadsheet-inner`) pour que le sticky des en-têtes fonctionne. - Le rendu réel de Dash DataTable doit être inspecté avant de figer le CSS : la structure DOM exacte (où poser `sticky`, quel élément porte la largeur totale) conditionne la solution. **À valider en testant dans le navigateur.** ## Composants | Élément | Rôle | Emplacement probable | | --------------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | CSS en-têtes sticky | `position: sticky; top: 0` sur la ligne d'en-tête, z-index, fond opaque | `src/assets/css/style.css` (cible `.marches_table`) | | Barre miroir (markup) | `