So zeigen Sie die Bildlaufleiste in einer HTML-Tabelle an

85

Ich schreibe eine Seite, auf der ich eine HTML-Tabelle benötige, um eine festgelegte Größe beizubehalten. Ich brauche die Überschriften oben in der Tabelle, um immer dort zu bleiben, aber ich brauche auch den Hauptteil der Tabelle, um zu scrollen, egal wie viele Zeilen zur Tabelle hinzugefügt werden.

Ich möchte, dass es wie Methode 2 in dieser URL aussieht: http://www.cssplay.co.uk/menu/tablescroll.html

Ich habe es versucht, aber es wird keine Bildlaufleiste angezeigt:

tbody {
  height: 80em;
  overflow: scroll;
}
<table border=1 id="qandatbl" align="center">
  <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
  </tr>

  <tbody>
    <tr>
      <td class='qid'></td>
      <td class="options"></td>
      <td class="duration"></td>
    </tr>
  </tbody>
</table>

BruceyBandit
quelle
Warum verwenden Sie nicht den Code aus der Beispielmethode? Sie können <tbody>leider nicht verwenden .
Mike Park

Antworten:

162

Etwas wie das?

http://jsfiddle.net/TweNm/

Die Idee ist, das <table>in eine nicht statisch positionierte zu wickeln, die <div>eine overflow:autoCSS-Eigenschaft hat. Dann positionieren Sie die Elemente in der <thead>absolut.

#table-wrapper {
  position:relative;
}
#table-scroll {
  height:150px;
  overflow:auto;  
  margin-top:20px;
}
#table-wrapper table {
  width:100%;

}
#table-wrapper table * {
  background:yellow;
  color:black;
}
#table-wrapper table thead th .text {
  position:absolute;   
  top:-20px;
  z-index:2;
  height:20px;
  width:35%;
  border:1px solid red;
}
<div id="table-wrapper">
  <div id="table-scroll">
    <table>
        <thead>
            <tr>
                <th><span class="text">A</span></th>
                <th><span class="text">B</span></th>
                <th><span class="text">C</span></th>
            </tr>
        </thead>
        <tbody>
          <tr> <td>1, 0</td> <td>2, 0</td> <td>3, 0</td> </tr>
          <tr> <td>1, 1</td> <td>2, 1</td> <td>3, 1</td> </tr>
          <tr> <td>1, 2</td> <td>2, 2</td> <td>3, 2</td> </tr>
          <tr> <td>1, 3</td> <td>2, 3</td> <td>3, 3</td> </tr>
          <tr> <td>1, 4</td> <td>2, 4</td> <td>3, 4</td> </tr>
          <tr> <td>1, 5</td> <td>2, 5</td> <td>3, 5</td> </tr>
          <tr> <td>1, 6</td> <td>2, 6</td> <td>3, 6</td> </tr>
          <tr> <td>1, 7</td> <td>2, 7</td> <td>3, 7</td> </tr>
          <tr> <td>1, 8</td> <td>2, 8</td> <td>3, 8</td> </tr>
          <tr> <td>1, 9</td> <td>2, 9</td> <td>3, 9</td> </tr>
          <tr> <td>1, 10</td> <td>2, 10</td> <td>3, 10</td> </tr>
          <!-- etc... -->
          <tr> <td>1, 99</td> <td>2, 99</td> <td>3, 99</td> </tr>
        </tbody>
    </table>
  </div>
</div>

Richard JP Le Guen
quelle
15
Wie wäre es ohne keine Spalten mit fester Breite?
Fractaliste
3
Ich habe Ihre Antwort versucht, aber die Kopfspalten sind nicht ausgerichtet. Ich habe nur Ihr CSS in einem Style-Tag innerhalb des Body-Tags verwendet, in das ich Ihre Tabelle kopiert habe
Antonio
Tolle Lösung, aber ich habe Probleme damit. Wenn Sie versuchen, eine Zeile auszublenden und die Anzeige festzulegen: Keine. Zwischen den Zeilen befinden sich Leerzeichen. Dies ist beim regulären Tisch nicht der Fall. Irgendwelche Ideen, Tipps oder Vorschläge?
Daniil Shevelev
@Antonio: Ich hatte das gleiche Problem (zentrierte * Header-Spalten scheinen nicht ausgerichtet zu sein), aber das Hinzufügen transform: translateX(-50%)hat den Trick für mich getan [* zentriert ist das Standard-Styling in Firefox, das durch die Option „CSS normalisieren“ in der JSFiddle dieser Antwort entfernt wird]
Sora.
43

Sie müssen Ihre <table>in eine <div>feste Größe einfügen und den <div>Stil festlegen, den Sie festlegen müssen overflow: scroll.

Hossein Barzegari
quelle
1
gab Höhe als 500px für mein div und es funktionierte gut. <div style = "Überlauf: Bildlauf; Höhe: 500px;">
Ziggler
3
Ich weiß nicht, warum alle es so kompliziert gemacht haben. Dies sollte die akzeptierte Antwort sein.
Amallard
1
Dies ist bei weitem die einfachste Lösung. Das Hinzufügen eines Divs mit Überlauf und fester Höhe kann einige Einschränkungen mit sich bringen, aber diese Lösung bringt Sie zumindest in die richtige Richtung.
lsimonetti
Hervorragende Antwort Kumpel! Prost an dich
:)
Dies sollte die akzeptierte Antwort sein. Einfach, direkt auf den Punkt und ich zerstöre nichts anderes damit.
Ich versuche es so sehr, aber ich weine stärker
40

Die akzeptierte Antwort bot einen guten Ausgangspunkt. Wenn Sie jedoch die Größe des Rahmens ändern, die Spaltenbreite ändern oder sogar die Tabellendaten ändern, werden die Überschriften auf verschiedene Weise durcheinander gebracht. Jedes andere Beispiel, das ich gesehen habe, weist ähnliche Probleme auf oder schränkt das Layout der Tabelle ernsthaft ein.

Ich denke, ich habe endlich alle diese Probleme gelöst. Es hat viel CSS gekostet, aber das Endprodukt ist ungefähr so ​​zuverlässig und einfach zu bedienen wie ein normaler Tisch.

Hier ist ein Beispiel mit allen erforderlichen Funktionen zum Replizieren der Tabelle, auf die das OP verweist : jsFiddle

Die Farben und Ränder müssten geändert werden, damit sie mit der Referenz identisch sind. Informationen zum Vornehmen solcher Änderungen finden Sie in den CSS-Kommentaren.

Hier ist der Code:

/*the following html and body rule sets are required only if using a % width or height*/
/*html {
width: 100%;
height: 100%;
}*/
body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
  background: white;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /*if you want a fixed width, set it here, else set to auto*/
  min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
  height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
  min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 15px;
  line-height: 20px;
  padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
  text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /*this determines column header height*/
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /*header row background color*/
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
  max-height: 100%;
  overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
  overflow-x: hidden;
  border: 1px solid black; /*border around table body*/
}
.scrollingtable > div > div:after {background: white;} /*match page background color*/
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /*inverse of column header height*/
  /*margin-right: 17px;*/ /*uncomment if using % width*/
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /*match column header height*/
  padding-top: 1px;
  border-left: 1px solid black; /*borders between header cells*/
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /*inverse border-width*/
  background: white; /*match page background color*/
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /*inverse of border width*/
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /*match column header height*/
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"></div></th>
            <th><div label="Column 2"></div></th>
            <th><div label="Column 3"></div></th>
            <th>
              <!--more versatile way of doing column label; requires 2 identical copies of label-->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->

DoctorDestructo
quelle
beeindruckende Arbeit. Ich habe jedoch eine Tabelle mit 15 Spalten und kann die Tabelle auf der Seite jetzt auch ohne horizontale Bildlaufleiste nicht enthalten. Ich habe versucht, Ihr CSS, Ihr wunderschön codiertes CSS, zu optimieren, um mehr Spalten mit dynamischer Breite aufzunehmen, aber nichts, was ich außer der Tabellenbreite ändere, macht einen Unterschied. Wenn ich die Tabellenbreite auf 100% ändere, wird die Tabelle in der Breite der Tabelle gerendert. Da die Spaltenbreiten jedoch nicht umgebrochen werden, werden immer noch nicht alle 15 Datenspalten angezeigt. Ich habe fast eine Bildlauftabelle, die wie ein Kewl aussieht, also ist jede Hilfe willkommen.
Nanker
Oh, warte eine Sekunde, keine horizontale Bildlaufleiste, die Tabelle schneidet einfach ab.
Nanker
@nanker Wenn Sie horizontales Scrollen benötigen und bereit sind, ein kleines bisschen JavaScript zu verwenden, sollten Sie diese Antwort überprüfen . Es ist der beste Weg, eine Bildlauftabelle zu erstellen, die mir bekannt ist. Als ich diese Antwort gepostet habe, gab es keine gute Möglichkeit, horizontales Scrollen nur mit CSS durchzuführen, aber ich habe mich eine Weile nicht damit befasst, sodass ich nicht weiß, was jetzt möglich ist.
DoctorDestructo
Tolle Arbeit. Könnten Sie kommentieren, wie Sie für mehrere Kopfzeilen optimieren können? Das einfache Wiederholen des <tr><th></th>..</tr>Konstrukts funktioniert nicht. Vielen Dank.
David I. McIntosh
@ DavidI.McIntosh Ein mehrzeiliger Header wäre mit dieser Technik schwierig. Das Hinzufügen von Zeilen wäre einfach, aber ich bin mir nicht sicher, wie Sie die horizontalen Ränder zwischen ihnen erhalten würden. Möglicherweise möchten Sie die JavaScript-Lösung ausprobieren, die ich in meinem vorherigen Kommentar verlinkt habe, es sei denn, Sie können JS aus irgendeinem Grund nicht verwenden.
DoctorDestructo
3

Ich habe dieses Problem gelöst, indem ich meinen Inhalt in zwei Tabellen aufgeteilt habe.

Eine Tabelle ist die Kopfzeile.

Die Sekunde ist ebenfalls ein <table>Tag, wird jedoch <div>mit statischer Höhe und Überlaufschriftrolle umbrochen .

Zvi
quelle
1

Es ist erwähnenswert, dass Sie abhängig von Ihrem Zweck (meiner war das automatische Ausfüllen der Ergebnisse einer Suchleiste) möglicherweise möchten, dass die Höhe geändert werden kann und dass die Bildlaufleiste nur vorhanden ist, wenn die Höhe diese überschreitet.

Wenn Sie das möchten, ersetzen Sie height: x;durch max-height: x;und overflow:scrollmit overflow:auto.

Darüber hinaus können Sie overflow-xund verwenden, overflow-ywenn Sie möchten, und offensichtlich funktioniert das gleiche horizontal mitwidth : x;

Ben
quelle
0

Wenn Sie an einem Punkt angelangt sind, an dem alle genannten Lösungen nicht mehr funktionieren (wie bei mir), gehen Sie folgendermaßen vor:

  • Erstellen Sie zwei Tabellen. Eine für den Header und eine für den Körper
  • Geben Sie den beiden Tabellen unterschiedliche übergeordnete Container / Divs
  • Gestalten Sie das div der zweiten Tabelle so, dass ein vertikaler Bildlauf des Inhalts möglich ist.

So in deinem HTML

<div class="table-header-class">
    <table>
       <thead>
          <tr>
            <th>Ava</th>
            <th>Alexis</th>
            <th>Mcclure</th>
          </tr>
       </thead>
    </table>
</div>
<div class="table-content-class">
   <table>
       <tbody>
          <tr>
            <td>I am the boss</td>
            <td>No, da-da is not the boss!</td>
            <td>Alexis, I am the boss, right?</td>
          </tr>
       </tbody>
    </table>
</div>

Gestalten Sie dann das übergeordnete Element der zweiten Tabelle, um ein vertikales Scrollen in Ihrem zu ermöglichen CSS

    .table-content-class {
        overflow-y: scroll;    // use auto; or scroll; to allow vertical scrolling; 
        overflow-x: hidden;    // disable horizontal scroll 
    }
Kaka Ruto
quelle
Dies ist die gleiche Implementierung wie die Antwort von Zvi ein Jahr zuvor.
TylerH
0

einfach auf Tabelle hinzufügen

style="overflow-x:auto;"

<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">
    <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
    </tr>

   <tbody>
    <tr>
    <td class='qid'></td>
    <td class="options"></td>
    <td class="duration"></td>
    </tr>
    </tbody>
</table>

style = "overflow-x: auto;" `

Lernort Meister
quelle