HTML-Tabelle mit 100% Breite und vertikalem Bildlauf innerhalb des Körpers

423

Wie kann ich eine <table>Breite von 100% einstellen und <tbody>für eine gewisse Höhe nur eine vertikale Schriftrolle verwenden?

vertikale Schriftrolle innerhalb des Körpers

table {
    width: 100%;
    display:block;
}
thead {
    display: inline-block;
    width: 100%;
    height: 20px;
}
tbody {
    height: 200px;
    display: inline-block;
    width: 100%;
    overflow: auto;
}
  
<table>
  <thead>
    <tr>
    	<th>Head 1</th>
    	<th>Head 2</th>
    	<th>Head 3</th>
    	<th>Head 4</th>
    	<th>Head 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
    	<td>Content 1</td>
    	<td>Content 2</td>
    	<td>Content 3</td>
    	<td>Content 4</td>
    	<td>Content 5</td>
    </tr>
  </tbody>
</table>

Ich möchte vermeiden, zusätzliche Divs hinzuzufügen. Alles, was ich möchte, ist eine einfache Tabelle wie diese und wenn ich versuche, die Anzeige zu ändern table-layout, positionund vieles mehr in der CSS-Tabelle, die mit 100% Breite nicht gut funktioniert, nur mit fester Breite in px.

Marko S.
quelle
Ich bin mir nicht sicher, was du erreichen willst. Schauen Sie sich das an: jsfiddle.net/CrSpu und sagen Sie, wie es sich verhalten soll
x4rf41
2
Ich weiß, aber schau .. th und td werden nicht in voller Breite angezeigt
Marko S
Siehe auch
Christophe Roussy

Antworten:

674

Um das <tbody>Element scrollbar zu machen , müssen wir die Art und Weise ändern, wie es auf der Seite angezeigt wird, dh display: block;um es als Element auf Blockebene anzuzeigen.

Da wir die displayEigenschaft von tbodyändern, sollten wir diese Eigenschaft auch für das theadElement ändern, um zu verhindern, dass das Tabellenlayout beschädigt wird.

Also haben wir:

thead, tbody { display: block; }

tbody {
    height: 100px;       /* Just for the demo          */
    overflow-y: auto;    /* Trigger vertical scroll    */
    overflow-x: hidden;  /* Hide the horizontal scroll */
}

Web - Browser angezeigt werden, das theadund tbodyElemente als Zeilengruppe ( table-header-groupund table-row-group) standardmäßig.

Sobald wir das ändern, trfüllen die inneren Elemente nicht den gesamten Raum ihres Containers aus.

Um dies zu beheben, müssen wir die Breite der tbodySpalten berechnen und den entsprechenden Wert theadüber JavaScript auf die Spalten anwenden .

Spalten mit automatischer Breite

Hier ist die jQuery-Version der obigen Logik:

// Change the selector if needed
var $table = $('table'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
    return $(this).width();
}).get();

// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
    $(v).width(colWidth[i]);
});    

Und hier ist die Ausgabe (unter Windows 7 Chrome 32) :

vertikale Schriftrolle innerhalb des Körpers

ARBEITSDEMO .

Tabelle mit voller Breite, Spalten mit relativer Breite

Wenn das Originalposter benötigt wird, können wir den Container tableauf 100% erweitern widthund dann für jede Spalte der Tabelle einen relativen Wert ( Prozentsatz ) verwenden width.

table {
    width: 100%; /* Optional */
}

tbody td, thead th {
    width: 20%;  /* Optional */
}

Da die Tabelle ein (Art) flüssiges Layout hat , sollten wir die Breite der theadSpalten anpassen , wenn die Größe des Containers geändert wird.

Daher sollten wir die Breite der Spalten festlegen, sobald die Fenstergröße geändert wird:

// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
    /* Same as before */ 
}).resize(); // Trigger the resize handler once the script runs

Die Ausgabe wäre:

Fluid Table mit vertikaler Schriftrolle im Körper

ARBEITSDEMO .


Browser-Unterstützung und Alternativen

Ich habe die beiden oben genannten Methoden unter Windows 7 über die neuen Versionen der wichtigsten Webbrowser (einschließlich IE10 +) getestet und es hat funktioniert.

Es ist jedoch nicht funktioniert richtig auf IE9 und unten.

Dies liegt daran, dass in einem Tabellenlayout alle Elemente denselben strukturellen Eigenschaften folgen sollten.

Durch die Verwendung von display: block;for <thead>und <tbody>Elementen haben wir die Tabellenstruktur gebrochen.

Layout über JavaScript neu gestalten

Ein Ansatz besteht darin, das (gesamte) Tabellenlayout neu zu gestalten. Verwenden Sie JavaScript, um im laufenden Betrieb ein neues Layout zu erstellen und die Breiten / Höhen der Zellen dynamisch zu handhaben und / oder anzupassen.

Schauen Sie sich zum Beispiel die folgenden Beispiele an:

Satztische

Dieser Ansatz verwendet zwei verschachtelte Tabellen mit einem enthaltenden div. Die erste tablehat nur eine Zelle mit einem div, und die zweite Tabelle befindet sich in diesem divElement.

Überprüfen Sie die vertikalen Bildlauftabellen bei CSS Play .

Dies funktioniert in den meisten Webbrowsern. Wir können die obige Logik auch dynamisch über JavaScript ausführen.

Tabelle mit fester Überschrift auf Bildlauf

Da der Zweck der vertikale Bildlaufleiste der Zugabe <tbody>wird die Tabelle anzeigt Header am Anfang jeder Zeile, könnten wir die Position des theadElements zu bleibenfixed am oberen Rand des Bildschirms statt.

Hier ist eine Arbeitsdemo dieses Ansatzes von Julien .
Es hat eine vielversprechende Webbrowser-Unterstützung.

Und hier eine reine CSS- Implementierung von Willem Van Bockstal .


Die reine CSS-Lösung

Hier ist die alte Antwort. Natürlich habe ich eine neue Methode hinzugefügt und die CSS-Deklarationen verfeinert.

Tabelle mit fester Breite

In diesem Fall tablesollte der Wert fest sein width (einschließlich der Summe der Spaltenbreiten und der Breite der vertikalen Bildlaufleiste). .

Jede Spalte sollte eine bestimmte haben Breite und die letzte Spalte des theadElements eine größere braucht Breite , die zu den anderen gleich Breite + die Breite der vertikalen Scroll-Leiste.

Daher wäre das CSS:

table {
    width: 716px; /* 140px * 5 column + 16px scrollbar width */
    border-spacing: 0;
}

tbody, thead tr { display: block; }

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 140px;
}

thead th:last-child {
    width: 156px; /* 140px + 16px scrollbar width */
}

Hier ist die Ausgabe:

Tabelle mit fester Breite

ARBEITSDEMO .

Tisch mit 100% Breite

Bei diesem Ansatz wird die table eine Breite von 100%und für jedes thund tdder Wert der widthEigenschaft sollte kleiner als sein 100% / number of cols.

Außerdem müssen wir die reduzieren Breite von theadals Wert der Breite der vertikalen Scroll-Leiste.

Dazu müssen wir CSS3 verwenden calc() Funktion wie folgt verwenden:

table {
    width: 100%;
    border-spacing: 0;
}

thead, tbody, tr, th, td { display: block; }

thead tr {
    /* fallback */
    width: 97%;
    /* minus scroll bar width */
    width: -webkit-calc(100% - 16px);
    width:    -moz-calc(100% - 16px);
    width:         calc(100% - 16px);
}

tr:after {  /* clearing float */
    content: ' ';
    display: block;
    visibility: hidden;
    clear: both;
}

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 19%;  /* 19% is less than (100% / 5 cols) = 20% */
    float: left;
}

Hier ist die Online-Demo .

Hinweis: Dieser Ansatz schlägt fehl schlägt wenn der Inhalt jeder Spalte die Zeile durchbricht, dh der Inhalt jeder Zelle sollte kurz genug sein .


Im Folgenden gibt es zwei einfache Beispiele für reine CSS-Lösungen, die ich zum Zeitpunkt der Beantwortung dieser Frage erstellt habe.

Hier ist das jsFiddle Demo v2 .

Alte Version: jsFiddle Demo v1

Hashem Qolami
quelle
17
Mit display: blockIhnen Eigenschaften lösen Tabelle als Spaltenbreite zwischen thead und tbody geteilt. Ich weiß, dass Sie dies durch Einstellen behoben haben, width: 19.2%aber falls wir die Breite jeder Spalte nicht im Voraus kennen, funktioniert dies nicht.
Samb
10
Dieser Code scheint davon auszugehen, dass die Körperzellen immer breiter sind als die Kopfzellen.
Adam Donahue
2
Funktioniert nicht wann height: 100%(wenn die Tabelle bis zum Ende der Seite erweitert werden soll).
AlikElzin-Kilaka
2
Dies funktioniert auch hervorragend mit AngularJS- ng-repeatTabellen. Ich bin mir nicht sicher, warum es all diese Bibliotheken mit festen Tabellenüberschriften gibt und was nicht, wenn es diese Lösung gibt.
Chakeda
2
Sie können dies mit der box-sizingEigenschaft etwas weiter verbessern , damit Ränder mit zwei unterschiedlichen Dicken die Spaltenausrichtung nicht beeinträchtigen.
Ricca
89

In der folgenden Lösung belegt die Tabelle 100% des übergeordneten Containers, ohne dass absolute Größen erforderlich sind. Es ist reines CSS, es wird ein flexibles Layout verwendet.

So sieht es aus: Geben Sie hier die Bildbeschreibung ein

Mögliche Nachteile:

  • Die vertikale Bildlaufleiste ist immer sichtbar, unabhängig davon, ob sie erforderlich ist.
  • Das Tabellenlayout ist festgelegt. Die Größe der Spalten wird nicht entsprechend der Inhaltsbreite geändert (Sie können die gewünschte Spaltenbreite weiterhin explizit festlegen).
  • Es gibt eine absolute Größe - die Breite der Bildlaufleiste, die für die Browser, die ich überprüfen konnte, ungefähr 0,9 em beträgt.

HTML (gekürzt):

<div class="table-container">
    <table>
        <thead>
            <tr>
                <th>head1</th>
                <th>head2</th>
                <th>head3</th>
                <th>head4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            ...
        </tbody>
    </table>
</div>

CSS, wobei einige Dekorationen aus Gründen der Übersichtlichkeit weggelassen wurden:

.table-container {
    height: 10em;
}
table {
    display: flex;
    flex-flow: column;
    height: 100%;
    width: 100%;
}
table thead {
    /* head takes the height it requires, 
    and it's not scaled when table is resized */
    flex: 0 0 auto;
    width: calc(100% - 0.9em);
}
table tbody {
    /* body takes all the remaining available space */
    flex: 1 1 auto;
    display: block;
    overflow-y: scroll;
}
table tbody tr {
    width: 100%;
}
table thead, table tbody tr {
    display: table;
    table-layout: fixed;
}

vollständiger Code auf jsfiddle

Gleicher Code in WENIGER, damit Sie ihn einmischen können:

.table-scrollable() {
  @scrollbar-width: 0.9em;
  display: flex;
  flex-flow: column;

  thead,
  tbody tr {
    display: table;
    table-layout: fixed;
  }

  thead {
    flex: 0 0 auto;
    width: ~"calc(100% - @{scrollbar-width})";
  }

  tbody {
    display: block;
    flex: 1 1 auto;
    overflow-y: scroll;

    tr {
      width: 100%;
    }
  }
}
tsayen
quelle
2
Danke für die Lösung! Es gab einen kleinen Fehler ... Sie haben die Breite für den Kopf zweimal eingestellt, und ich fand, dass das Subtrahieren von 1,05em von der Breite etwas besser ist: jsfiddle.net/xuvsncr2/170
TigerBear
1
Was ist mit der Inhaltsnummer des Zeichens? es bringt es durcheinander, wenn mehr Zeichen oder Wörter in die Zeilenzellen eingefügt werden
Limon
Ich denke, das Setzen einer geeigneten Verpackungsrichtlinie tdsollte helfen
tsayen
Irgendeine Lösung wie diese, aber die Notwendigkeit einer 100% igen Breite fallen zu lassen?
Alexandre Pereira Nunes
2
@tsayen Wie verhindern Sie, dass es sich verkleinert und überlappt, wenn Sie die Fenstergröße ändern?
clearshot66
31

In modernen Browsern können Sie einfach CSS verwenden:

th {
  position: sticky;
  top: 0;
  z-index: 2;
}
Gauß
quelle
8
Diese Beschwörung ist unvollständig ... Möchten Sie ein Beispiel veröffentlichen oder zumindest ausarbeiten?
Liam
funktioniert gut, gilt aber nur für th. Wenn wir die Position auf dem Kopf kleben lassen, funktioniert es nicht.
Vishal
Ein fester Kopf sollte zu W3C hinzugefügt werden!
Sonichy
2
Diese Antwort funktioniert, wenn Sie Ihre <table>mit <div>was hat overflow-y: auto;und einige wickeln max-height. Zum Beispiel:<div style="overflow-y: auto; max-height: 400px;"><table>...</table></div>
Minwork
Ab 2020 ist dies die ausgewählte Antwort (zusammen mit dem Update von @Minwork)
Christophe Vidal
18

Ich benutze display:blockfür theadund tbody. Aus diesem Grund theadunterscheidet sich die Breite der tbodySpalten von der Breite der Spalten.

table {
    margin:0 auto; 
    border-collapse:collapse;
}
thead {
    background:#CCCCCC;
    display:block
}
tbody {
    height:10em;overflow-y:scroll;
    display:block
}

Um dies zu beheben, verwende ich kleinen jQueryCode, der jedoch JavaScriptnur in ausgeführt werden kann.

var colNumber=3 //number of table columns    

for (var i=0; i<colNumber; i++) {
  var thWidth=$("#myTable").find("th:eq("+i+")").width();
  var tdWidth=$("#myTable").find("td:eq("+i+")").width();      
  if (thWidth<tdWidth)                    
      $("#myTable").find("th:eq("+i+")").width(tdWidth);
  else
      $("#myTable").find("td:eq("+i+")").width(thWidth);           
}  

Hier ist meine Arbeitsdemo: http://jsfiddle.net/gavroche/N7LEF/

Funktioniert nicht in IE 8

Gavroche
quelle
Dies ist die beste / einfachste Lösung, die ich gefunden habe und die nicht feste Spaltenbreiten zulässt (z. B. .NET DataGrid-Steuerelement). Für "Produktion" colNumberkönnte die Variable durch Code ersetzt werden, der stattdessen durch tatsächlich gefundene Zellen iteriert, und beachten Sie, dass sie nicht korrekt verarbeitet wird, wenncolspan s vorhanden sind (könnte bei Bedarf auch im Code verbessert werden, ist jedoch in Bezug auf die Art unwahrscheinlich Tabelle, die diese Bildlauffunktion wahrscheinlich haben möchte).
JonBrave
Dies funktioniert (in gewisser Weise), kommt jedoch nicht zurecht, wenn die Fenstergröße kleiner als die Tabelle ist (da die Breite der Bildlaufleiste ignoriert wird).
Gone Coding
Ja, der Header und die Zellen stimmen nicht mehr überein, wenn Ihre Tabellenbreite auf eine festgelegte Breite beschränkt ist
Craig
beste Antwort hier, am einfachsten auch
Charles Okwuagwu
17

Nur CSS

für Chrome, Firefox, Edge (und andere immergrüne Browser)

Einfach position: sticky; top: 0;deine thElemente:

/* Fix table head */
.tableFixHead    { overflow-y: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; }

/* Just common table stuff. */
table  { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th     { background:#eee; }
<div class="tableFixHead">
  <table>
    <thead>
      <tr><th>TH 1</th><th>TH 2</th></tr>
    </thead>
    <tbody>
      <tr><td>A1</td><td>A2</td></tr>
      <tr><td>B1</td><td>B2</td></tr>
      <tr><td>C1</td><td>C2</td></tr>
      <tr><td>D1</td><td>D2</td></tr>
      <tr><td>E1</td><td>E2</td></tr>
    </tbody>
  </table>
</div>

PS: wenn Sie brauchen Grenzen für TH - Elemente th {box-shadow: 1px 1px 0 #000; border-top: 0;}helfen wird (da die Standardgrenzen nicht korrekt auf Scroll gemalt werden).

Eine Variante des oben genannten, die nur ein wenig JS verwendet, um IE11 zu berücksichtigen, finden Sie in dieser Antwort unter https://stackoverflow.com/a/47923622/383904

Roko C. Buljan
quelle
Wenn Sie Rahmen für die Elemente haben, wird bei Verwendung von "Rahmen-Zusammenbruch: Zusammenbruch" der Rand an den Körper anstatt an die Kopfzeile geklebt. Um dieses Problem zu vermeiden, sollten Sie "border -apse: separate" verwenden. Siehe stackoverflow.com/a/53559396
mrod
@mrod Wenn separateSie verwenden, fügen Sie dem Feuer Öl hinzu. jsfiddle.net/RokoCB/o0zL4xyw und sehen Sie HIER eine Lösung : Fügen Sie dem festen TH Rahmen hinzu - ich freue mich über Vorschläge von OFC, wenn ich etwas verpasst habe.
Roko C. Buljan
11

Erstellen Sie zwei Tabellen nacheinander, setzen Sie die zweite Tabelle in ein Div mit fester Höhe und setzen Sie die Überlaufeigenschaft auf auto. Halten Sie auch alle td's im Kopf in der zweiten Tabelle leer.

<div>
    <table>
        <thead>
            <tr>
                <th>Head 1</th>
                <th>Head 2</th>
                <th>Head 3</th>
                <th>Head 4</th>
                <th>Head 5</th>
            </tr>
        </thead>
    </table>
</div>

<div style="max-height:500px;overflow:auto;">
    <table>
        <thead>
            <tr>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody>
        <tr>
            <td>Content 1</td>
            <td>Content 2</td>
            <td>Content 3</td>
            <td>Content 4</td>
            <td>Content 5</td>
        </tr>
        </tbody>
    </table>    
</div>
Sushil Kumar
quelle
8
In diesem Fall können die Spalten der zweiten Tabelle nicht der Breite der ersten Tabelle folgen.
Kat1330
2
Nicht gut! Sie verlieren die Breitensynchronisation für Spalten in zwei Tabellen.
Zafar
1
Um diese Lösung zu vervollständigen, müssen wir das @ Hashem Qolami-Skript (siehe oben ) hinzufügen, um die Breite der Header-Spalten zu synchronisieren
Elhay Avichzer
6

Ich habe es mit reinem CSS endlich richtig gemacht, indem ich diese Anweisungen befolgt habe:

http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

Der erste Schritt besteht darin, den <tbody>anzuzeigenden Block so einzustellen , dass ein Überlauf und eine Höhe angewendet werden können. Von dort aus müssen die Zeilen in der <thead>Position positioniert werden: relativ und Anzeige: blockieren, damit sie oben auf dem jetzt scrollbaren sitzen <tbody>.

tbody, thead { display: block; overflow-y: auto; }

Da die <thead>relativ positioniert ist, benötigt jede Tabellenzelle eine explizite Breite

td:nth-child(1), th:nth-child(1) { width: 100px; }
td:nth-child(2), th:nth-child(2) { width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Das reicht aber leider nicht aus. Wenn eine Bildlaufleiste vorhanden ist, weisen die Browser ihr Speicherplatz zu. Daher steht dem Browser <tbody>weniger Speicherplatz zur Verfügung als dem <thead>. Beachten Sie die leichte Fehlausrichtung, die dadurch entsteht ...

Die einzige Problemumgehung, die ich finden konnte, bestand darin, für alle Spalten außer der letzten eine Mindestbreite festzulegen.

td:nth-child(1), th:nth-child(1) { min-width: 100px; }
td:nth-child(2), th:nth-child(2) { min-width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Beispiel für einen ganzen Codepen unten:

CSS:

.fixed_headers {
  width: 750px;
  table-layout: fixed;
  border-collapse: collapse;
}
.fixed_headers th {
  text-decoration: underline;
}
.fixed_headers th,
.fixed_headers td {
  padding: 5px;
  text-align: left;
}
.fixed_headers td:nth-child(1),
.fixed_headers th:nth-child(1) {
  min-width: 200px;
}
.fixed_headers td:nth-child(2),
.fixed_headers th:nth-child(2) {
  min-width: 200px;
}
.fixed_headers td:nth-child(3),
.fixed_headers th:nth-child(3) {
  width: 350px;
}
.fixed_headers thead {
  background-color: #333333;
  color: #fdfdfd;
}
.fixed_headers thead tr {
  display: block;
  position: relative;
}
.fixed_headers tbody {
  display: block;
  overflow: auto;
  width: 100%;
  height: 300px;
}
.fixed_headers tbody tr:nth-child(even) {
  background-color: #dddddd;
}
.old_ie_wrapper {
  height: 300px;
  width: 750px;
  overflow-x: hidden;
  overflow-y: auto;
}
.old_ie_wrapper tbody {
  height: auto;
}

Html:

<!-- IE < 10 does not like giving a tbody a height.  The workaround here applies the scrolling to a wrapped <div>. -->
<!--[if lte IE 9]>
<div class="old_ie_wrapper">
<!--<![endif]-->

<table class="fixed_headers">
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Plum</td>
      <td>Purple</td>
      <td>These are Purple</td>
    </tr>
    <tr>
      <td>Watermelon</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Tomato</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cherry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cantelope</td>
      <td>Orange</td>
      <td>These are orange inside.</td>
    </tr>
    <tr>
      <td>Honeydew</td>
      <td>Green</td>
      <td>These are green inside.</td>
    </tr>
    <tr>
      <td>Papaya</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Raspberry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Blueberry</td>
      <td>Blue</td>
      <td>These are blue.</td>
    </tr>
    <tr>
      <td>Mango</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Passion Fruit</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

<!--[if lte IE 9]>
</div>
<!--<![endif]-->

EDIT: Alternative Lösung für Tabellenbreite 100% (oben ist eigentlich für feste Breite und hat die Frage nicht beantwortet):

HTML:

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

CSS:

table {
  width: 100%;
  text-align: left;
  min-width: 610px;
}
tr {
  height: 30px;
  padding-top: 10px
}
tbody { 
  height: 150px; 
  overflow-y: auto;
  overflow-x: hidden;
}
th,td,tr,thead,tbody { display: block; }
td,th { float: left; }
td:nth-child(1),
th:nth-child(1) {
  width: 20%;
}
td:nth-child(2),
th:nth-child(2) {
  width: 20%;
  float: left;
}
td:nth-child(3),
th:nth-child(3) {
  width: 59%;
  float: left;
}
/* some colors */
thead {
  background-color: #333333;
  color: #fdfdfd;
}
table tbody tr:nth-child(even) {
  background-color: #dddddd;
}

Demo: http://codepen.io/anon/pen/bNJeLO

Mikael Lepistö
quelle
1
Die Frage wollte speziell eine Tabelle mit 100% Breite, was das einzige ist, was das Beispiel, auf das Sie verwiesen haben , nicht tut.
Gone Coding
@TrueBlueAussie Guter Fang: D Alternative Lösung für 100% Breite hinzugefügt.
Mikael Lepistö
Sie berücksichtigen nicht die Länge des Inhalts der Zellenzeile
Limon
2

CSS-Problemumgehung zum Erzwingen der korrekten Anzeige von Spalten mit einem 'Block'-Tbody

Für diese Lösung müssen die thBreiten weiterhin von jQuery berechnet und festgelegt werden

table.scroll tbody,
table.scroll thead { display: block; }

table.scroll tbody {
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 300px;
}

table.scroll tr {
    display: flex;
}

table.scroll tr > td {
    flex-grow: 1;
    flex-basis: 0;
}

Und das Jquery / Javascript

var $table = $('#the_table_element'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

$table.addClass('scroll');

// Adjust the width of thead cells when window resizes
$(window).resize(function () {

    // Get the tbody columns width array
    colWidth = $bodyCells.map(function () {
        return $(this).width();
    }).get();

    // Set the width of thead columns
    $table.find('thead tr').children().each(function (i, v) {
        $(v).width(colWidth[i]);
    });

}).resize(); // Trigger resize handler
Emmanuel
quelle
@Craig im Jahr 2019 ist es völlig in Ordnung, sich überhaupt nicht um IE zu kümmern.
Automagisch
2

Versuchen Sie unten Ansatz, sehr einfach leicht zu implementieren

Unten ist der jsfiddle Link

http://jsfiddle.net/v2t2k8ke/2/

HTML:

<table border='1' id='tbl_cnt'>
<thead><tr></tr></thead><tbody></tbody>

CSS:

 #tbl_cnt{
 border-collapse: collapse; width: 100%;word-break:break-all;
 }
 #tbl_cnt thead, #tbl_cnt tbody{
 display: block;
 }
 #tbl_cnt thead tr{
 background-color: #8C8787; text-align: center;width:100%;display:block;
 }
 #tbl_cnt tbody {
 height: 100px;overflow-y: auto;overflow-x: hidden;
 }

Jquery:

 var data = [
    {
    "status":"moving","vehno":"tr544","loc":"bng","dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che", "dri":"ttt"
    },{    "status":"idle","vehno":"yy5499999999999994","loc":"bng","dri":"ttt"
    },{
    "status":"moving","vehno":"tr544","loc":"bng", "dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che","dri":"ttt"
    },{
    "status":"idle","vehno":"yy544","loc":"bng","dri":"ttt"
    }
    ];
   var sth = '';
   $.each(data[0], function (key, value) {
     sth += '<td>' + key + '</td>';
   });
   var stb = '';        
   $.each(data, function (key, value) {
       stb += '<tr>';
       $.each(value, function (key, value) {
       stb += '<td>' + value + '</td>';
       });
       stb += '</tr>';
    });
      $('#tbl_cnt thead tr').append(sth);
      $('#tbl_cnt tbody').append(stb);
      setTimeout(function () {
      var col_cnt=0 
      $.each(data[0], function (key, value) {col_cnt++;});    
      $('#tbl_cnt thead tr').css('width', ($("#tbl_cnt tbody") [0].scrollWidth)+ 'px');
      $('#tbl_cnt thead tr td,#tbl_cnt tbody tr td').css('width',  ($('#tbl_cnt thead tr ').width()/Number(col_cnt)) + 'px');}, 100)
Nandha
quelle
2
Diese Lösung bewältigt nicht, dass das Fenster schmaler als die Tischbreite ist. In diesem Fall sollte das horizontale Scrollen aktiviert sein. Außerdem stimmen die Überschriften nicht genau mit den Datenzellen (Chrome) überein.
Gone Coding
2

Das Hinzufügen einer festen Breite zu td, th nach dem Erstellen von tbody & thead display block funktioniert einwandfrei und wir können auch das slimscroll- Plugin verwenden, um die Bildlaufleiste schön zu machen.

Geben Sie hier die Bildbeschreibung ein

<!DOCTYPE html>
<html>

<head>
    <title> Scrollable table </title>
    <style>
        body {
            font-family: sans-serif;
            font-size: 0.9em;
        }
        table {
            border-collapse: collapse;
            border-bottom: 1px solid #ddd;
        }
        thead {
            background-color: #333;
            color: #fff;
        }
        thead,tbody {
            display: block;
        }
        th,td {
            padding: 8px 10px;
            border: 1px solid #ddd;
            width: 117px;
            box-sizing: border-box;
        }
        tbody {
            height: 160px;
            overflow-y: scroll
        }
    </style>
</head>

<body>

    <table class="example-table">
        <thead>
            <tr>
                <th> Header 1 </th>
                <th> Header 2 </th>
                <th> Header 3 </th>
                <th> Header 4 </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td> Row 1- Col 1 </td>
                <td> Row 1- Col 2 </td>
                <td> Row 1- Col 3 </td>
                <td> Row 1- Col 4 </td>
            </tr>
            <tr>
                <td> Row 2- Col 1 </td>
                <td> Row 2- Col 2 </td>
                <td> Row 2- Col 3 </td>
                <td> Row 2- Col 4 </td>
            </tr>
            <tr>
                <td> Row 3- Col 1 </td>
                <td> Row 3- Col 2 </td>
                <td> Row 3- Col 3 </td>
                <td> Row 3- Col 4 </td>
            </tr>
            <tr>
                <td> Row 4- Col 1 </td>
                <td> Row 4- Col 2 </td>
                <td> Row 4- Col 3 </td>
                <td> Row 4- Col 4 </td>
            </tr>
            <tr>
                <td> Row 5- Col 1 </td>
                <td> Row 5- Col 2 </td>
                <td> Row 5- Col 3 </td>
                <td> Row 5- Col 4 </td>
            </tr>
            <tr>
                <td> Row 6- Col 1 </td>
                <td> Row 6- Col 2 </td>
                <td> Row 6- Col 3 </td>
                <td> Row 6- Col 4 </td>
            </tr>
            <tr>
                <td> Row 7- Col 1 </td>
                <td> Row 7- Col 2 </td>
                <td> Row 7- Col 3 </td>
                <td> Row 7- Col 4 </td>
            </tr>
            <tr>
                <td> Row 8- Col 1 </td>
                <td> Row 8- Col 2 </td>
                <td> Row 8- Col 3 </td>
                <td> Row 8- Col 4 </td>
            </tr>
            <tr>
                <td> Row 9- Col 1 </td>
                <td> Row 9- Col 2 </td>
                <td> Row 9- Col 3 </td>
                <td> Row 9- Col 4 </td>
            </tr>
            <tr>
                <td> Row 10- Col 1 </td>
                <td> Row 10- Col 2 </td>
                <td> Row 10- Col 3 </td>
                <td> Row 10- Col 4 </td>
            </tr>
            <tr>
                <td> Row 11- Col 1 </td>
                <td> Row 11- Col 2 </td>
                <td> Row 11- Col 3 </td>
                <td> Row 11- Col 4 </td>
            </tr>
            <tr>
                <td> Row 12- Col 1 </td>
                <td> Row 12- Col 2 </td>
                <td> Row 12- Col 3 </td>
                <td> Row 12- Col 4 </td>
            </tr>
            <tr>
                <td> Row 13- Col 1 </td>
                <td> Row 13- Col 2 </td>
                <td> Row 13- Col 3 </td>
                <td> Row 13- Col 4 </td>
            </tr>
            <tr>
                <td> Row 14- Col 1 </td>
                <td> Row 14- Col 2 </td>
                <td> Row 14- Col 3 </td>
                <td> Row 14- Col 4 </td>
            </tr>
            <tr>
                <td> Row 15- Col 1 </td>
                <td> Row 15- Col 2 </td>
                <td> Row 15- Col 3 </td>
                <td> Row 15- Col 4 </td>
            </tr>
            <tr>
                <td> Row 16- Col 1 </td>
                <td> Row 16- Col 2 </td>
                <td> Row 16- Col 3 </td>
                <td> Row 16- Col 4 </td>
            </tr>
        </tbody>
    </table>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js"></script>
    <script>
        $('.example-table tbody').slimscroll({
            height: '160px',
            alwaysVisible: true,
            color: '#333'
        })
    </script>
</body>

</html>

Codegeek
quelle
1

Dies ist der Code, mit dem ich einen klebrigen Kopf auf einem Tisch mit einem scrollbaren Körper erstellen kann:

table ,tr td{
    border:1px solid red
}
tbody {
    display:block;
    height:50px;
    overflow:auto;
}
thead, tbody tr {
    display:table;
    width:100%;
    table-layout:fixed;/* even columns width , fix width of table too*/
}
thead {
    width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
}
table {
    width:400px;
}
Max Alexander Hanna
quelle
1

Um "overflow: scroll" zu verwenden, müssen Sie "display: block" für thead und tbody einstellen. Und das bringt die Spaltenbreiten zwischen ihnen durcheinander. Dann können Sie die Thead-Zeile mit Javascript klonen und als versteckte Zeile in den tbody einfügen, um die genauen Spaltenbreiten beizubehalten.

$('.myTable thead > tr').clone().appendTo('.myTable tbody').addClass('hidden-to-set-col-widths');

http://jsfiddle.net/Julesezaar/mup0c5hk/

<table class="myTable">
    <thead>
        <tr>
            <td>Problem</td>
            <td>Solution</td>
            <td>blah</td>
            <td>derp</td>
        </tr>
    </thead>
    <tbody></tbody>
</table>
<p>
  Some text to here
</p>

Das CSS:

table {
  background-color: #aaa;
  width: 100%;
}

thead,
tbody {
  display: block; // Necessary to use overflow: scroll
}

tbody {
  background-color: #ddd;
  height: 150px;
  overflow-y: scroll;
}

tbody tr.hidden-to-set-col-widths,
tbody tr.hidden-to-set-col-widths td {
  visibility: hidden;
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
}

td {
  padding: 3px 10px;
}
Julesezaar
quelle
0

Versuchen Sie diese jsfiddle . Dies verwendet jQuery und basiert auf der Antwort von Hashem Qolami. Erstellen Sie zunächst eine reguläre Tabelle und machen Sie sie dann scrollbar.

const makeScrollableTable = function (tableSelector, tbodyHeight) {
  let $table = $(tableSelector);
  let $bodyCells = $table.find('tbody tr:first').children();
  let $headCells = $table.find('thead tr:first').children();
  let headColWidth = 0;
  let bodyColWidth = 0;

  headColWidth = $headCells.map(function () {
    return $(this).outerWidth();
  }).get();
  bodyColWidth = $bodyCells.map(function () {
    return $(this).outerWidth();
  }).get();

  $table.find('thead tr').children().each(function (i, v) {
    $(v).css("width", headColWidth[i]+"px");
    $(v).css("min-width", headColWidth[i]+"px");
    $(v).css("max-width", headColWidth[i]+"px");
  });
  $table.find('tbody tr').children().each(function (i, v) {
    $(v).css("width", bodyColWidth[i]+"px");
    $(v).css("min-width", bodyColWidth[i]+"px");
    $(v).css("max-width", bodyColWidth[i]+"px");
  });

  $table.find('thead').css("display", "block");
  $table.find('tbody').css("display", "block");

  $table.find('tbody').css("height", tbodyHeight+"px");
  $table.find('tbody').css("overflow-y", "auto");
  $table.find('tbody').css("overflow-x", "hidden");

};
die Katze
quelle