Der gute alte <table>-Tag ist das semantisch korrekteste HTML zur Anzeige tabellarischer Daten. Aber ich finde es sehr schwierig zu steuern, wie die Tabelle dargestellt wird, insbesondere die Spaltenbreiten in einer dynamischen Umgebung, in der man möglicherweise nicht weiß, wie viele Inhalte in jede Tabellenzelle kommen. In einigen Fällen ist eine Spalte superbreit, während andere zusammengedrückt werden. Manchmal erhalten wir gleiche Breiten, aber auf Kosten einer Spalte, die mehr Inhalt enthält und mehr Platz benötigt.
Aber ich habe einen CSS-Tricks-ähnlichen Workaround gefunden, der die Dinge ein wenig erleichtert. Das möchte ich Ihnen in diesem Beitrag zeigen.
Das Problem
Zuerst müssen wir verstehen, wie das Layout vom Browser gehandhabt wird. Wir haben die table-layout-Eigenschaft in CSS, um zu definieren, wie eine Tabelle die Breite für jede Tabellenspalte verteilen soll. Sie nimmt einen von zwei Werten an:
auto(Standard)fixed
Beginnen wir mit einer Tabelle, ohne Breiten für ihre Spalten zu definieren. Mit anderen Worten, wir lassen den Browser entscheiden, wie viel Breite er jeder Spalte gibt, indem wir table-layout: auto in CSS darauf anwenden. Wie Sie bemerken werden, tut der Browser sein Bestes mit dem Algorithmus, den er hat, um die gesamte verfügbare Breite auf die einzelnen Spalten zu verteilen.
Wenn wir ein automatisches Tabellenlayout durch table-layout: fixed ersetzen, teilt der Browser einfach den gesamten verfügbaren Platz durch die Gesamtzahl der Spalten und wendet diesen Wert als Breite für jede Spalte an.
Aber was ist, wenn wir die Breiten unserer Spalten steuern wollen? Dafür haben wir das <colgroup>-Element! Es besteht aus einzelnen <col>-Elementen, mit denen wir die genaue Breite für jede Spalte festlegen können. Sehen wir uns an, wie das mit table-layout: auto funktioniert.
Ich habe die Stile zur Veranschaulichung inline gesetzt.
Der Browser beachtet die Inline-Breiten nicht, da sie in Summe den verfügbaren Tabellenplatz überschreiten. Infolgedessen stiehlt die Tabelle Platz von den Spalten, damit alle Spalten sichtbar sind. Das ist ein vollkommen in Ordnung Standardverhalten.
Wie funktioniert <colgroup> mit table-layout: fixed? Finden wir es heraus.
Das sieht überhaupt nicht gut aus. Wir brauchen die Spalte mit dem vielen Inhalt, um sich ein wenig zu strecken, während die restlichen Spalten eine feste Breite behalten. Ein fester table-layout-Wert respektiert die Breite – aber so sehr, dass er den Platz der Spalte frisst, die am meisten Platz benötigt ... was für uns nicht in Frage kommt.
Das könnte leicht gelöst werden, wenn wir der Spalte nur eine min-width statt einer width zuweisen könnten. Auf diese Weise würde die Spalte sagen: "Ich kann euch allen etwas von meiner Breite geben, bis wir diesen Minimalwert erreicht haben." Dann würde die Tabelle einfach über ihren Container hinausgehen und dem Benutzer ein horizontales Scrollen zur Anzeige des Restes der Tabelle bieten. Aber leider werden min-width für Tabellenspalten vom <col>-Element nicht beachtet.
Die Lösung
Die Lösung ist, eine min-width zu fälschen, und wir müssen dafür ein wenig kreativ sein.
Wir können ein leeres <col> als zweite Spalte für unser <colgroup> im HTML hinzufügen und ein colspan-Attribut auf die erste Spalte anwenden, damit die erste Spalte den Platz für beide Spalten einnimmt.
<table>
<colgroup>
<col class="col-200" />
<col />
<col class="col-input" />
<col class="col-date" />
<col class="col-edit" />
</colgroup>
<thead>
<tr>
<th colspan="2">Project name</th>
<th>Amount</th>
<th>Date</th>
<th>Edit</th>
</tr>
</thead>
<!-- etc. -->
</table>
Beachten Sie, dass ich im Vergleich zum vorherigen Beispiel Klassen anstelle von Inline-Stilen hinzugefügt habe. Die gleiche Idee gilt immer noch: Wir weisen jeder Spalte Breiten zu.
Der Trick liegt in der Beziehung zwischen dem ersten <col> und dem leeren zweiten <col>. Wenn wir dem ersten <col> eine Breite zuweisen (im obigen Snippet 200px), wird die zweite Spalte "gefressen", wenn das feste Tabellenlayout den verfügbaren Platz auf die Spalten verteilt. Aber die Breite der ersten Spalte (200px) wird respektiert und bleibt bestehen.
Voilà! Wir haben eine gefälschte min-width für eine Tabellenzelle. Die erste Zelle dehnt sich, wenn sich der verfügbare Platz ändert, und die Tabelle wird wie erhofft horizontal scrollbar.
(Ich habe der ersten Spalte hier ein wenig Sticky-Positionierung hinzugefügt.)
Barrierefreiheit (Accessibility)
Vergessen wir die Barrierefreiheit nicht ganz. Ich habe die Tabelle mit NVDA unter Windows und VoiceOver unter macOS durchlaufen und festgestellt, dass alle fünf Spalten angesagt werden, auch wenn wir nur vier davon verwenden. Und wenn die erste Spalte im Fokus ist, wird sie als "Spalte eins bis zwei" angesagt. Nicht perfekt elegant, aber auch nicht so, dass jemand verloren geht. Ich stelle mir vor, wir könnten ein aria-hidden-Attribut auf die ungenutzte Spalte legen, aber man weiß auch, dass ARIA kein Ersatz für schlechtes HTML ist.
Ich gebe zu, das fühlt sich ein wenig, äh, hacky an. Aber es funktioniert! Lassen Sie mich wissen, wenn Sie in den Kommentaren einen anderen Ansatz haben ... oder von Verwirrungen wissen, die dieser "Hack" bei unseren Benutzern hervorrufen könnte.
Das leere
colfühlt sich an, als würde es die Semantik der Tabelle ein wenig brechen.Eine weitere mögliche Lösung wäre die Verwendung von
maxundcalcmitvw-Einheiten zur Bestimmung der Größe der ersten Spalte – so etwas wieWenn die Tabelle eine maximale Breite hat, müssten Sie
clampverwenden, um die Breite der Spalte festzulegen, sobald die Tabelle ihre maximale Breite erreicht hat.Demo: https://codepen.io/chriskoelle/pen/NWBpOKJ
Diese Lösung könnte zugegebenermaßen wesentlich komplizierter werden, je nach Layout der Seite, die die Tabelle umgibt.
Interessant. Wie sind Sie auf 680px gekommen?
Ich mache das ständig mit Angular- und PrimeNG-Tabellen, nur dass ich es sicherer finde, %s anstelle von pxs zu verwenden. Normalerweise lasse ich eine Spalte auf "auto".
Warum nicht einfach display grid mit table verwenden und trs, thead, tfoot, tbody auf display contents setzen? Dann können Sie die Leistung von grid nutzen, um die Tabelle nach Belieben zu formatieren.
Das ist auch eine Möglichkeit, es zu tun. Ich weiß, dass es Probleme mit css display content gab, die die Semantik durcheinanderbrachten. Das Problem ist hier noch offen: https://github.com/w3c/csswg-drafts/issues/3040
Ich weiß nicht, ob es immer noch ein Problem ist – ich habe es in letzter Zeit nicht getestet.