Sizing
Goals
- No unintended overflow.
- No unintended word wrap.
- Sensible layout.
- One pass tree traversal.
Cross-axis alignment
HBox should approximately center compact children vertically (middle), and VBox should approximately center them horizontally (center). Children that expand on that axis can still fill the available space. This positions the widget, not the text inside it, and does not require pixel-identical output across toolkits.
Backend support and native limits are listed in the reference alignment matrix. Textual uses native group alignment, so mixed-size children do not necessarily have individual matching center lines. Explicit dimensions also retain backend-specific size-hint/minimum behavior.
Concepts
- An element could be categorized into 4 types:
- Static: A static element is a visible element with a specified or fixed size, e.g., a button, a label, etc.
- Growable: A growable element always grows to fit its content; the specified size is essentially the minimum size, e.g., a vbox, a hbox, a grid, etc.
- Shrinkable: A shrinkable element can be smaller than its content or shrink to accommodate available space, and it's also a growable element, e.g., a scroller, a multi-line text viewer, a canvas, etc.
- Weighted: A weighted element is a strongly growable and shrinkable element with the highest priority, e.g., a spacer, or manually set weight.
- There are 4 priority levels for expanding:
- 0 Static elements.
- 1 Non-axis side of growable elements, e.g., left/right for a vbox, all sides for a grid.
- 2 Axis side of growable elements, e.g., top/bottom for a vertical scroller.
- 3 Shrinkable elements, e.g., all sides for a canvas or a scroller.
- 4 Weighted elements.
- An expanding element won't be expanding if there is any expanding siblings with higher priority.
- The outmost container doesn't expand, usually it's a window.
In following demos, elements come with 5px padding/gap and 3px colored border.
Case 1: Fit the content
The most compact sizing.
- An element is compact if it's not expanding.
- No unintended overflow.
- A growable element always grows to fit its content.
Static
Static
Static
Static
Static
Static
Static
Case 2: Container with specified size
The outmost container is specified with a size of 150x150 px. (Positioning is not discussed here.)
- A static element remains its size.
- A growable element is default to expanding on all directions with priority 1.
- No unintended overflow.
- A growable element always grows to fit its content.
A Static
B Static
C Static
D Static
E Static
F Static
G Static
H Static
I Static
J Static
- No unintended overflow.
- A scroller (shrinkable) can contain content larger than its size and can shrink.
Case 3: Weighting
The outmost container is specified with a width of 150%.
- An element is expanding with the highest priority when weight is set.
- An expanding element won't be expanding if there is any expanding siblings with higher priority.
- Priority doesn't go over the container.
- Manually set the weight to make it expanding with the highest priority.
Case 4: More complex cases