Building Genuinely Responsive Canvas Apps
Turn off Scale to fit, build from containers, and compute layout from Parent.Width instead of placing controls at coordinates.
Rajiv KumarJanuary 5, 20215 min readCanvas apps scale a fixed rectangle by default, which is why they look shrunken on phones. Real responsiveness means switching scaling off and building layout that computes itself from containers and break points.
Canvas apps default to a fixed canvas. You pick a size, you place controls at coordinates, and the app scales that rectangle to whatever screen it lands on. On a monitor close to the design size it looks correct. On a phone it becomes a shrunken desktop, and on an ultrawide it floats in the middle with wasted space either side.
Genuinely responsive canvas apps are achievable, but not by adjusting a setting. They require turning scaling off and building layout that computes itself.
Turn off the scaling first
Nothing else works until this is done. In Settings > Display:
- Scale to fit — Off. This is the setting that stretches your fixed canvas. While it is on, the app cannot respond to anything.
- Lock aspect ratio — Off. Otherwise the app keeps a shape that no longer relates to the device.
- Lock orientation — Off, unless the application genuinely only works one way up.
Turning these off is disorienting: the app immediately looks wrong, because controls placed at absolute coordinates no longer have a guaranteed canvas. That is the correct starting point. From here, position is something you calculate.
Design from containers, not coordinates
Layout containers are what make this tractable. A horizontal or vertical container positions its children automatically, which removes most of the arithmetic.
The structure that works:
- A vertical container filling the screen, holding header, body and footer
- A horizontal container for the body, holding navigation and content
- Nested containers inside those for individual regions
With Flexible height and Flexible width on children, a container distributes available space among them. The result reflows genuinely rather than scaling.
The discipline that matters: once you commit to containers, do not mix in absolutely positioned controls. A single control with a hard-coded X breaks the layout at exactly the size you did not test.
Break points, expressed once
Responsive design needs a definition of "small". Define it once in App.OnStart or as a named formula, then reference it everywhere:
// App.OnStart
Set(gblBreakSmall, 768);
Set(gblBreakMedium, 1024);
Then drive layout from the actual screen width:
// Stack vertically on small screens, side by side otherwise
Parent.Width < gblBreakSmall
// Hide a secondary panel where there is no room for it
Parent.Width >= gblBreakMedium
// Proportional width with a sensible minimum
Max(280, Parent.Width * 0.28)
Two habits make this maintainable. Use Parent.Width rather than App.Width, so a control responds to its container rather than the whole app. And use Max() or Min() on proportional sizes, so a 28% column does not become unusably narrow on a phone.
Galleries need explicit attention
Galleries are where fixed-size thinking survives longest, because the template is designed at one width and then never revisited.
Set the gallery's TemplateSize and its layout responsively, and size controls inside the template from Parent.TemplateWidth rather than absolute values. A flexible-height gallery in a container will then fill available vertical space instead of leaving a gap or overflowing.
For data-dense screens, consider changing the shape rather than the size: a table-like layout on a wide screen and a stacked card layout on a phone communicate the same information far better than one layout squeezed into both.
Common mistakes and better practice
- Leaving Scale to fit on. No amount of formula work will help while the app is being stretched.
- Mixing containers and absolute positioning. One hard-coded coordinate undoes a container's layout.
- Using
App.Widtheverywhere.Parent.Widthkeeps controls responsive to their own region, which is what makes nesting work. - Percentages without bounds. Wrap proportional sizes in
Max()orMin()so they stay usable at extremes. - Testing only by resizing the browser. Browser resizing does not reproduce device pixel ratios, on-screen keyboards, or touch targets. Test on a real phone.
- Hard-coded font sizes. Text that is comfortable on a desktop can be unreadable on a phone. Scale key sizes with the break point.
- Forgetting the keyboard. On mobile, an on-screen keyboard removes roughly half the viewport. Forms need to remain usable with the field in view.
Troubleshooting
| Symptom | Cause | Resolution |
|---|---|---|
| App still scales rather than reflows | Scale to fit is on | Turn it off in Settings > Display |
| Controls overlap on narrow screens | Absolute positioning inside a container | Replace X and Y with container-managed layout |
| Container children do not resize | Flexible width or height not enabled | Enable them on each child |
| Layout correct in the studio, wrong on device | Studio preview does not match device dimensions | Test on the real device; use the player, not just preview |
| Gallery leaves a gap at the bottom | Fixed height rather than flexible | Set flexible height inside a vertical container |
| Text unreadable on mobile | Font sizes fixed at desktop values | Vary size with the break point |
Frequently asked questions
Can an existing fixed-layout app be made responsive?
Yes, but it is a rebuild of the layout rather than an adjustment. Screens generally need to be reconstructed around containers. Plan it as real work.
Do containers affect performance?
Deeply nested containers add layout calculation. Two or three levels is comfortable; six suggests the screen is doing too much and should be split.
Should there be separate apps for phone and desktop?
Occasionally, when the tasks genuinely differ — a field data-capture app versus a management dashboard. For the same task on different screens, one responsive app is easier to maintain than two.
Why does the studio look right when the device does not?
The studio preview does not reproduce device dimensions, pixel density or the on-screen keyboard. Always confirm on a real device.
Are named formulas useful here?
Yes. Defining break points and derived sizes as named formulas keeps them in one place and avoids the OnStart timing issues that Set() can introduce.
The trade-off worth naming
Responsive canvas apps take longer to build. Absolute positioning is faster, and for a genuinely desktop-only internal tool it can be a defensible choice.
Make that call deliberately rather than by default. The apps that cause trouble are the ones built fixed because it was quicker, then used on phones because that is where the work happens.

