CSS Tutorial / CSS Tables: Borders, Sizing, and table-layout
CSS table layout distributes column space according to the table's sizing rules and content. table-layout: auto considers cell content, while fixed layout can make column sizing more predictable when the table has an explicit width.
Separate table width and cell padding
table { width: 100%; border-collapse: collapse; }
th, td { padding: 12px; border: 1px solid #aaa; text-align: start; }
width: 100% tells the table to size itself based on the width of its parent. The space inside the cell is set to padding, and the border is set to border. border-collapse: Collapse is a method of displaying the borders of adjacent cells by merging them. Setting the width of the table and setting line breaks in the content are separate.
A table with width: 100% does not always fit within its parent. Non-wrapable content or a large minimum width may cause the actual table or cell content to be wider. In typical data tables, it is safe to leave cell heights growing to match the sentence length. If you give a fixed height, you need to check for truncation when enlarging text or adding content.
Allocate columns according to their content
<colgroup> <col style="width: 30%;"> <col style="width: 70%;"> </colgroup>
The exercise splits the short item name and long description into two columns. I chose a 30:70 ratio because I needed more space for the description. If the actual data consists of dates, prices, long descriptions, etc., distribute them according to the role of each column. If the default automatic placement is sufficiently readable, there is no need to force the ratio.
When specifying a percentage of the entire column, as shown here, set the sum to 100%. Do not view the colgroup width declaration as a final result that is enforced under any circumstances. Auto-layout works together with the minimum size of the content and table calculations. Please refer to the colgroup description in MDN.
Compare automatic and fixed layout
| value | Column Width Calculation | Things to check in the long content |
|---|---|---|
| table-layout: auto | Calculate based on cell contents | Long values can cause tables or columns to become large. |
| table-layout: fixed | Use the specified table width, column and first row width, etc. | Long content in back cells may overflow or be truncated |
Fixed table layout requires a specified table width; width: auto does not produce the intended fixed calculation. Here both tables use width: 100% and the same column group, differing only in table-layout. If a cell clips text, check its wrapping and ellipsis conditions separately. See MDN: table layout, CSS Overflow, Long Text Wrapping, and Ellipsis.
The data below contains long reservation codes that we want to display without line breaks. The full example applies nowrap·hidden·ellipsis to this cell identically to both tables. Automatic layout can be expanded to reflect the space of long values, and fixed layout can be shortened within a given column. The original text is provided in its entirety in a separate paragraph, so you can check the truncated code as well.
| item | explanation |
|---|---|
| What you need | Bring a water bottle and comfortable shoes. |
| reservation code | GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ |
| Visit information | Even if long information sentences span multiple lines, the cell height is increased to match the content. |
Scroll the table region on narrow screens
.table-scroll { overflow-x: auto; }
table { width: 100%; min-width: 32rem; }
If your root font size is 16px, then 32rem is 512px. If the available width on the screen is less than that, the table will maintain its minimum width and only the parent area will scroll horizontally. This must be distinguished from sliding the entire page horizontally. The 32rem in the exercise is for comparison purposes only for these two columns and is not intended as a minimum width for all tables. Check whether the small screen is cut off and can be manipulated according to the Check Responsive CSS with Width, Zoom, and Keyboard Tests items.
If your table is small and still readable, you can lower or remove the minimum width. Conversely, compressing multiple columns and long values can make them difficult to read. Determine from actual data whether semantic columns can be shortened, resolved by line breaks, or horizontal movement required. On mobile, instructions like “You can move horizontally” can be helpful.
The scrollable wrapper has tabindex="0", role="region", a descriptive accessible name, and a visible focus outline. Tab into it and use the arrow keys to reach the final column. A table that does not need scrolling does not automatically need an extra tab stop. See MDN: overflow.
Run the complete table comparison
Save and open the code below as UTF-8 in tables.html. It uses the same three rows and the same 30:70 column ratio, so you can compare the differences between layouts. The reservation code is fictitious data for layout practice.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Table sizes and long content</title>
<style>
body { margin: 16px; color: #333; font: 16px/1.6 sans-serif; }
.table-scroll { max-width: 640px; overflow-x: auto; margin-block: 16px; }
.table-scroll:focus-visible { outline: 3px solid #e58c1f; outline-offset: 3px; }
table { width: 100%; min-width: 32rem; border-collapse: collapse; }
th, td { padding: 12px; border: 1px solid #aaa; text-align: start; }
.auto { table-layout: auto; }
.fixed { table-layout: fixed; }
.token { font-family: monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.original { max-width: 640px; overflow-wrap: anywhere; }
</style>
</head>
<body>
<h1>Automatic and fixed table layout</h1>
<h2>table-layout: auto</h2>
<div class="table-scroll" role="region" aria-label="Auto Batch Comparison Table" tabindex="0"><table class="auto"><colgroup><col style="width: 30%;"><col style="width: 70%;"></colgroup><thead><tr><th scope="col">item</th><th scope="col">explanation</th></tr></thead><tbody><tr><th scope="row">What to bring</th><td>Bring a water bottle and comfortable shoes.</td></tr><tr><th scope="row">reservation code</th><td class="token">GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ</td></tr><tr><th scope="row">Visitor Information</th><td>Even if long information sentences span multiple lines, the cell height is increased to match the content.</td></tr></tbody></table></div>
<h2>table-layout: fixed</h2>
<div class="table-scroll" role="region" aria-label="Fixed batch comparison table" tabindex="0"><table class="fixed"><colgroup><col style="width: 30%;"><col style="width: 70%;"></colgroup><thead><tr><th scope="col">item</th><th scope="col">explanation</th></tr></thead><tbody><tr><th scope="row">What to bring</th><td>Bring a water bottle and comfortable shoes.</td></tr><tr><th scope="row">reservation code</th><td class="token">GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ</td></tr><tr><th scope="row">Visitor Information</th><td>Even if long information sentences span multiple lines, the cell height is increased to match the content.</td></tr></tbody></table></div>
<p class="original">Full reservation code: GARDEN-VISIT-RESERVATION-2026-ABCDEFGHIJKLMNOPQRSTUVWXYZ</p>
</body>
</html>
- Narrow the window and check the width of both tables. Fixed tables are at least 512px with a root of 16px, and automatic tables can be wider than that to reflect longer code. Both tables should move horizontally in the area they wrap, not across the page.
- Move to the fixed table area with Tab and check the last column with the right arrow key. On small screens, also check if you can move horizontally with your finger. When you finish scrolling, it returns to the far left.
- Change table-layout in .fixed to auto. After checking how the column and table width changes in the same data, restore it to fixed.
- Change the white-space of .token to normal and add overflow-wrap: anywhere. Check to see if the long code wraps to increase the cell height, then revert to the original declaration.
- Change the column ratio to 40:60. Compare the spacing in the short entry column with the line breaks in the description column. Restore it to the original 30:70 and check it on a wide screen and enlarged text.
If the proportions do not look as expected, check the table-layout and the specified table width, minimum width, and wrapping conditions for long strings. If horizontal movement doesn't work, make sure you specify overflow-x on the wrapped element and not on the table itself. If you choose to abbreviate words, you should be able to read important original text elsewhere.










