Skip to content

Manifest · Manifest member

display_override manifest member

Published

display_override is an ordered array of display-mode strings that the browser walks before it consults display. The single display value is locked to the fixed fallback chain fullscreen → standalone → minimal-ui → browser, so it has no way to express window-controls-overlay or tabbed; display_override is where those modes are requested, with display left as the fallback for engines that skip the member.

Chrome 89, Edge 89, and Samsung Internet 15.0 process the member (BCD html.manifest.display_override). Firefox 157 and Safari 27 ignore it and apply display alone, and Android WebView does not read it at all.

  • Type: array of strings. Each string is a display mode: fullscreen, standalone, minimal-ui, browser, window-controls-overlay, or tabbed. Chromium also recognizes borderless, which only applies to Isolated Web Apps on ChromeOS.
  • Default: an empty array. With no display_override, the browser uses display.
  • Example value: ["window-controls-overlay", "minimal-ui"].

Processing follows the Manifest Incubations algorithm (wicg.github.io): strings that are not a display mode are dropped from the list, then the browser takes the first remaining mode it supports. Only when nothing in the list is supported does it fall back to display and that member’s own chain. Two consequences follow:

  • Unknown entries are skipped, not fatal. A browser that does not recognize window-controls-overlay moves to the next entry.
  • The override list has no implicit chain. ["fullscreen"] does not fall through to standalone the way display: "fullscreen" does; the chain resumes only after the browser drops to display.

Installability counts the member too. Chromium’s installability check accepts a manifest whose display is browser if the first supported display_override entry is app-like; when it is not, DevTools reports Manifest contains 'display_override' field, and the first supported display mode must be one of 'standalone', 'fullscreen', or 'minimal-ui' (components/webapps/browser/installable/installable_logging.cc).

The three manifests below share one display: "standalone" fallback and differ only in what they ask for first.

Requesting the title-bar overlay with a standalone fallback

Section titled “Requesting the title-bar overlay with a standalone fallback”

A desktop app that draws its own toolbar asks for window-controls-overlay first and names minimal-ui as an explicit second choice. display stays standalone so Firefox and Safari, and any Chromium build that rejects the overlay, still launch an app window.

{
"name": "Ledger",
"start_url": "/app/",
"scope": "/app/",
"display": "standalone",
"display_override": ["window-controls-overlay", "minimal-ui"]
}

On Windows and macOS the web content now extends into the title-bar strip and the close, minimize, and maximize buttons are drawn over it, so the page must reserve that area.

Laying out around the overlay and detecting it at runtime

Section titled “Laying out around the overlay and detecting it at runtime”

The titlebar-area-* environment variables describe the rectangle the overlay leaves free; they resolve to 0 when no overlay is active, which makes the same CSS safe in a plain standalone window. The script below checks navigator.windowControlsOverlay and the display-mode media feature (MDN, @media (display-mode)) and falls back to a normal header.

.toolbar {
position: fixed;
left: env(titlebar-area-x, 0);
top: env(titlebar-area-y, 0);
width: env(titlebar-area-width, 100%);
height: env(titlebar-area-height, 48px);
-webkit-app-region: drag;
}
const overlay = navigator.windowControlsOverlay;
const inOverlay =
overlay?.visible === true ||
matchMedia('(display-mode: window-controls-overlay)').matches;
document.documentElement.dataset.titlebar = inOverlay ? 'overlay' : 'standard';
overlay?.addEventListener('geometrychange', (event) => {
// The overlay can be toggled off by the user from the title bar; relayout.
document.documentElement.dataset.titlebar = event.visible ? 'overlay' : 'standard';
});

overlay.visible is false until the user accepts the overlay from the title-bar toggle Chrome shows on first launch, so the geometrychange listener, not the initial check, is what keeps the layout correct.

Trying tabbed without losing older Chromium builds

Section titled “Trying tabbed without losing older Chromium builds”

An installed app that wants an in-window tab strip lists tabbed first. Chrome 126, Edge 126, and Samsung Internet 28.0 honour it; Chrome 125 and earlier skip the entry and use the next one.

{
"display": "standalone",
"display_override": ["tabbed", "standalone"],
"tab_strip": {
"home_tab": { "scope_patterns": [{ "pathname": "/" }] },
"new_tab_button": { "url": "/new" }
}
}

The trailing "standalone" is redundant with display and is there only to document the intent; removing it changes nothing because the fallback to display is automatic.

Specifications

SpecificationStatus
Manifest Incubations: display_override memberWICG draft
Web Application Manifest: display memberW3C