11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous.

Dans ma page HTML se trouve un tableau qui a environ 100 lignes et donc ne tient pas dans la hauteur de l'écran.
Cette table a un <thead> qui donc disparait lorsque l'on fait défiler la table.
Quelle est la meilleure façon de faire cela ?
On peut mettre un <thead> fictif dans un header en position fixed, mais la largeur des colonnes dépend de la "vraie" table et dont donc être ajustée.
Dans le passé, j'avais fait quelque chose de compliqué https://forum.alsacreations.com/topic-1-81647-1-Table-deroulante-avec-en-tete-fixe.html, avec création dynamique d'une feuille de style. Il doit y avoir quelque chose de plus simple.

Merci de votre aide.
Modifié par PapyJP (25 Mar 2024 - 12:31)
Effectivement ça semble une bien meilleure solution !
Je vais essayer ça.
Modifié par PapyJP (25 Mar 2024 - 21:55)
La technique du `position: sticky` fonctionne très bien, je l'utilise.

Malheureusement ce n'est pas compatible avec un `overflow-x: hidden` que l'on est susceptible d'utiliser sur un élément parent du tableau (afin de pouvoir le scroller horizontalement sur les petits écrans).

Et à ce sujet, si quelqu'un avait une solution sans hack JS je suis preneur. Un exemple de `position: sticky` annulé par un `overflow-x: hidden` (les deux premiers tableaux) : Tables.
Modifié par Olivier C (26 Mar 2024 - 10:35)
Rassures-moi, Olivier, la position sticky est par contre compatible avec overflow:scroll; ?
Parce que j'ai ça en place sur un site et ça fonctionne (je n'ai pas testé sur Safari).
@Bongota : il te suffit de tester pour savoir mais, oui, il y a là aussi - en principe - un problème de compatibilité.

Si ça fonctionne chez toi je veux bien que tu mettes un lien que je regarde comment tu t'y es pris.
Modifié par Olivier C (26 Mar 2024 - 10:42)
Modérateur
Olivier C a écrit :
La technique du `position: sticky` fonctionne très bien, je l'utilise.

Malheureusement ce n'est pas compatible avec un `overflow-x: hidden` que l'on est susceptible d'utiliser sur un élément parent du tableau (afin de pouvoir le scroller horizontalement sur les petits écrans).

Et à ce sujet, si quelqu'un avait une solution sans hack JS je suis preneur. Un exemple de `position: sticky` annulé par un `overflow-x: hidden` (les deux premiers tableaux) : Tables.


Bonjour, sur ton premier tableau , il y a overflow-x: auto et un max-height:80vh sur son parent. Le position:sticky fonctionne toujours , il se trouve appliqué dans , calculé depuis, ce conteneur.

En reduisantt la hauteur de ta fenêtre jusqu'au moment ou le tableau est plus haut que ces 80vh, les th restent bien scotchés dans ce conteneur qui montre alors une barre de défilement.

Ce serait comme vouloir affiché un tooltip en dehors d'un élément en overflow autre que visible. C'est le fonctionnement attendu. sticky s'accroche au plus proche parent défilant

https://developer.mozilla.org/fr/docs/Web/CSS/position#sticky

Cordialement
Modifié par gcyrillus (26 Mar 2024 - 11:52)
Modérateur
Bonjour,
Olivier C a écrit :
Malheureusement ce n'est pas compatible avec un `overflow-x: hidden`
Ça tombe bien. Il y a à peu près zéro bonnes raisons d'utiliser overflow-x: hidden` ! Smiley biggrin

Amicalement,
parsimonhi a écrit :
Ça tombe bien. Il y a à peu près zéro bonnes raisons d'utiliser overflow-x: hidden` ! Smiley biggrin

J'en étais sûr ! J'en étais sûr !
Je savais très bien que si tu voyais ce message tu aurais cette réaction.
Argh ! Smiley biggol
Voici le site sur lequel ça fonctionne, (sur le aside à gauche de la page) :
https://ecrisdroit.fr
aside {
  grid-column: colstart 1 / 1;
  grid-row:3;
  width:80%;
  overflow:scroll;
  max-height:600px;
  position:sticky;
  scrollbar-color: #346abf;
  scrollbar-width: thin;
  top:0;
  margin-left:.8em;
  margin-top:5.8em;
  padding:8px;
  background:#F5F5F5;}

On parle entre nous de notre problème et PapyJP passe au second plan Smiley confus
Modifié par Bongota (26 Mar 2024 - 13:29)
Modérateur
Bongota a écrit :
Voici le site sur lequel ça fonctionne, (sur le aside à gauche de la page) :
https://ecrisdroit.fr
aside {
  grid-column: colstart 1 / 1;
  grid-row:3;
  width:80%;
  overflow:scroll;
  max-height:600px;
  position:sticky;
  scrollbar-color: #346abf;
  scrollbar-width: thin;
  top:0;
  margin-left:.8em;
  margin-top:5.8em;
  padding:8px;
  background:#F5F5F5;}

On parle entre nous de notre problème et PapyJP passe au second plan Smiley confus


Ce sont des infos qui peuvent aussi lui être utiles Smiley cligne

Ton overflow est sur l’élément en position sticky. Cela n'a pas d'incidence, Olivier C evoquait le cas d'un parent avec un overflow redefini.
Cdt
Je suis très content de cette solution qui correspond effectivement à mes besoins/
Un point de détail cependant :
Dans la page qui m'intéresse a la structure suivante :

<body>
    <container>
        <header>...</header>
        <table>
           <thead>....</thead
           .....................................
        </table>
    </container>
</body>

le <header> contient un titre et des boutons. Comme il doit être visible en permanence il est en position:fixed; et background-color:0; qui qui permet que le défilement cache les lignes du haut.
Je n'arrive pas à régler correctement le CSS pour que <thead> en sticky soit en fait directement à sa place, juste au dessous du <header> et que la <table> défile correctement.
Actuellement j'ai

header {
  position:fixed;
  top:0;
  height:12em;
  width:100%;
  text-align:center;
  background-color: white;
}
......
table {
	margin:13em;
	min-width:100%;
	font-size:0.8em
}
table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
td, th {padding:0.25em 0.5em;min-width:5em;max-width:16em;
word-break:break-word;}
thead {
  position:sticky;
  top:13em;
  background:silver;
  border:1px solid black;
}
thead th {
  border:1px solid black;
}

ça marche "presque" Smiley cligne , sauf que le haut de la première ligne de la table est partiellement "mangé".
J'ai essayé de truquer en augmentant le padding-top des cellules de la première ligne. Ça les décale effectivement, mais comme les cellules sont en vertical-align:middle la présentation de ces cellules est perturbée.
Une idée ?
Modérateur
PapyJP a écrit :
Je suis très content de cette solution qui correspond effectivement à mes besoins/
Un point de détail cependant :
ça marche "presque" Smiley cligne , sauf que le haut de la première ligne de la table est partiellement "mangé".
J'ai essayé de truquer en augmentant le padding-top des cellules de la première ligne. Ça les décale effectivement, mais comme les cellules sont en vertical-align:middle la présentation de ces cellules est perturbée.
Une idée ?

Peut-être, table a un margin de 13em et des bordures qui ne sont pas prise en comptes dans le top:13em Smiley cligne C'est ces deux px qui sont mangés ?

Sinon, il y a le font-size qui peut influer sur les valeur rendues par margin et top .... Peut-etre se rabattre sur une valeur en rem pour un margin et un top qui se valent?
Modifié par gcyrillus (26 Mar 2024 - 17:47)
Il y a quelque chose qui m'échappe:
La différence entre un scientifique et un ingénieur, c'est que le scientifique cherche à comprendre et l'un ingénieur cherche une solution.
J'ai donc trouvé une solution sans comprendre, qui consiste à ajouter juste après le <thead> un
<tr class="padding"><td> </td></tr>

avec
tr.padding td {margin:none; font-size:0.2em;}

la valeur de 0.2em ayant été calculée par essais et erreurs.

Pas très fier de cette bidouille, mais ça résout le problème.
Modifié par PapyJP (26 Mar 2024 - 18:19)
Modérateur
Le parent du tableau à une font-size à 1em recalculé en 0.8em pour le tableau.
C'est cette difference de 0.2em que tu vois.

calc() pourrait t'aider en réajustant au plus prés ces différences:
Voici un exemple un peu alambiqué: https://codepen.io/gc-nomade/pen/oNOejJZ qui tente de conserver une cohérence avec des font-size (connues) différentes ou pas pour le tableau et son conteneur.

en raccourci, tu pouvais faire pour margin-top et top , quelque chose comme : calc(13 * .2rem + 13em) pour rattraper ta difference (si tu n'as pas entre temps redefinie les font-size de header et autre parents)

Cdt