Canvas Panel Slots: Anchors / Offsets / Alignment / Size to Content¶
At a glance
Lives on: the Canvas Panel Slot between a Canvas Panel and one direct
child - Get it with: Slot as Canvas Slot, which returns
Canvas Panel Slot or None - Setters return: no success value -
Can fail? yes; a widget under a different parent has a different slot
type, and a root User Widget added to the viewport does not have a Canvas
Panel Slot - Official docs:
UMG Anchors,
UMG Slots,
and
UCanvasPanelSlot
A Canvas Panel does not store one universal position on each widget. It creates a Canvas Panel Slot for each direct child, and that relationship owns the child's anchors, offsets, alignment, Size to Content, and Canvas Z Order.
The one-minute version¶
- A slot describes how this parent arranges this child. Its type comes from the direct parent: Canvas Panel -> Canvas Panel Slot, Vertical Box -> Vertical Box Slot, Grid Panel -> Grid Slot, and so on.
Slot as Canvas Slot(MyWidget)returns the existing slot only whenMyWidgetis valid and is a direct child of a Canvas Panel. ANonewidget input or any other direct-parent type returnsNonesilently; a later setter on that missing slot can produceAccessed None.- Anchors are normalized points/rectangles in the immediate Canvas Panel:
(0,0)is top-left,(1,1)is bottom-right, and(0.5,0.5)is center. - When an anchor is fixed on an axis (Minimum equals Maximum), offsets on that axis mean position plus size. When the anchors are split on an axis, offsets mean near and far margins. The same four numbers change meaning.
- Alignment is the child's layout pivot:
(0,0)top-left,(0.5,0.5)center,(1,1)bottom-right. It shifts which point of the arranged child sits at the anchor/offset result. Size to Content(Auto Sizein C++) makes the slot use the widget's desired size instead of the manual slot size. It does not ignore anchors, position, alignment, safe zones, or parent constraints.- Canvas Z Order controls overlap among children of that Canvas. It is not the same as Add to Viewport Z Order and does not create a global UI layer.
- Canvas layout uses logical Slate units under Unreal Motion Graphics (UMG) dots-per-inch (DPI) scaling. Do not mix physical pixels and UMG coordinates without an explicit conversion.
The slot belongs to the parent-child relationship¶
Panel Widgets create the slot type they understand:
Canvas Panel
|-- QuestMarker
| `-- Canvas Panel Slot: anchors, offsets, alignment, Z Order
`-- HealthBar
`-- Canvas Panel Slot: anchors, offsets, alignment, Z Order
Vertical Box
|-- TitleText
| `-- Vertical Box Slot: padding, horizontal/vertical alignment, size rule
`-- StartButton
`-- Vertical Box Slot: padding, horizontal/vertical alignment, size rule
The child exposes a Slot reference, but the parent created and owns the slot
that explains this one relationship. A Canvas Panel cannot offer Grid row and
column settings; a Grid cannot offer Canvas anchors. Those properties would
have no meaning to the other parent's layout algorithm.
Reparenting a widget changes the relationship:
QuestMarker under Canvas
-> has Canvas Panel Slot
move QuestMarker under Vertical Box
-> old Canvas relationship ends
-> new Vertical Box Slot is created
Reacquire the slot after remove/reparent/add operations. Do not keep a Canvas Panel Slot reference forever and assume it follows the widget through a new parent.
What anchors and offsets actually mean¶
Anchors have Minimum and Maximum Vector2D values. Each value is normalized
against the immediate Canvas Panel's allotted size:
(0.0, 0.0) = parent Canvas top-left
(0.5, 0.5) = parent Canvas center
(1.0, 1.0) = parent Canvas bottom-right
Minimum and Maximum can name one point or a rectangle.
Fixed anchors: Minimum equals Maximum¶
When Minimum and Maximum are equal on an axis, the child does not stretch on that axis. The offset fields carry a position from the anchor plus a size:
Anchors Min = Max = (0.5, 0.5)
Offsets:
Left = 100 // X position from the center anchor
Top = -40 // Y position from the center anchor
Right = 240 // width
Bottom = 80 // height
Alignment = (0.5, 0.5)
The centered alignment means the slot's center, not its top-left, sits at the
anchor plus (100, -40).
Stretched anchors: Minimum differs from Maximum¶
When Minimum and Maximum differ on an axis, the child stretches between two anchor lines and the offset fields on that axis become margins.
Full horizontal stretch:
Anchors Min = (0.0, 0.0)
Anchors Max = (1.0, 0.0)
Offsets:
Left = 32 // margin from left anchor line
Right = 32 // margin from right anchor line
Top = 24 // Y position because vertical anchor is still fixed
Bottom = 64 // height because vertical anchor is still fixed
Full stretch on both axes uses Left, Top, Right, and Bottom as four margins. Mixed anchors are interpreted per axis: horizontal can stretch while vertical keeps position/height, or the reverse.
| Anchor relationship on an axis | Near offset means | Far offset means |
|---|---|---|
| Minimum = Maximum | position from the anchor | size on that axis |
| Minimum != Maximum | near-side margin | far-side margin |
This is the source of the classic "I changed the anchor and my width became a
right margin" surprise. Choose anchors first, then write offsets in the
meaning those anchors establish. Do not copy one raw Margin value between a
fixed and stretched slot and expect the same rectangle.
At a conceptual level:
pseudocode of Canvas layout - not engine source
anchorMinPixels = ParentCanvasSize * AnchorMinimum
anchorMaxPixels = ParentCanvasSize * AnchorMaximum
if anchors are fixed on an axis:
position = anchorMinPixels + positionOffset
size = explicitSize
else:
position = anchorMinPixels + nearMargin
size = (anchorMaxPixels - farMargin) - position
arrangedPosition = position - size * Alignment
The real layout evaluates both axes and desired-size rules together, but this model explains why resolution, aspect ratio, anchors, offsets, and alignment all affect the final rectangle.
Alignment is a layout pivot¶
Alignment selects the point inside the arranged child/slot rectangle that the anchor-plus-offset result represents:
| Alignment | Point used |
|---|---|
(0.0, 0.0) |
top-left |
(0.5, 0.5) |
center |
(1.0, 1.0) |
bottom-right |
(0.5, 1.0) |
bottom-center, useful for a nameplate above a world point |
For a 200-by-80 fixed child at position (500, 300):
Alignment (0, 0) -> top-left starts at (500, 300)
Alignment (0.5, 0.5) -> center sits at (500, 300)
Alignment (1, 1) -> bottom-right sits at (500, 300)
Alignment is not the Render Transform Pivot. Canvas alignment participates in layout. Render Transform Pivot controls where a later visual scale/rotation transform pivots inside the already arranged widget. Applying both without knowing which one owns the offset is how a marker gets "centered twice."
Size to Content uses desired size¶
The Canvas property displayed as Size to Content is Auto Size in the
UCanvasPanelSlot API. When enabled, the slot uses the child widget's desired
size instead of the manual Canvas slot size.
Desired size is produced by layout from the widget and its content:
- text, font, wrapping, and padding;
- image brush size;
- a child panel's desired size;
- Size Box overrides and other layout constraints;
- visibility (
Collapsedcontributes no layout size).
Anchors, offsets, and alignment still place that desired-size rectangle.
Size to Content is not "ignore the parent and draw at any size."
Common traps:
- enabling Auto Size and then wondering why
Set Sizehas no visible effect; - reading Desired Size immediately after creation/content mutation, before a layout prepass has produced the current measurement;
- auto-sizing text whose wrap width depends on the very width being computed;
- expecting a stretched anchor to fill the parent while Auto Size requests the content's natural size.
Use an explicit Size Box or manual Canvas size when the design owns a fixed rectangle. Use Size to Content when the content genuinely owns the rectangle, then test long/localized text and runtime content changes.
Z Order is local to the Canvas¶
Canvas children can overlap. A larger Canvas Panel Slot Z Order gives that child a higher drawing priority relative to siblings in the same Canvas.
It does not:
- move the child to a different parent;
- change the order inside a Vertical Box or Grid;
- outrank a separate root User Widget added to a higher viewport layer;
- make an invisible/disabled widget visible or enabled; or
- solve ambiguous input policy by itself.
Use one intentional layer scheme (Background, Content, Overlay,
Tooltip, for example) instead of scattering arbitrary large values across
widgets.
Getting a Canvas Panel Slot safely at runtime¶
For an existing designer child:
MarkerWidget
-> Slot as Canvas Slot
-> Is Valid
true:
Set Anchors
Set Alignment
Set Position / Set Size or Set Offsets
Set Auto Size
Set Z Order
false:
MarkerWidget is not a direct Canvas child (or no longer has that slot)
Set anchors before raw offsets because anchors decide what the offset fields mean.
For a runtime-created Canvas child, prefer the slot returned at creation:
CanvasPanel -> Add Child to Canvas(NewMarker)
-> Return Value (Canvas Panel Slot)
-> configure anchors / alignment / position / size / Z Order
That output is stronger than adding the child and immediately rediscovering the slot you were just given.
The root UserWidget added through Add to Viewport or Add to Player Screen
is a different case. It has a viewport/player-screen layout relationship, not
a Canvas Panel Slot. Canvas slot setters affect a widget inside a Canvas,
not the root widget's viewport slot.
Resolution, aspect ratio, DPI, and Safe Zones¶
Anchors respond to the size of the immediate Canvas. They do not guarantee that the Canvas fills the viewport. A Canvas nested inside a Size Box, Overlay, or another User Widget can have a smaller arranged size, and its children anchor against that size.
For responsive layout:
- anchor edge controls to the intended edge rather than to top-left;
- stretch backgrounds/bars only on the axes that should grow;
- keep authored margins in logical UMG/Slate units;
- test wide, tall, and resized viewports, not only the Designer reference size;
- use parent layout panels for lists/flow instead of manually positioning every generated child on a Canvas.
UMG applies project DPI scaling to make UI resolution-independent. A Canvas
offset of 100 is a logical Slate-unit distance; it is not a promise of exactly
100 physical display pixels. World-to-widget projection nodes can already
return DPI-adjusted widget coordinates. Multiplying or dividing those values
again makes placement drift with resolution.
Safe Zones are separate from anchors. Anchoring to (1,1) means the Canvas
bottom-right, not "the last platform-safe pixel." Put the relevant layout
inside a Safe Zone or apply safe padding once in the same coordinate space.
Do not use both a Safe Zone parent and duplicate manual safe padding.
When layout is wrong (and what failure looks like)¶
Slot setters return no success value. Slot as Canvas Slot is the useful
failure boundary: it returns None when the Widget input itself is None or
when the relationship is not a Canvas slot.
- The widget is under the wrong direct parent. A Button inside a Vertical Box inside a Canvas has a Vertical Box Slot; the Vertical Box itself has the Canvas Panel Slot.
- You targeted the root viewport User Widget. Use viewport-slot functions for the root, or target its internal direct Canvas child.
- Anchors changed after offsets were authored. The same fields were reinterpreted as margins or position/size.
- Alignment was applied twice. Canvas alignment centers the widget, then manual half-size subtraction centers it again.
- Size to Content overrides manual size. Disable Auto Size or let desired size own the rectangle intentionally.
- Desired size is not current yet. Construction/content changed before a layout pass; defer the measurement or use an intentional prepass only when immediate measurement is truly required.
- The Canvas is not viewport-sized. Anchors are correct relative to the wrong assumed parent rectangle.
- DPI coordinate spaces were mixed. A widget-ready coordinate was scaled again or a physical screen coordinate was used as a logical Canvas offset.
- Safe-zone padding was ignored or doubled. The anchor does not own safe area policy.
- Another owner rewrites layout. An animation, Tick path, binding, or second manager applies a later position/transform.
A None result from Slot as Canvas Slot is quiet. Calling Set Position on
that missing slot afterward can produce Accessed None; validate at the cast
boundary and print the widget's direct parent/slot type while debugging.
The patterns everyone actually uses¶
Center a fixed-size prompt¶
Slot as Canvas Slot(PromptPanel)
-> Set Anchors Min/Max = (0.5, 0.5)
-> Set Alignment = (0.5, 0.5)
-> Set Position = (0, 0)
-> Set Size = (480, 160)
-> Set Auto Size = false
Stretch a top bar with fixed margins¶
Anchors Min = (0, 0)
Anchors Max = (1, 0)
Alignment = (0, 0)
Offsets = Left 32, Top 24, Right 32, Bottom 64
Here Right is a right margin and Bottom is height because only the
horizontal anchors stretch.
Place an auto-sized marker by its bottom-center¶
Slot as Canvas Slot(Marker)
-> Set Anchors Min/Max = (0, 0)
-> Set Alignment = (0.5, 1.0)
-> Set Auto Size = true
-> Set Position = projected widget-space point + designed gap
Do not subtract half the marker width again; alignment already chooses the bottom-center pivot.
The C++ twin, for the curious (our own example code):
void UMarkerLayer::ConfigureMarker(UWidget* Marker, const FVector2D& Position)
{
if (!IsValid(Marker))
{
return;
}
if (UCanvasPanelSlot* CanvasSlot =
Cast<UCanvasPanelSlot>(Marker->Slot))
{
CanvasSlot->SetAnchors(FAnchors(0.0f, 0.0f));
CanvasSlot->SetAlignment(FVector2D(0.5f, 1.0f));
CanvasSlot->SetAutoSize(true);
CanvasSlot->SetPosition(Position);
}
}
Local UI boundary¶
Canvas layout is local presentation. The server normally has no useful screen widget or local viewport to arrange.
In multiplayer, replicate the gameplay facts a heads-up display (HUD) needs - objective state, health, target Actor, team - and let each owning client's widget choose anchors, DPI scale, safe area, and local-player rectangle. In split-screen, each local player can have a different root widget/subviewport; do not assume one full-screen Canvas belongs to every player.
What Canvas Panel Slot nodes do not do¶
They do not:
- add a widget to a Canvas or to the viewport;
- move an arbitrary descendant that is not a direct Canvas child;
- convert a Vertical Box/Grid/Overlay slot into a Canvas Panel Slot;
- position the root User Widget's viewport slot;
- guarantee a full-screen parent Canvas;
- convert physical pixels into UMG units automatically for your input value;
- account for Safe Zone padding merely because an edge anchor is used;
- force desired-size measurement to become current immediately;
- change visibility, enabled state, focus, hit testing, or input mode;
- replicate layout to another machine; or
- prevent another animation/binding/update path from overwriting the slot.
Lookalikes - which one do I want?¶
| Node / tool | Use when | Watch out |
|---|---|---|
| Slot as Canvas Slot + Canvas setters | The target is a direct child of a Canvas and needs anchor/offset layout. | Returns None under any other direct parent. |
| Add Child to Canvas return slot | You are dynamically adding the child now. | Configure the returned slot directly. |
| Vertical/Horizontal Box Slot | A list/stack should flow automatically. | Padding/alignment/size rule, not Canvas position. |
| Grid Slot | Children belong in rows/columns. | Row/column/span replace Canvas anchors. |
| Set Position / Desired Size / Alignment in Viewport | The root User Widget already lives in a viewport/player-screen slot. | Does not move an arbitrary internal Canvas child. |
| Render Transform / Render Transform Pivot | You need a visual offset, scale, or rotation after layout. | Layout still reserves the original rectangle. |
| Size Box | A child needs explicit min/max/override size constraints. | Desired-size constraint, not Canvas placement. |
| Scale Box | Content should scale to fit an allotted rectangle. | Scaling policy differs from Size to Content. |
| Safe Zone | Platform unsafe regions need automatic padding. | Anchors alone do not know safe padding. |
Rule of thumb: ask which panel directly owns the child, get that panel's slot type, choose anchors before offsets, then decide whether manual size or desired size owns the rectangle.
Going deeper¶
- Project World Location to Widget Position and off-screen markers - producing player-local widget coordinates and applying marker pivots safely.
- Create Widget + Add to Viewport - root widget creation, owning player, viewport layers, and stored references.
- Set Visibility: Hidden, Collapsed, and hit testing - how visibility participates in layout without changing the parent slot.
- Updating a Widget: Bindings vs Events - choosing one update owner instead of competing layout writes.
- Official docs: UCanvasPanelSlot, UWidgetLayoutLibrary, Slot as Canvas Slot, UCanvasPanel, DPI Scaling, and UMG Safe Zones.
- Engine source (requires engine access - we do not reproduce it here):
UCanvasPanelSlot::SetAnchors,SetOffsets,SetAlignment,SetAutoSize, andSetZOrderinEngine/Source/Runtime/UMG/Private/Components/CanvasPanelSlot.cpp;UWidgetLayoutLibrary::SlotAsCanvasSlotinEngine/Source/Runtime/UMG/Private/WidgetLayoutLibrary.cpp; Canvas child-slot creation inEngine/Source/Runtime/UMG/Private/Components/CanvasPanel.cpp; and final arrangement inSConstraintCanvasunderEngine/Source/Runtime/Slate/Public/Widgets/Layout/SConstraintCanvas.h.