Tableau déroulant Twitter Bootstrap

149

J'aimerais avoir un tableau sur mon site Web. Le problème est que ce tableau aura environ 400 lignes. Comment puis-je limiter la hauteur de la table et lui appliquer une barre de défilement? Voici mon code:

<div class="span3">
  <h2>Achievements left</h2>
<table class="table table-striped">
  <thead>
    <tr>
      <th>#</th>
      <th>Name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>5</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>6</td>
      <td>Something</td>
    </tr>
  </tbody>
</table>

  <p><a class="btn" href="#">View details &raquo;</a></p>
</div>

J'ai essayé d'appliquer une hauteur maximale et une hauteur fixe à la table, mais cela ne fonctionne pas.

pangi
la source

Réponses:

241

Les éléments de tableau ne semblent pas prendre en charge cela directement. Placez la table dans un div et définissez la hauteur du div et de l'ensemble overflow: auto.

Jonathan Wood
la source
50
Cela a-t-il vraiment fonctionné? J'ai essayé cela et cela n'a eu aucun effet.
cjstehno
8
Juste pour info, régler le débordement sur «auto», plutôt que sur le débordement: défilement, ne créera pas une barre de défilement horizontale redondante.
daCoda
8
@JonathanWood: y a-t-il un moyen d'appliquer overflowuniquement sur le corps du tableau mais où les <thead>parties sont toujours affichées?
Willem Van Onsem
8
Juste pour que cela soit clair pour les gens .... <div style = "overflow: auto;"> <table class = "table"> .... </table> </div>
Henry Weber
3
Veuillez donner un petit exemple!
Yahya Yahyaoui
53
.span3 {  
    height: 100px !important;
    overflow: scroll;
}​

Vous voudrez l'envelopper dans son propre div ou donner à ce span3 un identifiant qui lui est propre afin de ne pas affecter votre mise en page entière.

Voici un violon: http://jsfiddle.net/zm6rf/

Accords
la source
2
Notez que le '! Important' n'est pas important;)
Accords
8
Attention, la définition de ces propriétés .span3affectera tous les span3 éléments de l'ensemble de votre site basé sur Bootstrap.
Terry
1
Vous ne pouvez ajouter un pourcentage de hauteur que si le conteneur parent a une hauteur en pixels. Dans votre cas, vous devez faire quelque chose comme définir .row à 500px et .span3 à 50%. Si le parent n'a pas de hauteur définie, le navigateur utilise par défaut la hauteur du contenu si vous lui donnez un pourcentage.
Accords
1
Pouvez-vous faire cela tout en rendant le corps scollable et le thead pas?
réverbère
1
Pour votre information, le réglage overflow: scroll créera une barre de défilement horizontale qui peut être redondante. Le rendre automatique, c'est-à-dire overflow: auto, ne fait pas cela.
daCoda
38

Pas besoin de l'envelopper dans un div ...

CSS :

tr {
width: 100%;
display: inline-table;
table-layout: fixed;
}

table{
 height:300px;              // <-- Select the height of the table
 display: -moz-groupbox;    // Firefox Bad Effect
}
tbody{
  overflow-y: scroll;      
  height: 200px;            //  <-- Select the height of the body
  width: 100%;
  position: absolute;
}

Bootply : http://www.bootply.com/AgI8LpDugl

BENARD Patrick
la source
J'ai été très excité quand j'ai vu cet exemple, mais il s'avère que la mise en page est "funked" lorsque les données de l' tdélément varient en taille. bootply.com/OsvzINuTUA
Frito
4
@Frito Ne vous inquiétez pas, soyez heureux;) J'ai juste oublié la mise en page du tableau: corrigé; ... Lien mis à jour
BENARD Patrick
30

J'ai eu le même problème et j'ai utilisé une combinaison des solutions ci-dessus (et j'ai ajouté une touche de ma part). Notez que j'ai dû spécifier les largeurs de colonne pour les garder cohérentes entre l'en-tête et le corps.

Dans ma solution, l'en-tête et le pied de page restent fixes pendant que le corps défile.

<div class="table-responsive">
    <table class="table table-striped table-hover table-condensed">
        <thead>
            <tr>
                <th width="25%">First Name</th>
                <th width="13%">Last Name</th>
                <th width="25%" class="text-center">Address</th>
                <th width="25%" class="text-center">City</th>
                <th width="4%" class="text-center">State</th>
                <th width="8%" class="text-center">Zip</th>
            </tr>
        </thead>
    </table>
    <div class="bodycontainer scrollable">
        <table class="table table-hover table-striped table-condensed table-scrollable">
            <tbody>
                <!-- add rows here, specifying same widths as in header, at least on one row -->
            </tbody>
        </table>
    </div>
    <table class="table table-hover table-striped table-condensed">
        <tfoot>
            <!-- add your footer here... -->
        </tfoot>
    </table>
</div>

Et puis juste appliqué le CSS suivant:

.bodycontainer { max-height: 450px; width: 100%; margin: 0; overflow-y: auto; }
.table-scrollable { margin: 0; padding: 0; }

J'espère que ça aidera quelqu'un d'autre.

Todd
la source
Merci, cela aide. Malheureusement, je ne peux pas spécifier la largeur des éléments car ce n'est cependant pas un élément valide. (???)
Erwin Rooijakkers
1
les colonnes du td ne sont pas alignées avec les éléments th parce que la barre de défilement déplace le contenu
IHeartAndroid
Ahh ... Je suis sur un Mac où les barres de défilement sont invisibles et n'apparaissent au-dessus du contenu que pendant le défilement. Ce sera difficile car les barres de défilement dépendent du système d'exploitation et du navigateur.
Todd
9

J'ai récemment dû faire cela avec bootstrap et angularjs, j'ai créé une directive angularjs qui résout le problème, vous pouvez voir un exemple de travail et des détails sur ce billet de blog .

Vous l'utilisez simplement en ajoutant un attribut d'en-tête fixe à la balise table:

<table class="table table-bordered" fixed-header>
...
</table>

Si vous n'utilisez pas angularjs, vous pouvez modifier le javascript de la directive et l'utiliser directement à la place.

Jason
la source
8

CSS

.achievements-wrapper { height: 300px; overflow: auto; }

HTML

<div class="span3 achievements-wrapper">
    <h2>Achievements left</h2>
    <table class="table table-striped">
    ...
    </table>
</div>
Terry
la source
Est-il possible de garder la hauteur relative?
pangi
Je veux que la hauteur soit définie avec des pourcentages. Est-ce possible? Je n'ai pas pu le faire fonctionner.
pangi
Bien sûr, réglez simplement la hauteur de la table à 100%. .table-class-name { height: 100%; }.
Terry
Cela prolonge ma table, et cela continue encore et encore. (Il n'a aucun effet)
pangi
4
Par cette méthode, l'en-tête peut également faire défiler, alors existe-t-il un moyen de corriger l'en-tête du tableau?
Kyleinincubator
4

Ce n'est peut-être pas une solution pour un grand nombre de lignes. J'utilise simplement l'astuce de la table de duplication pour faire le travail pour une petite table de comptage de lignes tout en conservant une largeur de colonne flexible, vous pouvez essayer ce violon .

(La colonne à largeur fixe est la méthode que j'utilise pour les grandes tables de comptage de lignes qui ne nécessitent que la duplication de lignes d'en-tête)

Exemple de code:

<div style="height:30px;overflow:hidden;margin-right:15px;">
   <table class="table">
       <thead>
           <tr>
                <th>Col 1</th>
                <th>Col 2</th>
                <th>Col 3</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Cel 1,1</td>
                <td>Cel 1,2</td>
                <td>Cel 1,3</td>
            </tr>
            <tr>
                <td>Cel 2,1</td>
                <td>Cel 2,2</td>
                <td>Cel 2,3</td>
            </tr>
            <tr>
                <td>Cel 3,1</td>
                <td>Cel 3,2</td>
                <td>Cel 3,3</td>
            </tr>


        </tbody>
    </table>
</div>
<div style="height:100px;overflow-y:scroll;;">
    <table class="table">
        <thead>

        </thead>
        <tbody>
            <tr>
                <td>Cel 1,1</td>
                <td>Cel 1,2</td>
                <td>Cel 1,3</td>
            </tr>
            <tr>
                <td>Cel 2,1</td>
                <td>Cel 2,2</td>
                <td>Cel 2,3</td>
            </tr>
            <tr>
                <td>Cel 3,1</td>
                <td>Cel 3,2</td>
                <td>Cel 3,3</td>
            </tr>
             <tr style="color:white">
                <th>Col 1</th>
                <th>Col 2</th>
                <th>Col 3</th>
            </tr>
        </tbody>
    </table>
</div>
Chukiat
la source
4

Mettez la table dans un div et donnez ce div à la classe pre-scrollable.

Reza Saadati
la source
3

J'ai récemment eu un problème similaire et j'ai fini par le résoudre en utilisant un mélange de différentes solutions.

La première et la plus simple consistait à utiliser deux tables, une pour les en-têtes et une pour le corps. Cela fonctionne mais les en-têtes et les colonnes du corps ne sont pas alignés. Et comme je voulais utiliser la taille automatique fournie avec les tables de bootstrap Twitter, j'ai fini par créer une fonction Javascript qui change les en-têtes lorsque: le corps est rendu; les fenêtres sont redimensionnées; les données de la colonne changent, etc.

Voici une partie du code que j'ai utilisé:

        <table class="table table-striped table-hover" style="margin-bottom: 0px;">
        <thead>
            <tr>
                <th data-sort="id">Header 1</i></th>
                <th data-sort="guide">Header 2</th>
                <th data-sort="origin">Header 3</th>
                <th data-sort="supplier">Header 4</th>
            </tr>
        </thead>
    </table>
    <div class="bodycontainer scrollable">
        <table class="table table-hover table-striped table-scrollable">
            <tbody id="rows"></tbody>
        </table>
    </div>

Les en-têtes et le corps sont divisés en deux tableaux distincts. L'un d'eux se trouve à l'intérieur d'un DIV avec le style nécessaire pour générer les barres de défilement verticales. Voici le CSS que j'ai utilisé:

.bodycontainer {
  //height: 200px
  width: 100%;
  margin: 0;
}

.table-scrollable {
  margin: 0px;
  padding: 0px;
}

J'ai commenté la hauteur ici parce que je voulais que le tableau atteigne le bas de la page, quelle que soit la hauteur de la page.

Les attributs de tri de données que j'ai utilisés dans les en-têtes sont également utilisés dans chaque td. De cette façon, je pourrais obtenir la largeur et le remplissage de chaque td et la largeur de la ligne. En utilisant les attributs de tri de données que j'ai définis en utilisant CSS, le remplissage et la largeur de chaque en-tête en conséquence et de la ligne d'en-tête qui est toujours plus grande car elle n'a pas de barre de défilement. Voici la fonction utilisant coffeescript:

fixHeaders: =>
  for header, i in @headers
    tdpadding = parseInt(@$("td[data-sort=#{header}]").css('padding'))
    tdwidth = parseInt(@$("td[data-sort=#{header}]").css('width'))
    @$("th[data-sort=#{header}]").css('padding', tdpadding)
    @$("th[data-sort=#{header}]").css('width', tdwidth)
    if (i+1) == @headers.length
      trwidth = @$("td[data-sort=#{header}]").parent().css('width')
      @$("th[data-sort=#{header}]").parent().parent().parent().css('width', trwidth)
      @$('.bodycontainer').css('height', window.innerHeight - ($('html').outerHeight() -@$('.bodycontainer').outerHeight() ) ) unless @collection.length == 0

Ici, je suppose que vous avez un tableau des en-têtes appelés @headers.

Ce n'est pas joli mais ça marche. J'espère que ça aide quelqu'un.

guzmonne
la source
3

Toutes les solutions ci-dessus font défiler l'en-tête du tableau aussi ... Si vous ne voulez faire défiler que le corps, appliquez ceci:

tbody {
    height: 100px !important;
    overflow: scroll;
    display:block;
}
solo999
la source
7
Cela ne fonctionnera que s'il s'agit d'une table à une seule colonne. Si vous avez une table avec plusieurs colonnes, cela ne fera défiler que la première colonne.
empo
2

Aucune de ces réponses n'a fonctionné de manière satisfaisante pour moi. Soit ils n'ont pas fixé la ligne d'en-tête du tableau en place, soit ils ont besoin de largeurs de colonne fixes pour fonctionner, et même dans ce cas, la ligne d'en-tête et les lignes de corps sont mal alignées dans divers navigateurs.

Je recommande de mordre la balle et d'utiliser un contrôle de grille approprié comme jsGrid ou mon favori personnel, SlickGrid . Cela introduit évidemment une dépendance, mais si vous voulez que vos tables se comportent comme de vraies grilles avec la prise en charge de plusieurs navigateurs, cela vous évitera de vous arracher les cheveux. Il vous donne également la possibilité de trier et de redimensionner les colonnes ainsi que des tonnes d'autres fonctionnalités si vous les souhaitez.

Simon Brangwin
la source
2

Concernant la suggestion de Jonathan Wood. Je n'ai pas la possibilité d'encapsuler les tables avec un nouveau div car j'utilise un CMS. En utilisant JQuery, voici ce que j'ai fait:

$( "table" ).wrap( "<div class='table-overflow'></div>" );

Cela enveloppe les éléments de table avec un nouveau div avec la classe "table-overflow".

Vous pouvez ensuite simplement ajouter la définition suivante dans votre fichier css:

.table-overflow { overflow: auto; }     
Scott
la source
2

placez le tableau à l'intérieur du div pour créer un tableau déroulant verticalement. changer overflow-ypour overflow-xfaire défiler le tableau horizontalement. juste overflowpour rendre le tableau déroulant à la fois horizontalement et verticalement.

<div style="overflow-y: scroll;"> 
    <table>
    ...
    </table>
</div>
Iqbal Pratomo Santoso
la source
1

Je pensais que je publierais ici car je ne pouvais pas faire fonctionner l'un des éléments ci-dessus avec Bootstrap 4. J'ai trouvé cela en ligne et j'ai parfaitement fonctionné pour moi ...

table
{
    width: 100%;
    display: block;
    border:solid black 1px;
}

thead
{
    display: inline-block;
    width: 100%;
    height: 20px;
}

tbody
{
    height: 200px;
    display: inline-block;
    width: 100%;
    overflow: auto;
}

th, td
{
    width: 100px;
    border:solid 1px black;
    text-align:center;
}

J'ai également joint le fichier jsfindle.

https://jsfiddle.net/jgngg28t/

J'espère que cela aide quelqu'un d'autre.

BV2005
la source