Table block: hasFixedLayout not configurable via UI, and default CSS not fully responsive
What problem does this address ?
1. hasFixedLayout is not exposed in the block settings UI
In the block.json file for the Table block, there is an attribute : https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/table/block.json
"hasFixedLayout": {
"type": "boolean",
"default": true
}
However, this value is not configurable from the block sidebar (Inspector Controls). This means users cannot toggle between table-layout: fixed and auto without custom code or filters.
👉 Request: Can this attribute be exposed in the UI as a toggle, or at least allow for easier overrides via block filters or global settings?
2. Responsive behavior does not work without custom CSS By default, the Table block includes styles like :
.wp-block-table {
overflow-x: auto;
}
.wp-block-table .has-fixed-layout {
table-layout: fixed;
width: 100%;
}
But this alone does not make the table responsive on small screens, especially when long content is involved. To make tables truly responsive, we had to add the following CSS (used inside a media query) :
@media (max-width: $screen-wp-sm-max) {
.wp-block-table {
table {
width: max-content !important;
table-layout: auto !important;
}
}
}
Without this, the table remains rigid and does not allow horizontal scrolling as expected.
👉 Request: Could the default responsive CSS for the Table block be improved to better handle overflow and layout issues on mobile/tablet/desktop devices ?
Hi there, thanks for raising this!
Just wanted to clarify a couple of things based on my experience:
-
The
hasFixedLayoutattribute is actually editable via the block settings UI—it's exposed through the “Fixed width table cells” toggle in the block’s Inspector Controls. Toggling this will switch betweentable-layout: fixedandauto. -
Regarding responsiveness, the Table block is already reasonably responsive out of the box, with
overflow-x: autoallowing horizontal scrolling when needed.
That said, if there's anything I'm missing or if you're observing different behavior in your setup, happy to compare notes!
Thanks again!
Supplemental Artifacts
https://github.com/user-attachments/assets/578f9498-8cbe-4719-8e4d-42116427e18a
Environment
- WordPress: 6.9-alpha-60301
- PHP: 8.2.28
- Server: Apache/2.4.62 (Debian)
- Database: mysqli (Server: 11.8.2-MariaDB-ubu2404 / Client: mysqlnd 8.2.28)
- Browser: Chrome 137.0.0.0
- OS: macOS
- Theme: Twenty Twenty-Five 1.2
- MU Plugins:
- Gutenberg Test Plugin, Disable Login Autofocus
- Gutenberg Test Plugin, Disable Remote Patterns
- Gutenberg Test Plugin, Enable Templates UI
- Gutenberg Test Plugin, No-cache Headers
- Gutenberg Test Plugin, Normalize Theme
- server-timing.php
- Plugins:
- Gutenberg 21.0.0
- Test Reports 1.2.0
@shubhtoy
Thanks for your feedback,
sorry I didn't see the switch for table-layout fixed, I don't know why :)
For responsive, I think it's not very readable, you have to wait until the table is 150px wide to trigger the scrollbar...
In fact, to trigger the scrollbar earlier, you'd have to play with the word-break: auto-phrase or even the white-space: nowrap.
without word-break:auto-phrase
with word-break: auto-phrase
Related: https://github.com/WordPress/gutenberg/issues/9524
Based on the discussion in the previous issue, this isn't currently considered a bug. However, I personally feel it should be — especially given the impact on usability. It might be worth exploring the addition of minimal CSS to improve the responsiveness of the table block, as suggested earlier.
Do you think it would make sense to revisit this in 2025 and consider adding a lightweight CSS solution to address minimal responsive behavior?
We have an update which extends the fix by adding responsive handling for complex tables (≥4 columns), ensuring they keep a readable minimum width and enable horizontal scrolling on mobile — see detailed explanation for full context.
I'd love to get some feedback on https://github.com/WordPress/gutenberg/pull/71189. Thank you!
Thanks for the PR.
I understand what #71189 is trying to do, but personally, I think it's too specific and complicated. Let's see what CSS the PR generates.
.wp-block-table:not(:has(td:nth-of-type(4))) .has-fixed-layout{
table-layout:fixed;
width:100%;
}
.wp-block-table:not(:has(td:nth-of-type(4))) .has-fixed-layout td,
.wp-block-table:not(:has(td:nth-of-type(4))) .has-fixed-layout th{
word-break:break-word;
}
@container (min-width: 500px){
.wp-block-table:has(td:nth-of-type(4):last-of-type) .has-fixed-layout{
table-layout:fixed;
width:100%;
}
.wp-block-table:has(td:nth-of-type(4):last-of-type) .has-fixed-layout td,
.wp-block-table:has(td:nth-of-type(4):last-of-type) .has-fixed-layout th{
word-break:break-word;
}
}
@container (min-width: 600px){
.wp-block-table:has(td:nth-of-type(5):last-of-type) .has-fixed-layout{
table-layout:fixed;
width:100%;
}
.wp-block-table:has(td:nth-of-type(5):last-of-type) .has-fixed-layout td,
.wp-block-table:has(td:nth-of-type(5):last-of-type) .has-fixed-layout th{
word-break:break-word;
}
}
@container (min-width: 700px){
.wp-block-table:has(td:nth-of-type(6):last-of-type) .has-fixed-layout{
table-layout:fixed;
width:100%;
}
.wp-block-table:has(td:nth-of-type(6):last-of-type) .has-fixed-layout td,
.wp-block-table:has(td:nth-of-type(6):last-of-type) .has-fixed-layout th{
word-break:break-word;
}
}
@container (min-width: 800px){
.wp-block-table:has(td:nth-of-type(7)) .has-fixed-layout{
table-layout:fixed;
width:100%;
}
.wp-block-table:has(td:nth-of-type(7)) .has-fixed-layout td,
.wp-block-table:has(td:nth-of-type(7)) .has-fixed-layout th{
word-break:break-word;
}
}
In my experience, I know developers who add their own functionality to the core table block. For example, I've seen them replacing the first column with th tag or providing scrolling options. What would they think when they saw this CSS? It seems impossible to fully understand it and write appropriate CSS without conflicting with their own functionality.
Personally, I prefer to simply resolve it with the word-break option. There is an issue proposing adding a word-break option.
See: https://github.com/WordPress/gutenberg/issues/11956