How to put the header below the top margin?

Hi,
I made a document with 1 cm margin. I want the header to be inside the 1cm margins.
But the header is automaticaly put outside the 1cm margin except if I use header-ascent: 0px. But in this case header is displaying on the main text.

Here is a minimal (not) workinge example :

#set page(
  margin: 1cm,
  header-ascent: 0cm,
  header:[my header]
)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

If you remover header-ascent, you will see that header is displayed outside 1cm margin.

How can I solve my problem ?

Thanks

Hi, welcome to the Typst forum!

Could you put a screenshot of the result you’re trying to achieve? I don’t really understand what you’re asking since for me, “inside the margin” means inside the 1cm space reserved for the margin. And in your example, in both cases (with or without header-ascent: 0cm) the header is always inside the margin…

Sorry, I realise I misspoke.
When I said within the margin, I meant within the page (without going beyond the margins).
Here’s an image with what I’d like (what I do on LO Writer). The print margins are defined (at 1cm) and all the content: page or header does not exceed the margins.

Ah I see. And I suppose you want this header repeated automatically on every page?

Then you could put your document body in a grid, and use a grid header (by default, if the grid takes more than one page the grid header is repeated on every page):

#set page(margin: 1cm, paper: "a6", numbering: "1")
#let header = rect(width: 100%)[My Header]
#show: doc => grid(
  grid.header(header),
  doc
)
#lorem(200)

But it’s not a general solution: there are things you cannot put in a grid (e.g. page breaks or page settings) so this would not work will all documents.

Maybe best is to measure the header, and adapt the top margin to make sure you have the desired space above the header:

#let margin = 1cm
#let header = rect(height: 1.5em, width: 100%)[My Header]
#set page(margin: margin, header: header, paper: "a6", numbering: "1")

#show: doc => context {
  let h-height = measure(header).height
  set page(margin: (top: margin + h-height), header-ascent: 0pt)
  doc
}

#lorem(200)

(I adapted a bit your question title, feel free to change it again if you find a better one.)

Thank you for such a detailed answer.
I thought there was a simpler solution.
The default behaviour of Typst seems to me to be problematic when the height of the header is greater than the height of the top margin. But there must be subtleties that I don’t understand.
In any case, as my header is always the same height, I’m going to manually increase the top margin by the height of my header.
Thanks,

The default behaviour of Typst seems to me to be problematic when the height of the header is greater than the height of the top margin.

I think in this case we would just increase the size of the top margin. I’m not a typography expert but from what I know the header is supposed to be in the margin.

I just realized my solution might be needlessly complicated. If you know the size of the header, it’s much simpler:

#set page(
  margin: (top: 3cm, rest: 1cm),
  header: rect(height: 2cm, width: 100%)[My Header],
  header-ascent: 0pt,
)

#lorem(200)