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 attributesx, 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 align: str | None = None

Horizontal alignment (left/center/right), if given.

field height: int | None = None

Fixes the box’s rendered height; auto-computed from children if unset.

field valign: str | None = None

Vertical alignment (top/middle/center/bottom), if given.

field width: int | None = None

Fixes the box’s rendered width; auto-computed from children if unset.

field x: int | None = None

Horizontal position, if given.

field y: int | None = None

Vertical position, if given.

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 itright 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: ViewParams

No attributes of its own - <column> only reads a child’s x (see ViewParams), inherited rather than redeclared.

field align: str | None = None

Horizontal alignment (left/center/right), if given.

field valign: str | None = None

Vertical alignment (top/middle/center/bottom), if given.

field x: int | None = None

Horizontal position, if given.

field y: int | None = None

Vertical position, if given.

<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

field align: str | None = None

Horizontal alignment (left/center/right), if given.

field valign: str = 'top'

Default vertical alignment for a child that doesn’t set its own y: top, middle/center, or bottom.

field x: int | None = None

Horizontal position, if given.

field y: int | None = None

Vertical position, if given.

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 align: str | None = None

Horizontal alignment (left/center/right), if given.

field color: Color [Optional]

Background fill color.

field height: int | None = None

Fixes the box’s rendered height; auto-computed from children if unset.

field valign: str | None = None

Vertical alignment (top/middle/center/bottom), if given.

field width: int | None = None

Fixes the box’s rendered width; auto-computed from children if unset.

field x: int | None = None

Horizontal position, if given.

field y: int | None = None

Vertical position, if given.

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.