Responsive Layouts in Delphi FMX: Align, Anchors, and the Layout Controls That Do the Work for You
Stop hand-coding control positions in FMX. Align, anchors, margins, and container layouts like TGridPanelLayout give you resolution-independent forms across Windows, macOS, iOS, and Android — with no resize handlers.
12 Jul 2026, 10:59 UTC

Hard-coding Left, Top, Width, and Height on an FMX form feels fast until you run the same app on a 5-inch Android phone, a 13-inch Windows tablet, and a maximized 4K desktop monitor. Buttons overlap, labels clip, and the form that looked fine in the designer falls apart. The fix is not more pixel math — it is letting FMX's layout system do the positioning for you.
This post walks through the three mechanisms that matter — Align, anchors, and the container layout controls — with a worked example you can build in a few minutes. It assumes a recent Delphi version (11.x or later) and a Multi-Device Application project; the behavior described is long-established FMX behavior, but property names are worth confirming in your IDE's Object Inspector.
Align: the first thing to reach for
Every FMX TControl has an Align property (a TAlignLayout value). Instead of absolute coordinates, you declare intent: Top docks a control to the parent's top edge and stretches it full width; Client fills whatever space remains; Center floats the control in the middle; Scale resizes proportionally with the parent.
The mental model that makes this click: aligned controls consume space in z-order. The first Top-aligned control takes the top strip, the next one takes the top of what remains, and the Client-aligned control gets the leftovers. When the form resizes, FMX re-runs this calculation automatically. That is your responsive behavior, for free.
Two properties refine the result: Margins adds space outside a control (pushing siblings away), and Padding adds space inside a container (pushing children inward). Using these instead of manual gaps keeps spacing consistent when the layout recalculates.
Anchors: when docking is too rigid
Docking works until you need something like "stay 16 pixels from the bottom-right corner." That is what Anchors is for. By default a control is anchored to the top-left, so when the parent grows, the control stays put. Enable akRight and akBottom and the control maintains its distance from those edges instead — the classic pattern for an OK/Cancel button pair.
The trade-off: anchors preserve distance, not proportion. A control anchored on all four sides stretches with the parent, which is rarely what you want for buttons but works well for a memo or image. If you find yourself fighting anchors to keep a control centered, switch to Align := Center instead.
Let container layouts replace your resize handlers
For anything beyond a handful of controls, drop the manual approach entirely and use FMX's layout containers:
TLayout— a plain container. Group controls inside it, then align the whole group as one unit.TGridPanelLayout— rows and columns with proportional or absolute sizing. Ideal for forms and settings screens; add a row and everything reflows.TFlowLayout— children flow left-to-right and wrap, like words in a paragraph. Great for tag clouds or button sets that must survive narrow screens.TScaledLayout— scales all children proportionally to the container. Useful for dashboards designed at one fixed resolution; less suitable for text-heavy UIs, since scaled text can look soft.
Worked example: a settings row that survives any screen
Create a new Multi-Device Application, then build this on the main form:
- Drop a
TGridPanelLayout, setAlign := Client. In itsColumnCollection, create two columns; set the first to an absolute width (e.g., 120) and the second to a percentage of 100. Add one row. - Drop a
TLabelinto column 0 withAlign := ClientandMarginsof 8 on each side. - Drop a
TEditinto column 1 withAlign := Clientand the same margins. - Drop a
TLayouton the form withAlign := Bottom,Height := 56. Inside it, place aTButtonwithAnchors := [akRight, akBottom](disable the default top/left anchors) and position it near the right edge.
Run on Windows, grab the form corner, and resize aggressively. The label column stays fixed, the edit absorbs all extra width, and the button tracks the bottom-right corner — with zero resize code. Deploy to an Android or iOS target and the same logic holds; FMX's display scaling handles pixel-density differences so your logical sizes stay consistent across a phone and a desktop monitor.
Trade-offs and limitations
Deeply nested aligned layouts are not free. Every resize triggers a layout pass through the nesting tree, and on lower-end mobile devices a pathological hierarchy (many nested TLayouts each with aligned children and margins) can produce visible lag during rotation. Keep nesting shallow; prefer one TGridPanelLayout over five stacked TLayouts.
Also note that FMX alignment semantics differ from VCL's — don't assume a VCL form's docking strategy ports directly. And third-party FMX controls occasionally misbehave inside container layouts if they override sizing methods. The practical check: after building a screen, resize the form to its minimum useful size and to fullscreen, and rotate a mobile device, watching for clipping or controls that stop tracking their edges. If a control drifts, inspect its Align, Anchors, and Margins in that order — one of the three is almost always the culprit.
Where to start
Pick your most-broken form, strip out any OnResize positioning code, and rebuild it with a TGridPanelLayout plus aligned children. You'll likely delete code and gain resolution independence in the same commit. That is the real payoff: responsive layout in FMX is a declaration, not a calculation.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.