How can I have different margins on first page vs. subsequent pages?

Hello all,

Is it possible to have different margins on the very first page compared to the following pages?

The reason is that I want my main text to start lower on the first page to account for a C5 envelope window. I do want to place some content in that area (like the address), but not the body of the letter itself.

Of course, I could hack it with a bunch of newlines or #v blocks, but that feels ugly. Since Typst is a layout language that gives me conditionals and even lets me do calculations, I would expect this to be something I can program cleanly into a template.

However, I can’t find a straightforward way to do this. Maybe it’s not supported at all, or maybe I just don’t understand Typst well enough.

Could someone clarify whether this is possible, and if so, how to implement it neatly?

Thanks!

Bram

You can set the margin using #set page(...), see the page setup guide for more information.

You could then set the page configuration at the start of the title page and then again at the end, here is a minimal example:

#set page("a4", margin: (left: 2in))

// do first page stuff ...


#pagebreak()

#set page("a4", margin: auto)

// do rest of document stuff...

My preferred method would be to define the page setup for the whole document at the top and then re-define it within a scope for the title page, as follows:

#set page("a4", margin: auto)

#[
    #set page("a4", margin: (left: 2in))

    // do first page stuff ...
]

#pagebreak()

// do rest of document stuff...

The page setup defined within the scope (#[ ]) will only apply to content in that scope.

1 Like

With the second method, the #pagebreak() can be omitted, it automatically creates a page break as the page set-rules change (revert)

2 Likes

even with the first variant the #pagebreak() can be skipped: using set page() will always start a new page (unless it’s a trivial/non-change).

I would probably use a variant of the second approach:

#set page("a4", margin: auto)

#page("a4", margin: (left: 2in))[
    // do first page stuff ...
]

// do rest of document stuff...

This makes it more explicit that the first page is really just a single page. But it behaves the same as the original, so it’s purely a matter of taste.

Also highly relevant here:

There is a new very similar topic on which there are a few relevant answers.

For the top margin, OP points out that newlines or #v(...) would do the trick. My proposed solution still does basically that, but I think in a bit of a cleaner way. Crucially, it also works for the bottom margin, so that Typst automatically inserts a page break earlier than it would – i.e. what a top/bottom margin causes:

The basic trick is to insert a floating element at the top or bottom:

// `clearance: 0pt` is so that the `v` element controls the height exactly
#place(bottom, float: true, clearance: 0pt, v(2.5cm))

The height of the v element can even be negative, making the regular page margin smaller.