display_override: opting into window-controls-overlay and tabbed modes
In one line: display can only express the four values on its fixed fallback chain
(fullscreen → standalone → minimal-ui → browser). display_override is an ordered
array the browser walks before falling back to display, so it’s how you opt into newer
modes like window-controls-overlay and tabbed without losing a safe fallback on browsers
that don’t support them.
Why display_override exists
Section titled “Why display_override exists”display is a single value confined to one chain. There’s no way to say “use
window-controls-overlay if you can, otherwise behave like standalone” with display
alone, because window-controls-overlay isn’t on the chain. display_override solves this:
it lets you list preferred modes in priority order, and the browser uses the first one it
both recognizes and supports.
{ "display": "standalone", "display_override": ["window-controls-overlay", "minimal-ui"], "scope": "/app/", "start_url": "/app/"}How the browser resolves it
Section titled “How the browser resolves it”The browser evaluates display_override strictly in order, then falls back to display:
- Walk
display_overrideleft to right. Use the first entry that is a valid, supported display mode. - If no entry matches (all unknown or unsupported), ignore
display_overrideentirely and fall back to the plaindisplayvalue and its normal chain.
Two consequences follow from this:
- Unknown entries are skipped, not fatal. An older browser that has never heard of
window-controls-overlaysimply moves to the next entry, so the manifest degrades gracefully instead of breaking. display_overridedoes not inherit thedisplayfallback chain. Listing["fullscreen"]does not automatically fall through tostandalonethe waydisplay: "fullscreen"does. Within the override array each entry is considered on its own; the chain only resumes once the browser drops to thedisplayvalue.
The modes you actually unlock
Section titled “The modes you actually unlock”window-controls-overlay— on desktop, the app’s web content extends up into the title-bar area, and the window controls (close/minimize/maximize) overlay your content. You get the full window height for a custom toolbar. Use thetitlebar-area-*environment variables and thenavigator.windowControlsOverlayAPI to lay out a region that stays clear of the OS controls.tabbed— gives an installed app its own in-app tab strip so users can keep multiple app pages open inside one application window. Support is narrower and still evolving.standalone/minimal-ui/fullscreen/browser— the ordinarydisplayvalues are also legal insidedisplay_override, which is useful purely as an explicit fallback entry before the implicitdisplayfallback kicks in.
Browser & ecosystem support
Section titled “Browser & ecosystem support”The modes you can list inside display_override are still experimental and have limited
support, and they differ from one another. The cited MDN references mark
window-controls-overlay and the newer display modes as experimental and direct you to each
feature’s browser-compatibility table — treat those tables as the source of truth before
relying on a mode, and always pair any override with a display value that is widely
supported.
display_override, installability, and scope
Section titled “display_override, installability, and scope”- Installability counts
display_overridetoo. Per MDN’s installability guide, Chromium-based browsers require the manifest to includedisplayand/ordisplay_override, so listing override modes can itself satisfy that part of the criteria. Still keep adisplayvalue that launches an app-style window for the broadest coverage. - Scope still bounds the chrome treatment. When the user navigates outside
scope, the browser typically surfaces a prominent UI element (such as the address bar) to signal the context. Nothing forces an app context to stay in scope, but the overlay or tab strip is intended for the in-scope app launched fromstart_url.
Practical checklist
Section titled “Practical checklist”- Set a safe
display(usuallystandalone) so installability and old browsers are covered. - List override modes in true priority order — the first supported entry wins.
- Don’t rely on
display_overrideto fall through its own list likedisplaydoes. - For
window-controls-overlay, use thetitlebar-area-*env vars and the API to lay content out clear of the window controls; test the case where the overlay isn’t granted. - Feature-detect
navigator.windowControlsOverlaybefore assuming the overlay is active. - Treat
tabbedas progressive enhancement; verify behavior on each target browser.