HOWTO · HTML

HTML テーブルの列幅を設定する

CSS、colgroup、table-layout、セレクター、オーバーフロー処理を使って、HTML テーブルの列幅を予測可能に設定する方法を説明します。

このページの内容

CSS を使って HTML テーブルとその列の幅を設定します。保守しやすいテーブルでは、 で列幅を定義し、テーブルにその比率を守らせる必要がある場合は table-layout: fixed を使います。内容が収まらないとブラウザーが列を調整することもあるため、以下の例ではその境界の扱いも示します。

CSS で列幅を設定する

や
の古い width 属性は廃止された HTML です。ブラウザーは従来のマークアップを解釈できますが、新しいコードでは表示規則を CSS に置きます。割合はテーブルの使用幅を基準にするため、テーブル自体が親要素から利用可能な幅を得る必要があります。

小規模な一度限りのテーブルなら、<th style="width: 15%">ID</th> のようなインライン指定で十分です。再利用するコンポーネントでは、スタイルシートまたは <colgroup> を使い、データセルを含む列全体に規則を適用します。

<style>
.people {
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
}

.people th,
.people td {
  border: 1px solid black;
  overflow-wrap: anywhere;
}

.people .id-column { width: 15%; }
.people .name-column { width: 70%; }
.people .age-column { width: 15%; }
</style>
<table class="people">
  <colgroup>
    <col class="id-column">
    <col class="name-column">
    <col class="age-column">
  </colgroup>
  <thead>
    <tr><th scope="col">ID</th><th scope="col">Name</th><th scope="col">Age</th></tr>
  </thead>
  <tbody>
    <tr><td>1</td><td>John</td><td>25</td></tr>
    <tr><td>2</td><td>Jackson</td><td>40</td></tr>
  </tbody>
</table>

3 つの割合の合計は 100% なので、初期配分は明確です。Name は ID と Age より広くなります。table-layout: fixed では、各行の最長セルではなく、主にテーブル幅、明示した列幅、最初の行によってサイズが決まります。overflow-wrap: anywhere は、非常に長い値をテーブルの幅を広げずに折り返します。

<colgroup> はテーブルの行グループより前に置きます。<col> は列を表し、表示されるセルではなく、独自の内容も持ちません。連続する列で同じ規則を使う場合は <col> に span を指定します。この方法は HTML の意味構造も保ちます。見出しには <th> と scope="col" を使い、支援技術が見出しとセルを関連付けられるようにします。

クラスと :nth-child() を比較する

.people th:nth-child(1) { width: 15%; }、.people th:nth-child(2) { width: 70%; }、.people th:nth-child(3) { width: 15%; } のようなセレクターで最初の行に幅を設定できます。各見出しにクラスを追加せず、クラス方式と :nth-child() の手法を利用できます。列の意味が重要ならクラスの方が明確で、列順が単純で安定しているなら :nth-child() が便利です。

行に colspan が含まれる場合、見出し行の構造が異なる場合、列を並べ替える場合は :nth-child() に依存しないでください。その場合は <colgroup> や名前付きクラスで列の対応を明示します。一部の幅だけを指定すると、ブラウザーが残りの空間を配分します。自動レイアウトで未指定の列が常に正確な割合になるとは限りません。

収まらない内容を扱う

固定レイアウトでも、狭い列があらゆる値を収められるほど広くなるわけではありません。改行できない長い URL や識別子は、折り返せないとあふれることがあります。次の境界例では幅の規則を維持し、ページレイアウトを変えずにセルを水平方向へスクロールさせます。

<style>
  .compact {
    table-layout: fixed;
    width: 320px;
  }
  .compact th,
  .compact td {
    max-width: 0;
    overflow: hidden;
    overflow-wrap: anywhere;
  }
  .compact td.code {
    overflow-x: auto;
    white-space: nowrap;
  }
</style>
<table class="compact">
  <colgroup><col style="width: 25%"><col style="width: 75%"></colgroup>
  <tr><th scope="col">Type</th><th scope="col">Value</th></tr>
  <tr><td>URL</td><td class="code">https://example.com/a-very-long-value-without-spaces</td></tr>
</table>

通常の文章では、横スクロールより折り返しが適しています。現実的な内容と狭いビューポート幅でテーブルをテストしてください。幅はテーブルレイアウトアルゴリズムが解釈するヒントであり、すべてのセルが正確なピクセルサイズを保つ保証ではありません。