How to make each grid cell take up all available space?

First things first, it’s worth mentioning that the “happy path” for grid fill is to use the built-in fill parameter for grid and grid cells, since that fill is handled by the grid itself and always covers the whole cell.

With that not being possible here due to the desired radius, the ideal solution would be to remain with auto-sized rows (the default), but set rect(height: 100%) on each rectangle so that each rectangle occupies the final measured height for the cell. However, by default, 100% in an auto row always means 100% of the page’s (or parent container’s, if there is one) height, instead of the row height, to avoid a cyclic dependency problem (the auto row height depends on the cells’ heights, but the cells’ heights would depend on the auto row height); you cannot currently change that, but there is a proposal to be able to do so (which would alleviate the need for extra measure() calls): Add `table.cell(fit: Axes<bool>)` parameter · Issue #4000 · typst/typst · GitHub

For the time being, setting the row height to 1fr as suggested above does work to some extent, in that all remaining space will be equally divided between each row of rectangles, but more importantly, sets 100% to mean the row height, allowing you to #set rect(height: 100%), leading to the desired effect. (100% is equal to the row height for all row sizes except for auto.) However, this has the problem that 1fr will be relative to your whole page, so I’d recommend using fixed height rows for this purpose. Regardless of the approach taken, setting the rectangle heights to 100% (or to some fixed size if you prefer) is the preferred solution (and does not require using Typst 0.12.0):

#set page(width: 300pt, height: 400pt)

#set rect(
  inset: 8pt,
  fill: rgb("e4e5ea"),
  width: 100%,
  height: 100%,  // <--- /!\
  radius: 5pt,
)

#grid(
  columns: (1fr, 1fr, 1fr),
  gutter: 3pt,
  rows: 1fr,
  // rows: (8em, 6em), // <--- would be ideal
  grid.cell(rowspan: 2, rect[
    I don't want to use `fill` provided by `grid` because I can not get nice `radius`.\
    This is 2 rows.
  ]),
  rect[How to make this expand?],
  rect[I want each cell to take up all available space.],
  rect[I don't want to hard code heights of each row.],
  rect[How to make this expand?],
)

output

3 Likes