How can I robustly place a box exactly on the left edge of each page?

I want to place a red box, 4 mm wide and as high as the page height, on every page. I tried to do this with:

set page(
  header: context { place(
    top + left,
    dx: page.margin.left,
    box(width: 4mm, height: page.height, fill: red),
  ) }
)

But I get the following error message: error: cannot access fields on type auto.

What would be the simplest way to make this work without hard-coding margin and page dimensions?

If you mean the left edge respecting the margin, you can simply remove the dx parameter or set it to zero, otherwise you can use the background to place the box at the paper edge without a margin.

1 Like

See: Page Function – Typst Documentation

  • auto: The margins are set automatically to 2.5/21 times the smaller dimension of the page. This results in 2.5cm margins for an A4 page.

This is why page.margin.left raises an error.

Put a manual value at first, then replace with a calculation from the ratio above.

#let left-margin = 2.5/21 * calculate.min(page.width, page.height)` // You still need `context` provided.

But as mentioned by @flokl , this is not needed if you are using header. Only for background as it disregards page margins.

With background:
// Requires context
#let get-margin-left() = if page.margin == auto {
  calc.min(page.height, page.width) * 2.5 / 21
} else {
  page.margin.left
}

#set page(
  background: context {
    place(
      top + left,
      dx: get-margin-left(),
      box(width: 4mm, height: page.height, fill: red),
    )
  },
)
With header:
#set page(
  header: context {
    place(
      top + left,
      dx: 0cm,
      box(width: 4mm, height: page.height, fill: red),
    )
  },
)

1 Like