I’m trying to build a responsive table.
My goal is a 5 column, 4 row table that fill the page width (minus padding). I need the columns to be able to widen/narrow, with the other columns responding appropriately, and I need text inside each cell to wrap as the column width changes.
I’ve tried both Flex and Grid, but I can’t get the columns to resize together the way I’m expecting. Either the columns don’t stay linked, or the text/cells don’t collapse correctly.
Not sure if this possible, but would appreciate some guidance. Thanks!
Hi @Jarret!
I think I’ve managed to achieve what you’re after, using an existing example I had for a five column, four row table.
Here’s the file:
Responsive table.penpot (190.6 KB)
There is some fragility in a layout like this. It might get funky depending on the content you throw into it. For example, in this demo, the table will not resize to narrower than the very long text cell. This is because the text inside is set to fixed width. (Longer explanation on the why behind that below.) You might be able to overcome this with some smart use of max width.
Here’s how I did it:
- Set the container/page that holds the table to a fixed width using Flex. This allows the flex child (element inside the container) to fill the width, but also ensure the page expands to fit the height of its contents.
- Set the table (using Grid) to fill the width of its container and fit the height of its contents.
- Set each grid column and row to auto. This means it will expand and contract according to the content inside.
- Each grid cell is a component that has a border. In order for the borders to achieve that table grid look, these need to be set to fill the width of each column, and fill the height of each row.
- Inside the grid cell is the text. Each text element is set to fix width along with auto height in the text options. These options combined will set the text to automatically stay the same width as the text, but if it runs on to multiple lines (using carriage returns like you would in a table), its height will expand to fit the text. One exception here is the header cells that also contain icons and these are set to their own little flex layout.
The tricky issue in creating layouts like this is that, for the height and width of each element, you have to choose between fixed/fit or fill (px/auto or fr/% in grid). And every element inside that element has to be set to either fixed/fit or flexible. Every element set to fit will respond to its children, and every element set to fill will respond to its parent. So combining mixtures of fixed/fit and flexible can come with unexpected results. (Penpot will avoid impossible combinations.) And every fixed element can throw all of these out of balance ![]()
If you’re trying to recreate a table as it works on the web (browser) or in software UI, it’s probably one of the biggest challenges in Penpot. This is because rendering these tables use a complex combination of rules to make them respond to content and resize accordingly, and you’re trying to recreate that combination of rules in an interface with more binary options. But one day I reckon we’ll crack it ![]()
