Why Your App Looks Wrong on Phone: The Three Default Values Nobody Mentions
Every canvas control carries a tablet default, a phone default, and a web default. They disagree with each other by up to 3.7×.
You build an app for tablet. Someone opens it on a phone. The text is enormous, the buttons are the wrong shape, and nothing lines up. The standard explanation is “canvas apps are not responsive” — which is not the whole story, and the missing part is measurable.
Control properties do not have a default. They have up to three:
<appMagic:includeProperty name="Size" defaultValue="14" phoneDefaultValue="24" />
<appMagic:includeProperty name="Width" defaultValue="150" phoneDefaultValue="560" webDefaultValue="260" />
<appMagic:includeProperty name="Height" defaultValue="40" phoneDefaultValue="70" webDefaultValue="40" />
defaultValue is tablet. phoneDefaultValue is phone. webDefaultValue is the web player. Which one a control is born with depends on the form factor of the app at the moment you drop it on the screen.
Here is every divergence in the controls we examined.
Font size
| Control | Tablet | Phone | Web |
|---|---|---|---|
label | 14 | 24 | — |
datepicker | 14 | 24 | — |
text | 14 | 24 | 12 |
htmlViewer | — | 24 | — |
button | 13 | 23 | — |
timer | 13 | 23 | — |
attachments | 13 | 21 | — |
combobox | — | 30 | — |
A label is 14pt on tablet and 24pt on phone — a 71% jump. The combobox goes to 30. And the text control is the interesting one: 14 on tablet, 24 on phone, 12 on web. Three form factors, three sizes, a 2× spread between largest and smallest.
The intent is legibility on a small dense screen, and in isolation it is defensible. The problem is that it applies at creation time, not at render time. A label created in a tablet app keeps Size = 14 forever, including on a phone. A label created in a phone app keeps 24, including on a 27-inch monitor.
Width and height
| Control | Tablet | Phone | Web |
|---|---|---|---|
label | 150 × 40 | 560 × 70 | 260 × 40 |
text | 320 × 40 | 560 × 70 | 180 × 32 |
button | 160 × 40 | 280 × 70 | 85 × 32 |
timer | 160 × 40 | 280 × 70 | 85 × 32 |
combobox | 328 × 40 | 575 × 70 | 180 × 32 |
datepicker | 328 × 40 | 575 × 70 | 180 × 32 |
image | 100 × 100 | 320 × 320 | 236 × 175 |
attachments | 330 × 300 | 575 × 520 | 384 × — |
htmlViewer | 200 × 40 | 560 × 70 | — |
The label is the clearest case: 150px wide on tablet, 560px on phone. That is 3.7×. A phone label is nearly the full 640px phone width by default; a tablet label is a tenth of the 1366px tablet width.
Buttons go the other way on web: 160 wide on tablet, 280 on phone, 85 on web. The web player expects compact, dense chrome. Tablet expects touch targets. Phone expects full-width blocks.
Note the height pattern too: 40 on tablet, 70 on phone, 32 on web for essentially every input control. Three completely different touch-target philosophies, encoded as literals in the same template.
The image control gives the game away: 100 × 100 square on tablet, 320 × 320 square on phone, 236 × 175 on web. Somebody picked a 4:3-ish rectangle for web and squares for the other two.
Padding
The combobox is the only control in our sample that changes padding by form factor:
| Property | Tablet | Phone |
|---|---|---|
PaddingTop | 5 | 10 |
PaddingRight | 5 | 10 |
PaddingBottom | 5 | 10 |
PaddingLeft | 5 | 10 |
Double the padding on phone. No other control does this, which means combobox internals are spaced differently from every neighbouring input if you mix form factors.
The layout ceilings move too
The hidden sizing clamps are also form-factor aware:
| Control | Tablet max | Phone max |
|---|---|---|
groupContainer | 1366 × 7680 | 640 × 11360 |
datepicker | 1366 × 768 | 640 × 1136 |
The phone container is allowed to be 11,360px tall against the tablet’s 7,680 — because phone layouts are long scrolls. And 640 × 1136 is an iPhone 5 viewport at 2× density, a number frozen into the template years ago.
fluidGrid also declares NumberOfColumns with defaultValue="1" and phoneDefaultValue="1" — identical, which is its own small piece of evidence that the phone overrides were added mechanically across properties rather than deliberately per property.
Why this actually bites
Converting an app between form factors does not convert its controls. The defaults were baked in when each control was created. Change the layout orientation and the controls keep the values they were born with. This is the mechanism behind “I switched to phone layout and everything is broken.”
Copy-paste carries the source form factor’s values. Paste a control from a phone app into a tablet app and it arrives at 24pt in a 14pt world. It looks like the theme is broken. The theme is fine.
Components are worse. A component authored in one form factor and consumed in another brings its defaults along, and there is no signal to the consumer that this happened.
Mixed-provenance screens explain “inconsistent” apps. If a screen was built partly by a maker on tablet, partly pasted from a phone app, partly generated from a form, you get three sets of defaults on one screen. That is not sloppiness; it is three different *DefaultValue attributes doing exactly what they say.
What to do
- Pick a form factor before you build, and do not change it. The defaults are set at creation; retrofitting means touching every control.
- Set
Sizeexplicitly on anything that matters. If you never set it, you have inherited a number chosen for a different device. - Never trust pasted controls. Check
Size,Width,Height— and on comboboxes, padding — after any cross-app paste. - Standardise with theme styles instead of defaults. The theme file carries 116 named styles (
defaultLabelStyle,titleLabelStyle,headerLabelStyle, …) mapping properties to palette tokens. A style applies the same values regardless of which form factor the control was created in. It is the only mechanism here that is form-factor neutral. - If you generate apps programmatically, choose the defaults yourself. Do not inherit; emit explicit values for
Size,Width,Heightand padding on every control. That is the only way to get a deterministic result across form factors.
The summary: canvas apps are not non-responsive by accident. They are creation-time responsive — the platform picks good values for your device once, writes them down, and never revisits them. Every layout problem you have had moving between phone and tablet is the gap between those two ideas.
Methodology
Sample: 15 classic control templates from two production .msapp exports (2023-02-14, 2026-02-16). All values quoted directly from References/Templates.json.
unzip -q app.msapp -d app/
python3 - <<'EOF'
import json, re
for t in json.load(open('app/References/Templates.json'))['UsedTemplates']:
for m in re.finditer(r'<appMagic:includeProperty name="([^"]+)"([^/>]*)', t['Template']):
a = m.group(2)
if 'phoneDefaultValue' in a or 'webDefaultValue' in a:
g = lambda k: (re.search(k + r'="([^"]*)"', a) or [None, '-'])[1]
print(f"{t['Name']:<14}{m.group(1):<16}"
f"tablet={g('defaultValue'):<8}phone={g('phoneDefaultValue'):<8}web={g('webDefaultValue')}")
EOF
A dash means the attribute is absent, in which case the control falls back to defaultValue. The modern (PCF) controls use a different metadata format and are not covered by this table.