← Back to DevBytes

CSS 'table-layout' Property: Complete Reference

CSS table-layout Property: Complete Reference

The table-layout property in CSS controls the algorithm used to lay out table cells, rows, and columns. It determines how the browser calculates the width of table columns and ultimately affects rendering performance, predictability, and design control.

What Is the table-layout Property?

The table-layout property accepts two values:

The property applies to all table elements (<table>, <thead>, <tbody>, <tfoot>, <tr>, <td>, <th>), but it is most commonly set on the <table> element itself.

Why It Matters

Choosing the correct table-layout value directly impacts:

How to Use the table-layout Property

To use the property, simply apply it to a table element:

/* Fixed layout */
table {
  table-layout: fixed;
  width: 100%;
}

/* Auto layout (default) */
table {
  table-layout: auto;
  width: 100%;
}

Example 1: Default Auto Layout

In this example, column widths are determined by the content. The first row’s cell widths influence the rest, but long content can expand the column.

<!DOCTYPE html>
<html>
<head>
  <style>
    table {
      width: 100%;
      border-collapse: collapse;
    }
    th, td {
      border: 1px solid #ccc;
      padding: 8px;
    }
  </style>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>Short Header</th>
        <th>Very Long Header That Expands</th>
        <th>Medium</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>A</td>
        <td>B</td>
        <td>C</td>
      </tr>
    </tbody>
  </table>
</body>
</html>

With table-layout: auto (default), the second column will be wider than the first because of its long header content.

Example 2: Fixed Layout with Explicit Column Widths

Using fixed, you can assign specific widths to columns via the first row or <col> elements. The table will honor those widths regardless of content.

<!DOCTYPE html>
<html>
<head>
  <style>
    table {
      table-layout: fixed;
      width: 100%;
      border-collapse: collapse;
    }
    th, td {
      border: 1px solid #999;
      padding: 8px;
    }
    .col1 { width: 20%; }
    .col2 { width: 50%; }
    .col3 { width: 30%; }
  </style>
</head>
<body>
  <table>
    <colgroup>
      <col class="col1">
      <col class="col2">
      <col class="col3">
    </colgroup>
    <thead>
      <tr>
        <th>Name</th>
        <th>Description</th>
        <th>Price</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Widget</td>
        <td>A very long description that would normally stretch the column, but with fixed layout it is clipped or overflows.</td>
        <td>$9.99</td>
      </tr>
    </tbody>
  </table>
</body>
</html>

In this fixed layout, the second column remains 50% of the table width even though its content is long. To handle overflow, you can add:

td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

Example 3: Fixed Layout Without Explicit Column Widths

If no column widths are specified, the browser will divide the table width equally among all columns.

<table style="table-layout: fixed; width: 600px;">
  <tr>
    <td>Column 1</td>
    <td>Column 2</td>
    <td>Column 3</td>
  </tr>
  <tr>
    <td>Content</td>
    <td>More content</td>
    <td>Even more content that may overflow</td>
  </tr>
</table>

All three columns will be 200px wide (600px / 3).

Example 4: Mixing Fixed and Auto in the Same Table

You can set some columns explicitly and let others share the remaining space by omitting widths. However, the overall algorithm remains fixed.

<table style="table-layout: fixed; width: 100%;">
  <colgroup>
    <col style="width: 150px;">
    <col>  <!-- no explicit width -->
    <col style="width: 100px;">
  </colgroup>
  <tr>
    <td>150px</td>
    <td>Remaining space</td>
    <td>100px</td>
  </tr>
</table>

The second column will take the remaining width after subtracting 250px (150+100) from the table’s total width.

Best Practices

Practical Use Case: Creating a Fixed‑Width Calendar Grid

When building a calendar table where each day cell must have the same width, table-layout: fixed is ideal.

<!DOCTYPE html>
<html>
<head>
  <style>
    .calendar {
      table-layout: fixed;
      width: 700px;
      border-collapse: collapse;
    }
    .calendar th, .calendar td {
      width: 100px; /* 700px / 7 days */
      height: 80px;
      border: 1px solid #aaa;
      text-align: center;
      vertical-align: top;
    }
  </style>
</head>
<body>
  <table class="calendar">
    <thead>
      <tr>
        <th>Sun</th>
        <th>Mon</th>
        <th>Tue</th>
        <th>Wed</th>
        <th>Thu</th>
        <th>Fri</th>
        <th>Sat</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
      <tr>
        <td>8</td>
        <td>9</td>
        <td>10</td>
        <td>11</td>
        <td>12</td>
        <td>13</td>
        <td>14</td>
      </tr>
      <!-- additional rows -->
    </tbody>
  </table>
</body>
</html>

Every day cell is exactly 100px wide, regardless of the length of the day number or any additional content.

Conclusion

The table-layout property is a small but powerful tool in CSS that governs how tables allocate space to their columns. By understanding the difference between auto (content‑driven, slower) and fixed (explicit, fast, and predictable), you can make informed decisions about performance, design consistency, and content handling. For modern web layouts where control and speed are critical, table-layout: fixed is often the better choice—especially when combined with explicit column widths and overflow management. Use auto only when you need the table to adapt dynamically to variable content and performance is not a primary concern. Mastering this property will help you build robust, maintainable table structures that behave exactly as you intend.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles