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:
auto(default) – The browser uses a multi-pass algorithm that considers the content of each cell. Column widths are calculated dynamically based on the widest content in each column.fixed– Column widths are determined solely by the table’swidthand the first row’s cell widths (or explicit<col>/<colgroup>widths). Content beyond the set width is either clipped or overflowed (depending onoverflow), but the layout does not change after the first pass.
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:
- Rendering speed:
fixedlayout is significantly faster because the browser only needs one pass to determine column widths.autocan require multiple passes, especially on large tables. - Design predictability: With
fixed, you gain precise control over column widths, which is essential for grid-like layouts or when you need columns to align with external elements. - Content behavior:
autoadapts to content, which is great for text-heavy tables but can cause unwanted layout shifts.fixedmay require explicit handling of long content viaoverflow,word-break, ortext-overflow.
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
- Use
fixedlayout for predictable grids – When you need columns to align with a design mockup or with other elements (e.g., in a dashboard),fixedis the way to go. - Always set a
widthon the table when usingfixed– Without an explicit table width, the browser may not have a reference to distribute column widths, leading to unexpected results. - Define column widths in the first row or via
<col>– Forfixedto work as expected, the first row (or<col>elements) must contain width hints. Otherwise all columns get equal width. - Combine with
overflowandtext-overflowfor long content – Fixed tables often clip content. Useoverflow: hiddenandtext-overflow: ellipsisto keep the layout clean while still indicating truncated text. - Reserve
autofor content-driven tables – If the table’s content varies significantly and you want columns to automatically expand to fit, useauto. Be aware of performance implications for large tables (hundreds of rows or more). - Test across browsers – While
table-layoutis widely supported, subtle differences in how browsers calculate minimum and maximum column widths can occur, especially withauto. - Avoid using
table-layout: autoinside responsive layouts – Auto-layout tables can cause horizontal overflow on small screens. Consider usingfixedwith percentage-based widths and horizontal scrolling if necessary.
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.