Comment puis-je laisser le corps d'une table défiler tout en gardant sa tête fixe en place?


148

J'écris une page où j'ai besoin d'un tableau HTML pour conserver une taille définie. J'ai besoin que les en-têtes en haut du tableau y restent à tout moment, mais j'ai également besoin que le corps du tableau défile quel que soit le nombre de lignes ajoutées au tableau. Pensez à une mini version d'Excel. Cela semble être une tâche simple, mais presque toutes les solutions que j'ai trouvées sur le Web présentent des inconvénients. Comment puis-je resoudre ceci?


2
il y a beaucoup d'exemples là-bas. celui-ci est l'un d'entre eux .
Darren Kopp

J'ai besoin de cibler IE6, IE7, FF, ... mais surtout IE malheureusement
minty

Il y a beaucoup de hacks CSS là-dedans. Cela devrait être trivial de travailler dans IE7.
Jim

4
Je suis intéressé par la réponse pour tous les navigateurs!
minty

15
"Cela devrait être trivial de travailler dans IE7." Jim, c'est toi? Êtes-vous mon chef de projet? :)
Aaronius

Réponses:


53

J'ai dû trouver la même réponse. Le meilleur exemple que j'ai trouvé est http://www.cssplay.co.uk/menu/tablescroll.html - j'ai trouvé que l'exemple n ° 2 fonctionnait bien pour moi. Vous devrez définir la hauteur de la table interne avec Java Script, le reste est CSS.


3
malheureusement, cette méthode échoue lorsque vous avez une table large (défilement horizontal). Vous aurez deux barres de défilement horizontales; un pour l'en-tête et un pour les données.
vol7ron

4
votre solution ne fonctionne pas si vous ne spécifiez pas la <th> largeur à l'intérieur de <thead>
Alexandru R

2
Pour vous conformer aux normes (relativement) nouvelles de Stack Overflow, pourriez-vous modifier cette réponse pour inclure les bits pertinents du lien?
Fund Monica's Lawsuit

Où est la source, Billy?
candlejack

Il est impossible de synchroniser les largeurs de colonne entre l'en-tête et le corps du tableau (défilable) sans recourir à JavaScript ou à des valeurs prédéfinies.
rustyx


12

J'ai vu l' excellente solution de Sean Haddy à une question similaire et j'ai pris la liberté de faire quelques modifications :

  • Utilisez des classes au lieu de l'ID, afin qu'un script jQuery puisse être réutilisé pour plusieurs tables sur une page
  • Ajout de la prise en charge des éléments de table HTML sémantique tels que caption, thead, tfoot et tbody
  • La barre de défilement est facultative afin qu'elle n'apparaisse pas pour les tableaux «plus courts» que la hauteur de défilement
  • Ajustement de la largeur du div de défilement pour amener la barre de défilement sur le bord droit du tableau
  • Concept rendu accessible par
    • en utilisant aria-hidden = "true" sur l'en-tête de table statique injecté
    • et en laissant la tête d'origine en place, juste cachée avec jQuery et définie aria-hidden="false"
  • Montré des exemples de plusieurs tables avec différentes tailles

Sean a cependant fait le gros du travail. Merci également à Matt Burland d'avoir souligné la nécessité de soutenir tfoot.

Veuillez voir par vous-même sur http://jsfiddle.net/jhfrench/eNP2N/


Bon, mais ça va mal si vous voulez un en-tête et un pied de page!
Matt Burland

3
Merci Matt, j'ai fait l'ajustement.
Jeromy French

L'alignement doit être peaufiné si vous affichez les bordures td et th.
dhochee le

8

Avez-vous essayé d'utiliser la tête et le corps, et de définir une hauteur fixe sur le corps avec débordement: défilement?

Quels sont vos navigateurs cibles?

EDIT: Cela a bien fonctionné (presque) dans Firefox - l'ajout de la barre de défilement verticale a également nécessité une barre de défilement horizontale - beurk. IE vient de régler la hauteur de chaque td à ce que j'avais spécifié la hauteur de tbody à être. Voici le meilleur que je pourrais trouver:

<html>
    <head>
    <title>Blah</title>
    <style type="text/css">
    table { width:300px; }
    tbody { height:10em;  overflow:scroll;}
    td { height:auto; }
    </style>
    </head>
    <body>
    <table>
        <thead>
            <tr>
              <th>One</th><th>Two</th>
              </td>
            </tr>
        </thead>
        <tbody>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
        </tbody>
    </table>
    </body>
</html>

1
J'ai besoin de cibler IE6, IE7, FF, ... mais surtout IE malheureusement
minty

Changez la table pour qu'elle soit inférieure à 100% de largeur, disons 99% et qu'elle devrait
régler

2
overflow-x: hidden;et overflow-y: autoaussi aider.
justkt

7
Cela fonctionnait dans Firefox, et c'est le code évident et non compliqué. Cependant, dans les versions plus récentes de Firefox, il est cassé.
Rasmus Kaj

6
Cela ne fonctionne pas car le "débordement" ne s'applique qu'aux "conteneurs de bloc" ( w3.org/TR/CSS21/visufx.html#overflow ) et les boîtes de table ne sont pas des "conteneurs de bloc" ( w3.org/TR/CSS21/ visuren.html # block-boxes ).
mhsmith

8

Ce dont vous avez besoin est:

1) ont un corps de table de hauteur limitée car le défilement se produit uniquement lorsque le contenu est plus grand que la fenêtre de défilement. Cependant, tbodyil ne peut pas être dimensionné et vous devez l'afficher blockpour le faire:

tbody {
   overflow-y: auto;
   display: block;
   max-height: 10em;    // For example
}

2) Synchronisez à nouveau les largeurs des colonnes d'en-tête et de corps de table, car ce dernier en a blockfait un élément non lié. La seule façon de le faire est de simuler la synchronisation en appliquant la même largeur de colonne aux deux .

Cependant, puisque tbodylui-même est un blockmaintenant, il ne peut plus se comporter comme un table. Puisque vous avez toujours besoin d'un tablecomportement pour afficher correctement vos colonnes, la solution est de demander à chacune de vos lignes de s'afficher en tant que tables individuels :

thead {         
   display: table;  
   width: 100%;     // Fill the containing table
}
tbody tr {
   display: table;
   width: 100%;     // Fill the containing table
}

(Notez qu'en utilisant cette technique, vous ne pourrez plus vous étendre sur les lignes).

Une fois cela fait, vous pouvez imposer aux largeurs de colonne d'avoir la même largeur dans les deux theadet tbody. Vous ne pourriez pas que:

  • individuellement pour chaque colonne (via des classes CSS spécifiques ou un style en ligne), ce qui est assez fastidieux à faire pour chaque instance de table;
  • uniformément pour toutes les colonnes (par th, td { width: 20%; } si vous avez 5 colonnes par exemple), ce qui est plus pratique (pas besoin de définir la largeur pour chaque instance de table) mais ne peut fonctionner pour aucun nombre de colonnes
  • uniformément pour tout nombre de colonnes, grâce à une disposition de table fixe.

Je préfère la dernière option, qui nécessite d'ajouter:

thead {
   table-layout: fixed;   // Same layout for all cells
}
tbody tr {
   table-layout: fixed;   // Same layout for all cells
}
th, td {
   width: auto;   // Same width for all cells, if table has fixed layout
}    

Voir une démo ici , tirée de la réponse à cette question .


Merci pour l'explication. Il est fascinant de voir combien de façons quelque chose comme cela peut être fait et la plupart des réponses ne présentent que du code et un lien plunkr, vous laissant le découvrir par vous-même.
Paul Rooney

4

Edit:   C'est une très vieille réponse et est ici pour la prospérité juste pour montrer qu'elle était prise en charge une fois dans les années 2000 mais qu'elle a été abandonnée parce que la stratégie des navigateurs dans les années 2010 était de respecter les spécifications du W3C même si certaines fonctionnalités étaient supprimées: Tableau défilant avec en-tête fixe / footer était maladroitement spécifié avant HTML5.


Mauvaises nouvelles

Malheureusement, il n'y a pas de moyen élégant de gérer un tableau déroulant avec fixe thead/ tfoot parce que les spécifications HTML / CSS ne sont pas très claires sur cette fonctionnalité .

Explications

Bien que la spécification HTML 4.01 indique thead/ tfoot/ tbodysont utilisés (introduits?) Pour faire défiler le corps du tableau:

Les lignes du tableau peuvent être groupées [...] à l'aide des éléments THEAD, TFOOT et TBODY [...]. Cette division permet aux agents utilisateurs de prendre en charge le défilement des corps de table indépendamment de la tête et du pied de table.

Mais la fonctionnalité de tableau déroulant de travail sur FF 3.6 a été supprimée dans FF 3.7 car considérée comme un bogue car non conforme aux spécifications HTML / CSS. Voir ceci et cela commentaires sur les bogues FF.

Astuce du Mozilla Developer Network

Vous trouverez ci-dessous une version simplifiée des conseils utiles de MDN pour le tableau déroulant
voir cette page archivée ou la version française actuelle

<style type="text/css">
table {
  border-spacing: 0;              /* workaround */
}
tbody {
  height: 4em;                    /* define the height */
  overflow-x: hidden;             /* esthetics */
  overflow-y: auto;               /* allow scrolling cells */
}
td {
  border-left:   1px solid blue;  /* workaround */
  border-bottom: 1px solid blue;  /* workaround */
}
</style>

<table>
    <thead><tr><th>Header
    <tfoot><tr><th>Footer
    <tbody>
        <tr><td>Cell 1    <tr><td>Cell 2
        <tr><td>Cell 3    <tr><td>Cell 4
        <tr><td>Cell 5    <tr><td>Cell 6
        <tr><td>Cell 7    <tr><td>Cell 8
        <tr><td>Cell 9    <tr><td>Cell 10
        <tr><td>Cell 11   <tr><td>Cell 12
        <tr><td>Cell 13   <tr><td>Cell 14
    </tbody>
</table>

Cependant MDN dit aussi que cela ne fonctionne plus sur FF :-(
J'ai aussi testé sur IE8 => la table n'est pas non plus scrollable: - ((


Les conseils MDN pour le lien de tableau déroulant ne sont pas des informations pertinentes, il parle de réduction de bordure. Peut-être que la page a changé parce que 5 ans se sont écoulés
Partizanos

Merci @partizanos J'ai enfin trouvé la page originale du wiki dans l'histoire de MDN! Mon ancienne réponse semble maintenant obsolète, mais pour la prospérité, la prochaine génération de développeurs saura qu'elle était possible et facile à mettre en œuvre dans les années 2000 ;-) Cheers
olibre

3

Je ne sais pas si quelqu'un regarde toujours cela, mais la façon dont j'ai fait cela précédemment consiste à utiliser deux tableaux pour afficher le tableau original unique - le premier juste la ligne de titre du tableau d'origine et aucune ligne de corps de tableau (ou une ligne de corps vide à créer il valide).

Le second est dans un div séparé et n'a pas de titre et uniquement les lignes de corps de tableau d'origine. Le div séparé est alors rendu défilable.

Le deuxième tableau de son div est placé juste en dessous du premier tableau dans le HTML et il ressemble à un tableau unique avec un en-tête fixe et une section inférieure déroulante. Je n'ai testé cela que dans Safari, Firefox et IE (les dernières versions de chacun au printemps 2010) mais cela a fonctionné dans tous.

Le seul problème était que la première table ne validerait pas sans corps (validateur W3.org - XHTML 1.0 strict), et quand j'en ai ajouté une sans contenu, cela provoque une ligne vide. Vous pouvez utiliser CSS pour rendre cela invisible, mais cela consomme toujours de l'espace sur la page.


Comment la rangée supplémentaire prendrait-elle encore de l'espace? Il n'a pas besoin de prendre de l'espace d'écran si vous l'utilisez display: none;, à moins que vous ne parliez d'espace dans la source ..?
ClarkeyBoy

3

Cette solution fonctionne sous Chrome 35, Firefox 30 et IE 11 (non testé sur les autres versions)

Son pur CSS: http://jsfiddle.net/ffabreti/d4sope1u/

Tout est configuré pour s'afficher: bloc, la table a besoin d'une hauteur:

    table {
        overflow: scroll;
        display: block;    /*inline-block*/
        height: 120px;
    }
    thead > tr  {
        position: absolute;
        display: block;
        padding: 0;
        margin: 0;
        top: 0;
        background-color: gray;
    }
    tbody > tr:nth-of-type(1) {
        margin-top: 16px;
    }
    tbody tr {
        display: block;
    }

    td, th {
        width: 70px;
        border-style:solid;
        border-width:1px;
        border-color:black;
    }

2

Cela m'a causé d'énormes maux de tête en essayant de mettre en œuvre une telle grille pour une de nos applications. J'ai essayé toutes les différentes techniques mais elles avaient chacune des problèmes. Le plus proche que je suis venu était d'utiliser un plugin jQuery tel que Flexigrid (regardez sur http://www.ajaxrain.com pour des alternatives), mais cela ne semble pas prendre en charge des tables 100% larges, ce dont j'avais besoin.

Ce que j'ai fini par faire, c'est rouler le mien; Firefox prend en charge les tbodyéléments de défilement , donc j'ai reniflé le navigateur et utilisé le CSS approprié (réglage de la hauteur, dépassement de capacité, etc.) pour faire ce défilement, puis pour les autres navigateurs, j'ai utilisé deux tables séparées à utilisertable-layout: fixed qui utilisent un dimensionnement algorithme qui est garanti pour ne pas dépasser la taille indiquée (les tables normales se développeront lorsque le contenu est trop large pour tenir). En donnant aux deux tableaux des largeurs identiques, j'ai pu aligner leurs colonnes. J'ai enveloppé le second dans un ensemble de div pour faire défiler et avec un peu de pokery jiggery avec des marges, etc. j'ai réussi à obtenir le look et la sensation que je voulais.

Désolé si cette réponse semble un peu vague par endroits; J'écris vite car je n'ai pas beaucoup de temps. Laissez un commentaire si vous voulez que je développe davantage!


Désolé de ressusciter cet ancien fil, mais j'ai vraiment besoin de savoir comment vous avez résolu le problème. J'ai fait fonctionner FF mais pas les navigateurs IE / WebKit. Veuillez aider quand vous le pouvez.
Alfero Chingono

2

Voici un code qui fonctionne vraiment pour IE et FF (au moins):

<html>
<head>
    <title>Test</title>
    <style type="text/css">
        table{
            width: 400px;
        }
        tbody {
            height: 100px;
            overflow: scroll;
        }
        div {
            height: 100px;
            width: 400px;
            position: relative;
        }
        tr.alt td {
            background-color: #EEEEEE;
        }
    </style>
    <!--[if IE]>
        <style type="text/css">
            div {
                overflow-y: scroll;
                overflow-x: hidden;
            }
            thead tr {
                position: absolute;
                top: expression(this.offsetParent.scrollTop);
            }
            tbody {
                height: auto;
            }
        </style>
    <![endif]--> 
</head>
<body>
    <div >
        <table border="0" cellspacing="0" cellpadding="0">
            <thead>
                <tr>
                    <th style="background: lightgreen;">user</th>
                    <th style="background: lightgreen;">email</th>
                    <th style="background: lightgreen;">id</th>
                    <th style="background: lightgreen;">Y/N</th>
                </tr>
            </thead>
            <tbody align="center">
                <!--[if IE]>
                    <tr>
                        <td colspan="4">on IE it's overridden by the header</td>
                    </tr>
                <![endif]--> 
                <tr>
                    <td>user 1</td>
                    <td>user@user.com</td>
                    <td>1</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 2</td>
                    <td>user@user.com</td>
                    <td>2</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 3</td>
                    <td>user@user.com</td>
                    <td>3</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 4</td>
                    <td>user@user.com</td>
                    <td>4</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 5</td>
                    <td>user@user.com</td>
                    <td>5</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 6</td>
                    <td>user@user.com</td>
                    <td>6</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 7</td>
                    <td>user@user.com</td>
                    <td>7</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 8</td>
                    <td>user@user.com</td>
                    <td>8</td>
                    <td>N</td>
                </tr>
            </tbody>
        </table>
    </div>
</body></html>

J'ai changé le code d'origine pour le rendre plus clair et aussi pour le faire fonctionner correctement dans IE et aussi FF ..

Code d'origine ICI


1
Dans IE7 / 8, cela ne fonctionne qu'en mode Quirks, et cela cesse de fonctionner dès que vous ajoutez un doctype, c'est<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
ccpizza

1

Voici mon alternative. Il utilise également différents DIV pour l'en-tête, le corps et le pied de page, mais synchronisés pour le redimensionnement de la fenêtre et avec la recherche, le défilement, le tri, le filtrage et le positionnement:

Mes listes de CD

Cliquez sur les boutons Jazz, Classique ... pour voir les tableaux. Il est configuré de manière à être adéquat même si JavaScript est désactivé.

Semble OK sur IE, FF et WebKit (Chrome, Safari).


1

Désolé, je n'ai pas lu toutes les réponses à votre question.

Ouais ici la chose que tu veux (j'ai déjà fait)

Vous pouvez utiliser deux tables, avec le même nom de classe pour un style similaire, une uniquement avec la tête de table et une autre avec vos lignes. Maintenant, placez ce tableau dans un div à hauteur fixe avec overflow-y: auto OR scroll.


1

Le principal problème que j'ai eu avec les suggestions ci-dessus était de pouvoir brancher tablesorter.js ET de pouvoir faire flotter les en-têtes d'une table contrainte à une taille maximale spécifique. Je suis finalement tombé sur le plugin jQuery.floatThead qui fournissait les en-têtes flottants et permettait au tri de continuer à fonctionner.

Il a également une belle page de comparaison qui se montre par rapport à des plugins similaires .


1

Live JsFiddle

C'est possible avec seulement HTML et CSS

table.scrollTable {
  border: 1px solid #963;
  width: 718px;
}

thead.fixedHeader {
  display: block;
}

thead.fixedHeader tr {
  height: 30px;
  background: #c96;
}

thead.fixedHeader tr th {
  border-right: 1px solid black;
}

tbody.scrollContent {
  display: block;
  height: 262px;
  overflow: auto;
}

tbody.scrollContent td {
  background: #eee;
  border-right: 1px solid black;
  height: 25px;
}

tbody.scrollContent tr.alternateRow td {
  background: #fff;
}

thead.fixedHeader th {
  width: 233px;
}

thead.fixedHeader th:last-child {
  width: 251px;
}

tbody.scrollContent td {
  width: 233px;
}
<table cellspacing="0" cellpadding="0" class="scrollTable">
  <thead class="fixedHeader">
    <tr class="alternateRow">
      <th>Header 1</th>
      <th>Header 2</th>
      <th>Header 3</th>
    </tr>
  </thead>
  <tbody class="scrollContent">
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>End of Cell Content 1</td>
      <td>End of Cell Content 2</td>
      <td>End of Cell Content 3</td>
    </tr>
  </tbody>
</table>


0

Si vous pouvez utiliser JavaScript, voici ma solution Créer un tableau avec une largeur fixe sur toutes les colonnes (pixels!) Ajoutez la classe Faites défiler vers le tableau et ajoutez cette hauteur de jeu javascript + jquery 1.4.x en css ou style!

Testé dans: Opera, Chrome, Safari, FF, IE5.5 ( échec du script Epic ), IE6, IE7, IE8, IE9

//Usage add Scrollify class to a table where all columns (header and body) have a fixed pixel width
$(document).ready(function () {
    $("table.Scrollify").each(function (index, element) {
        var header = $(element).children().children().first();
        var headerHtml = header.html();
        var width = $(element).outerWidth();
        var height = parseInt($(element).css("height")) - header.outerHeight();
        $(element).height("auto");
        header.remove();
        var html = "<table style=\"border-collapse: collapse;\" border=\"1\" rules=\"all\" cellspacing=\"0\"><tr>" + headerHtml +
                         "</tr></table><div style=\"overflow: auto;border:0;margin:0;padding:0;height:" + height + "px;width:" + (parseInt(width) + scrollbarWidth()) + "px;\">" +
                         $(element).parent().html() + "</div>";

        $(element).parent().html(html);
    });
});


//Function source: http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels
//License: Apache License, version 2
function scrollbarWidth() {
    var scr = null;
    var inn = null;
    var wNoScroll = 0;
    var wScroll = 0;

    // Outer scrolling div
    scr = document.createElement('div');
    scr.style.position = 'absolute';
    scr.style.top = '-1000px';
    scr.style.left = '-1000px';
    scr.style.width = '100px';
    scr.style.height = '50px';
    // Start with no scrollbar
    scr.style.overflow = 'hidden';

    // Inner content div
    inn = document.createElement('div');
    inn.style.width = '100%';
    inn.style.height = '200px';

    // Put the inner div in the scrolling div
    scr.appendChild(inn);
    // Append the scrolling div to the doc
    document.body.appendChild(scr);

    // Width of the inner div sans scrollbar
    wNoScroll = inn.offsetWidth;
    // Add the scrollbar
    scr.style.overflow = 'auto';
    // Width of the inner div width scrollbar
    wScroll = inn.offsetWidth;

    // Remove the scrolling div from the doc
    document.body.removeChild(
        document.body.lastChild);

    // Pixel width of the scroller
    return (wNoScroll - wScroll);
}

Edit: hauteur fixe.


0

Je fais cela avec javascript (pas de bibliothèque) et CSS - le corps du tableau défile avec la page, et le tableau n'a pas besoin d'être de largeur ou de hauteur fixe, bien que chaque colonne doive avoir une largeur. Vous pouvez également conserver la fonctionnalité de tri.

Fondamentalement:

  1. En HTML, créez des conteneurs divs pour positionner la ligne d'en-tête du tableau et le corps du tableau, créez également un div "masque" pour masquer le corps du tableau lorsqu'il défile au-delà de l'en-tête

  2. En CSS, convertissez les parties du tableau en blocs

  3. En Javascript, obtenez la largeur du tableau et correspond à la largeur du masque ... obtenez la hauteur du contenu de la page ... mesurez la position de défilement ... manipulez CSS pour définir la position de la ligne d'en-tête du tableau et la hauteur du masque

Voici le javascript et une DEMO jsFiddle.

// get table width and match the mask width

function setMaskWidth() { 
  if (document.getElementById('mask') !==null) {
    var tableWidth = document.getElementById('theTable').offsetWidth;

    // match elements to the table width
    document.getElementById('mask').style.width = tableWidth + "px";
   }
}

function fixTop() {

  // get height of page content 
  function getScrollY() {
      var y = 0;
      if( typeof ( window.pageYOffset ) == 'number' ) {
        y = window.pageYOffset;
      } else if ( document.body && ( document.body.scrollTop) ) {
        y = document.body.scrollTop;
      } else if ( document.documentElement && ( document.documentElement.scrollTop) ) {
        y = document.documentElement.scrollTop;
      }
      return [y];
  }  

  var y = getScrollY();
  var y = y[0];

  if (document.getElementById('mask') !==null) {
      document.getElementById('mask').style.height = y + "px" ;

      if (document.all && document.querySelector && !document.addEventListener) {
        document.styleSheets[1].rules[0].style.top = y + "px" ;
      } else {
        document.styleSheets[1].cssRules[0].style.top = y + "px" ;
      }
  }

}

window.onscroll = function() {
  setMaskWidth();
  fixTop();
}

Mais dans votre démo, l'en-tête du tableau ne reste pas en place, il défile simplement. (Chrome ici.)
Sz.

Je ne vois pas cela dans Chrome. Êtes-vous sûr de ne pas confondre les cellules surlignées en jaune avec des instructions en rouge pour l'en-tête? Les cellules d'en-tête sont en haut et sont grises sur gris ("Col 1", "Col 2", etc.).
Deborah

0

Pour moi, rien lié au défilement n'a vraiment fonctionné jusqu'à ce que je supprime la largeur du tableau CSS. À l'origine, la table CSS ressemblait à ceci:

.table-fill {
    background: white;
    border-radius:3px;
    border-collapse: collapse;
    margin: auto;
    width: 100%;
    max-width: 800px;
    padding:5px;
    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
    animation: float 5s infinite;
}

Dès que j'ai enlevé la largeur: 100%; toutes les fonctionnalités de défilement ont commencé à fonctionner.


0

Si vous avez des normes suffisamment basses;), vous pouvez placer un tableau qui ne contient qu'un en-tête directement au-dessus d'un tableau qui n'a qu'un corps. Il ne défilera pas horizontalement, mais si vous n'en avez pas besoin ...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.