Pakorn
July 25, 2025, 2:18pm
1
I tried to create a fancy box using the following minimal example. However, when the block break across pages, it sometimes breaks such that the title
is not with its child. How I can prevent this?
#set page(height: 3cm, width: 4cm)
#let myblock(title, body) = {
block({
move(block(fill: yellow, title, inset: 0.2em,), dx: 0.5em, dy: -0.6em)
v(-1em)
body
}, stroke: 1pt, width: 100%)
}
#myblock[
Title
][
#lorem(5)
]
#myblock[Another][
#lorem(20)
]
The rendered output:
expected:
which was rendered from:
#set page(height: 3cm, width: 4cm)
#let myblock(title, body) = {
block({
move(block(fill: yellow, title, inset: 0.2em,), dx: 0.5em, dy: -0.6em)
v(-1em)
body
}, stroke: 1pt, width: 100%)
}
#myblock[
Title
][
#lorem(5)
]
#pagebreak() // Here!
#myblock[Another][
#lorem(20)
]
Hi there @Pakorn , try setting block
breakable: false
Whether the block can be broken and continue on the next page.
From Typst Doc: Block Function – Typst Documentation
#let myblock(title, body) = {
block(
breakable: false, // <--
{
move(block(fill: yellow, title, inset: 0.2em,), dx: 0.5em, dy: -0.6em)
v(-1em)
body
}, stroke: 1pt, width: 100%)
}
Pakorn
July 25, 2025, 2:27pm
3
That would cause the block not to break at all, which also is not desirable.
As you can see in the expected behavior, the overall block should be able to break across page, just the title that should stick with its body.
Sorry I went a bit fast on that. The MRE and the expected behaviour are not the same… Hence my quick reply as it did solve the problem on the MRE. I understand the requirement now. Would you update your MRE so it matches the desired behaviour please?
Pakorn
July 25, 2025, 2:40pm
5
No worries, but what is MRE?
Your code snippet in your first post.
A Minimal reproducible example - Wikipedia is a piece of code that contains only the required code to reproduce the issue you are having.
Then, if you also post the expected result, we can work together in order to reach the state where you are satisfied, i.e. the issue is solved.
#lorem(20)
instead of “Things” will probably work (that is what I am using now).
Pakorn
July 25, 2025, 2:55pm
7
I didn’t noticed that, thank you.
Now the code has been updated.
1 Like
I thought sticky: true
on the block
sticky - Typst Documentation would have solved it but it doesn’t work (or I can’t make it work). Perhaps related to Block loses stickness when containing large text · Issue #6546 · typst/typst · GitHub .
These packages are not solving your problem but worth looking at as they seems to do similar things:
What do you think of this? Setting pagebreak(weak:true)
does solve the issue.
#let myblock(title, body) = {
block({
move(block(fill: yellow, title, inset: 0.2em,), dx: 0.5em, dy: -0.6em)
v(-1em)
body
}, stroke: 1pt, width: 100%)
pagebreak(weak:true) //<--
}
flokl
July 25, 2025, 3:56pm
10
You can wrap your title block with another block which is sticky and sticks to the body.
#let myblock(title, body) = {
block({
block(sticky: true, below: 0.2em, move(block(fill: yellow, title, inset: 0.2em), dx: 0.5em, dy: -0.6em))
body
}, stroke: 1pt, width: 100%)
}
1 Like
Nice. Out of interest, do you have any idea why sticky: true
doesn’t work inside the inner block
?
flokl
July 25, 2025, 4:13pm
12
Not really. Maybe because it is inside move
?
Pakorn
July 25, 2025, 7:25pm
13
Since @flokl covers the more cases (e.g. having two blocks in the same page)
So I marked his as solution.
Thank you all.
1 Like