Skip to content

Better documentation of relative lengths: page, region, block, container, element, etc. #6346

@shreevatsa

Description

@shreevatsa

Description

Hello, I am trying out Typst and while the documentation has a reasonably good tutorial and reference, and also guides to some extent, I find it lacking in the “explanation” quadrant — I was interested in understanding the typesetting/layout model, and there was too little in the tutorial and most of the reference section seemed more interested in the programming model than basic questions of layout.

A specific example is relative lengths like "100%", which are documented only as “A length in relation to some known length”, but I have not been able to find in the docs a way of figuring out what that known length is, in a given context.

On the forum, user Andrew pointed me to this section of the source code:

/// A length in relation to some known length.
///
/// This type is a combination of a [length] with a [ratio]. It results from
/// addition and subtraction of a length and a ratio. Wherever a relative length
/// is expected, you can also use a bare length or ratio.
///
/// # Relative to the page
/// A common use case is setting the width or height of a layout element (e.g.,
/// [block], [rect], etc.) as a certain percentage of the width of the page.
/// Here, the rectangle's width is set to `{25%}`, so it takes up one fourth of
/// the page's _inner_ width (the width minus margins).
///
/// ```example
/// #rect(width: 25%)
/// ```
///
/// Bare lengths or ratios are always valid where relative lengths are expected,
/// but the two can also be freely mixed:
/// ```example
/// #rect(width: 25% + 1cm)
/// ```
///
/// If you're trying to size an element so that it takes up the page's _full_
/// width, you have a few options (this highly depends on your exact use case):
///
/// 1. Set page margins to `{0pt}` (`[#set page(margin: 0pt)]`)
/// 2. Multiply the ratio by the known full page width (`{21cm * 69%}`)
/// 3. Use padding which will negate the margins (`[#pad(x: -2.5cm, ...)]`)
/// 4. Use the page [background](page.background) or
/// [foreground](page.foreground) field as those don't take margins into
/// account (note that it will render the content outside of the document
/// flow, see [place] to control the content position)
///
/// # Relative to a container
/// When a layout element (e.g. a [rect]) is nested in another layout container
/// (e.g. a [block]) instead of being a direct descendant of the page, relative
/// widths become relative to the container:
///
/// ```example
/// #block(
/// width: 100pt,
/// fill: aqua,
/// rect(width: 50%),
/// )
/// ```
///
/// # Scripting
/// You can multiply relative lengths by [ratios]($ratio), [integers]($int), and
/// [floats]($float).
///
/// A relative length has the following fields:
/// - `length`: Its length component.
/// - `ratio`: Its ratio component.
///
/// ```example
/// #(100% - 50pt).length \
/// #(100% - 50pt).ratio
/// ```
that suggests a few things:

  • relative lengths are, in a “common use case”, relative to the “width of the page”, which is “the page's inner width (the width minus margins)”.

  • in general they are relative to the “container”, when a “layout element” is nested in “another layout container”.

So there seem to be a bunch of undefined/undocumented terms here, like “ region”, “container”, and “element”. (For example, is there a list of all the elements, or different kinds of regions?)

The most useful has been the “What becomes a paragraph?” at https://typst.app/docs/reference/model/par/ and I'd like more such sections.

The basic thing I'm trying to understand is: in general, what does a page consist of? For example, I understand the TeX model where the page is a vbox containing hboxes (and glue and penalties), and I can also debug this myself or check my understanding in any given situation, with \tracingoutput — it seems that the Typst model is more sophisticated, as regular paragraphs and (say) headings are first-class concepts treated differently, so a page can be some combination of different things, and the documentation has not been helpful in understanding what these things are and what exactly is going on in any given context. A concrete test is: can a user who has read the documentation correctly answer, given a location in the Typst source code, what a relative length like "50%" there is going to be relative to?

(Also, IMO a user ought to be able to learn these things from documentation rather than having to read the source code comments, ideally.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions