Skip to content

Layout attributes ​

Every element takes a style prop of type ItemStyle, and rsx! fills it from the attributes below. <View> additionally takes the container attributes, which describe how its children are placed. All of it lives in egui_reactor::layout and is re-exported from the prelude.

rust
<View direction="column" gap={8} p={12} bg={egui::Color32::from_gray(30)} radius={8.0}>
    <Text grow={1.0} w="100%">"item"</Text>
</View>

Lengths ​

Any size, margin or padding is a Length:

Written asMeans
{12} / {12.0}12 egui points
"12" / "12px"the same
"50%"half of the containing block
"auto"sized by the layout algorithm

Anything else in a string panics with a message naming what it expected, at the moment the style is built. From<f32> and From<i32> give points, which is why number literals need no unit.

Item attributes (ItemStyle) ​

Accepted by every element.

AttributeTypeMeaning
w hLengthWidth, height
min_w min_hLengthMinimum width, height
max_w max_hLengthMaximum width, height
growf32flex-grow: share of the leftover space
shrinkf32flex-shrink: share of the overflow to give up
basisLengthflex-basis: the size to start from
align_selfAlignOverrides the parent's align for this child
m mx my mt mr mb mlLengthMargin: all, x, y, top, right, bottom, left
p px py pt pr pb plLengthPadding, same shape
col_span row_spanu16How many grid tracks this child covers

The margin and padding shorthands go all → axis → side, and the more specific one wins: p={8} pt={0} is eight points everywhere but the top.

min_w={0.0} is worth knowing by name. A flex item's automatic minimum is its content, so a wide child pushes its neighbour off the edge instead of being clipped; setting the minimum to zero on the item that should give way is the fix.

Container attributes (ContainerStyle) ​

Accepted by <View> only.

AttributeTypeValues
displayDisplay"flex" (default), "grid", "block", "none"
directionDirection"row" (default), "column", "row-reverse", "column-reverse"
wrapboolWrap children onto more lines
justifyJustify"normal" (default), "start", "end", "flex-start", "flex-end", "center", "stretch", "space-between", "space-evenly", "space-around"
alignAlign"normal" (default), "start", "end", "flex-start", "flex-end", "center", "baseline", "stretch"
align_contentJustifyThe same values, distributing wrapped lines on the cross axis
gapGapOne number for both axes, or (column, row)
colsu16Equal-width grid columns; only with display="grid"

justify and align default to Normal, which means "unspecified" and leaves the underlying engine's own default in place — it is not the same as "start".

An invalid string panics with the list of accepted spellings, so a typo shows up on the first frame that draws the element rather than as a silent mislayout.

Paint attributes (PaintStyle) ​

Carried inside ItemStyle, so every element accepts them too.

AttributeTypeMeaning
bgegui::Color32Background, behind the content
borderegui::StrokeBorder, in front of the content, inside the box
radiusf32Corner radius, shared by background, border and shadow
shadowboolThe theme's window shadow
custom_shadowegui::ShadowA shadow of your own; wins over shadow
opacityf32Multiplies the opacity of everything the node draws

All three shapes sit on the node's border box — its whole box, not the rect its content draws in. A border is also layout: its width is added to the padding edge, so children start inside the stroke and it is painted exactly in the band the layout kept them out of. Nothing else about the paint reaches the layout.

Painting happens after the frame's layout is solved, so a container that grew around children that stayed put is painted at its new size in the same pass. Outside a <View> (in plain Ui mode) nothing is painted from style; <Frame> is the escape hatch there.

style= and the shorthands together ​

style={expr} and the shorthand attributes fill the same prop, and if both are present the shorthands chain off the expression:

rust
// becomes .style((style).p(6))
<Chip style={style} p={6}/>

That is what lets a wrapper component take #[prop(default)] style: ItemStyle, receive its caller's layout untouched, and add its own on top:

rust
#[component]
fn Chip(cx: &mut Cx, #[prop(default)] style: ItemStyle, label: &str) {
    let clicked = cx.leaf(&style.shrink(0.0), |ui| ui.button(label).clicked());
    // ..
}

The same types are usable by hand — ItemStyle::default().w(220.0).h(20.0), ContainerStyle::default().direction("column") — which is what the escape hatches take.

More ​

The full attribute list, the taffy mapping, and what happens to each attribute inside a <VirtualList> row are in docs/ARCHITECTURE.md section 6.

Released under the MIT or Apache-2.0 license.