How can i make a table cell pass each other?

i want a table like this except the last column.

#table(
  columns: 3,
  table.cell(rowspan: 2, "a"),
  "b",
  none,
  table.cell(rowspan: 2, "c"),
  none,
  "d",
  none,
)

but when i delete the column, it becomes flat.

#table(
  columns: 2,
  table.cell(rowspan: 2, "a"),
  "b",
  table.cell(rowspan: 2, "c"),
  "d",
)

how can i keep the step without an empty column?


edit: just after posting this, i came up with making the width of the column 0.
if there’s a more concice solution, i’d like to know.

Hello @sumi!
I am unaware of more practical solutions than setting a 0-width column at the end, because tables spanning works in a such a way that you require n+1 rows. The last example collapses because a or c cannot span two rows, since there are not enough.
If you post your solution in response to your own topic, you will be able to mark it as a solution. I have no doubts someone is going to come and contradict me on this thought! So there might be an obvious solution I have missed.

1 Like

thanks for information!
since 0-width column seems to be the only solution (for now), i’ll post it myself and mark as a solution.

set the width of the empty column as 0.

1 Like

At first this seems puzzling, but then it’s clear that typst’s result with two columns is logical: the height of the second row is a free variable that can be set to zero because there is nothing that forces that row to be any higher than that.

An alternate solution is to use defined row heights, so we give the otherwise vanishing second row a real height:

#table(
  columns: 2,
  rows: (auto, 2em, auto),
  fill: (x, y) => blue.lighten(30% * y),
  table.cell(rowspan: 2, "a"),
  "b",
  table.cell(rowspan: 2, "c"),
  "d",
)

bild

And just out of interest I colored the cells in blue shades by their row index y to see what it would say… below it shows that we have rows 0, 1, 2 also when collapsed:

bild

4 Likes

Depending on what kind of data you are trying to show, it’ possible that a table is not the best choice. I’m imagining a situation where you have multiple columns, all with different ratios between the top row and bottom row. Managing them with rowspan would become very difficult.
In this case using stack() would be a better fit:

//Box with a fixed height so 1fr doesn't fill the rest of the page
#box(
  height: 5em,
  stack(
    dir: ltr,
    //Column 1
    table(
      columns: 1,
      rows: (2fr, 1fr),
      "a",
      "d",
    ),
    //Column 2
    table(
      columns: 1,
      rows: (1fr, 2fr),
      "b",
      "c",
    )
    //Further columns would go here
  )
)

image

Unlike the other answers, this does require that the height be defined.

1 Like

i should’ve just set the height. i feel stupid…
also i couldn’t come up with using stacks.

thanks!

1 Like