Faking Min Width on a Table Column

Avatar of Anders Pedersen
Anders Pedersen am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

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.