Layout: box, column, row, screen
These four tags never draw anything themselves — they composite their children. Three of them
(<box>, <column>, <row>) share the same idea of a child’s positioning attributes — x, y,
align, valign — but each container honors them differently, which is the main thing to get right
when nesting layouts.
These four attributes are declared exactly once, on ViewParams, which every widget’s Params
inherits (see Python API reference) — so they show up in every properties table in this whole reference,
not just here. What’s specific to each container on this page is what it does with them: whether it
reads them at all, and what default applies when one’s unset.
<box>
Free-form container: each child is placed independently rather than stacked. Useful for overlaying things (a background image with text on top) or for a group of elements that don’t follow a simple list.
- pydantic model todays_paper_web.widgets.core.layout.BoxParams[source]
Bases:
ViewParams- field height: int | None = None
Fixes the box’s rendered height; auto-computed from children if unset.
width/height are box’s own — everything else above (x/y/align/valign) is read on each
child (set on the child element, e.g. <text x="10" align="center">), not on the box itself.
How x/align combine: if the child sets x, that value is the anchor and align shifts the child
relative to it — right subtracts the child’s rendered width, center subtracts half of it, left
leaves it as-is (so x is the left edge). If the child does not set x, it’s instead aligned within
the box’s own final width: right puts it flush with the right edge, center centers it, left puts it
flush with the left edge. y/valign work the same way against the box’s height. This means
align="center" behaves differently depending on whether x is also set — usually you want one or the
other, not both. (An explicit x="0" counts as “set”, same as any other value — it’s not treated as
unset.)
<column>
Stacks children vertically in document order, each directly below the previous one. Width is the widest child; height is the sum of all children’s heights.
- pydantic model todays_paper_web.widgets.core.layout.ColumnParams[source]
Bases:
ViewParamsNo attributes of its own - <column> only reads a child’s x (see ViewParams), inherited rather than redeclared.
<column> has no attributes of its own — nothing to override its auto-computed size, unlike <box> — so
its Params is ViewParams with nothing added. Of those, only a child’s own x (offsetting it
horizontally from the column’s left edge) is actually read here; align/valign aren’t.
<row>
The horizontal mirror of <column>: children are placed left to right, each starting where the previous
one’s right edge ended. Width is the sum of children’s widths; height is the tallest child.
- pydantic model todays_paper_web.widgets.core.layout.RowParams[source]
Bases:
ViewParams
valign above is <row>’s own attribute — its default vertical alignment for any child that doesn’t set
its own y. Note the asymmetry with <box>: on <row>, valign is set on the row, not per child —
there’s no per-child align/valign here, only the row-level default plus a per-child y override.
<screen>
The mandatory root element of every template. Renders exactly like a <box> for its children (same
x/y/align/valign rules above apply), plus fills a background first:
- pydantic model todays_paper_web.widgets.core.screen.ScreenParams[source]
Bases:
BoxParams- field height: int | None = None
Fixes the box’s rendered height; auto-computed from children if unset.
width/height are always taken from the config’s screens.width/screens.height (see
Config format), regardless of what’s written on the <screen> tag in the
template — a width/height attribute here is silently ignored, which is why they show up above as
optional even though a screen can’t actually render without them.