Skip to content

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 when MyWidget is valid and is a direct child of a Canvas Panel. A None widget input or any other direct-parent type returns None silently; a later setter on that missing slot can produce Accessed 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 Size in 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 (Collapsed contributes 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 Size has 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.

  1. 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.
  2. You targeted the root viewport User Widget. Use viewport-slot functions for the root, or target its internal direct Canvas child.
  3. Anchors changed after offsets were authored. The same fields were reinterpreted as margins or position/size.
  4. Alignment was applied twice. Canvas alignment centers the widget, then manual half-size subtraction centers it again.
  5. Size to Content overrides manual size. Disable Auto Size or let desired size own the rectangle intentionally.
  6. 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.
  7. The Canvas is not viewport-sized. Anchors are correct relative to the wrong assumed parent rectangle.
  8. DPI coordinate spaces were mixed. A widget-ready coordinate was scaled again or a physical screen coordinate was used as a logical Canvas offset.
  9. Safe-zone padding was ignored or doubled. The anchor does not own safe area policy.
  10. 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