Search code examples
typst

Fill complete cell height in Typst table


I have a typst grid where I want boxes to fill the height for the given row.

Eg I have the following

#let colbox(content) = {
  box(
    fill: rgb("#0097cf12"),
    inset: 10pt,
    width: 100%,
    radius: 5pt
  )[
    #content
  ]
}

#grid(
  columns: (1fr, 1fr),
  gutter: 10pt,
  
  grid.cell(
    colspan: 2
  )[
    #colbox([
      = Header 1
      #lorem(50)
    ])
  ],
  
  colbox([
   = Header 2A
   - #lorem(100)
   - #lorem(10)
   - #lorem(10)
   ]),
  
   colbox([ 
     = Header 2B
     - #lorem(10)
     - #lorem(10)
     - #lorem(10)
   ]), // TODO: this should have the same size vertical as Header 2A
  
  grid.cell(
    colspan: 2
  )[
   #colbox([
      = Header 3
      - #lorem(10)
      - #lorem(10)
      - #lorem(10)
    ])
  ],
    
)

which results in this:

image with empty white space showing the problem

Note the red arrow shows that the Header 2B box should fill the white space.

How can I achieve this?

As a small follow-up question, given that any content is not #lorem(10) but #lorem(1000), how can I allow the boxes to span multiple pages.


Solution

  • If you just want to fill your grid cells blue, like in the example, you do not actually need to wrap the cells in a function. Instead, you can do this:

    #set grid.cell(fill: rgb("#0097cf12"))
    
    #grid(
      columns: (1fr, 1fr),
      gutter: 10pt,
      
      grid.cell(
        colspan: 2
      )[
        = Header 1
        #lorem(50)
      ],
      
      [
       = Header 2A
       - #lorem(100)
       - #lorem(10)
       - #lorem(10)
       ],
      
       [ 
         = Header 2B
         - #lorem(10)
         - #lorem(10)
         - #lorem(10)
       ],
      
      grid.cell(
        colspan: 2
      )[
        = Header 3
        - #lorem(10)
        - #lorem(10)
        - #lorem(10)
      ],
    )
    

    If you need your wrapper function to do more, use the show rule of grid.cell. For example, this show rule will insert a black-stroked rectangle at the top left of each cell:

    #show grid.cell: it => block(inset: 10pt, {
      place(top+left, rect())
      it
    })