Skip to content
Shiny.NET

YogaLayout

YogaLayout brings the layout model of Yoga to .NET MAUI and Blazor. It is flexbox with Yoga’s defaults and extras. The same properties give the same boxes on both hosts.

  • NuGet downloads for Shiny.Maui.Controls
  • NuGet downloads for Shiny.Blazor.Controls
Frameworks
.NET MAUI
Blazor
  • No native code. On MAUI a pure C# engine lays children out. On Blazor the browser’s flexbox does the work, set up with Yoga’s defaults.
  • Yoga defaults: column direction, FlexShrink 0, AlignContent FlexStart, minimum size 0, border-box, relative position.
  • Absolute positioning with Left/Top/Right/Bottom/Start/End insets against the padding box.
  • Percentages for sizes, min/max, basis and insets: "50%".
  • AspectRatio. One known dimension, including a stretched one, gives the other.
  • Auto margins (AutoMargins="Start") push a child to the end of its line or centre it.
  • Gaps: Gap, RowGap, ColumnGap.
  • Right-to-left flow. Start/End follow the flow direction.
claude plugin marketplace add shinyorg/skills
claude plugin install shiny@shiny

One plugin installs all 37 Shiny skills. Your agent loads only the skill relevant to what you're building, so there's no cost to having them all available.

copilot plugin marketplace add https://github.com/shinyorg/skills
copilot plugin install shiny@shiny

One plugin installs all 37 Shiny skills. Your agent loads only the skill relevant to what you're building, so there's no cost to having them all available.

View Skills Repository
CSS Yoga / YogaLayout
FlexDirection default row Column
FlexShrink default 1 0
AlignContent default stretch FlexStart
Minimum size auto (content) 0
Box sizing content-box border-box
Position default static Relative

Child properties are attached, so they work on any view.

xmlns:shiny="http://shiny.net/maui/controls"
<shiny:YogaLayout FlexDirection="Row" Gap="12">
<shiny:YogaLayout shiny:YogaLayout.FlexGrow="1" shiny:YogaLayout.FlexBasis="0">
<!-- The column stretches the image across; AspectRatio derives its height. -->
<Image Source="card.png" Aspect="AspectFill" shiny:YogaLayout.AspectRatio="1.5" />
<Label Text="Aurora" Margin="8" />
<Border shiny:YogaLayout.PositionType="Absolute"
shiny:YogaLayout.Top="8"
shiny:YogaLayout.Right="8">
<Label Text="NEW" />
</Border>
</shiny:YogaLayout>
<BoxView shiny:YogaLayout.NodeWidth="25%" />
</shiny:YogaLayout>

In C#, lengths are YogaValue: YogaLayout.SetNodeWidth(view, YogaValue.Percent(50)), YogaLayout.SetLeft(view, 10). A double converts implicitly.

Every Yoga node is a <YogaLayout>, the way every React Native view is a node. Lengths are strings, because Razor would read a bare 50% as C#.

<YogaLayout FlexDirection="YogaFlexDirection.Row" AlignItems="YogaAlign.Center" Gap="8" Padding="8 12">
<YogaLayout FlexGrow="1"><strong>Inbox</strong></YogaLayout>
<YogaLayout AutoMargins="YogaEdges.Start">Done</YogaLayout>
<YogaLayout PositionType="YogaPositionType.Absolute" Top="8" Right="8" Width="24" AspectRatio="1" />
</YogaLayout>

Plain elements placed directly inside a YogaLayout get Yoga’s flex-shrink: 0, border-box and minimum size 0. The rule is in a CSS cascade layer, so any style of your own on the element still wins.

Property Default
FlexDirection Column Column, ColumnReverse, Row, RowReverse
JustifyContent FlexStart FlexStart, Center, FlexEnd, SpaceBetween, SpaceAround, SpaceEvenly
AlignItems Stretch FlexStart, Center, FlexEnd, Stretch, Baseline
AlignContent FlexStart also the Space* values; applies to wrapped lines
FlexWrap NoWrap NoWrap, Wrap, WrapReverse
Gap / RowGap / ColumnGap 0 the per-axis gaps override Gap
Padding MAUI Thickness; Blazor CSS shorthand (bare numbers are px)
Direction inherit MAUI FlowDirection; Blazor Direction (Inherit, LTR, RTL)
Property Default
FlexGrow / FlexShrink 0 / 0
FlexBasis auto points or %
AlignSelf Auto overrides AlignItems
PositionType Relative Absolute leaves the flow; Static ignores insets
Left Top Right Bottom Start End insets, points or %
Width / Height (Blazor), NodeWidth / NodeHeight (MAUI) auto points or %
MinWidth MinHeight MaxWidth MaxHeight points or %
AspectRatio width ÷ height
AutoMargins None YogaEdges flags: Left, Top, Right, Bottom, Start, End, Horizontal, Vertical, All
Display Flex None removes the child from layout
  • Baseline on MAUI: MAUI exposes no text baselines, so Baseline aligns each child’s bottom edge, as Yoga does for a node without a baseline function. Blazor aligns real text baselines.
  • Margins on MAUI are physical. Margin.Left stays on the left in right-to-left flow. Use Start/End for flow-relative insets and auto margins.
  • Absolute children are measured against the container’s padding box and add nothing to its size. An axis with no insets falls back to where JustifyContent/AlignItems would place a lone child.
  • Need FlexLayout’s API instead? ShinyFlexLayout is a cached, drop-in replacement for MAUI’s FlexLayout.