# display 清单成员

> display 成员决定已安装的 Web 应用保留多少浏览器界面：fullscreen、standalone、minimal-ui 或 browser，四个值位于一条固定的回退链上。

`display` 决定已安装的 Web 应用启动时保留多少浏览器自身的界面。四个值位于一条固定的回退链上：
`fullscreen` → `standalone` → `minimal-ui` → `browser`，平台不提供的模式会自动降级到下一个，
作者无需做任何额外处理。

Android 上的 Chrome 39、桌面端的 Chrome 73、Edge 79、Samsung Internet 4.0 与 iOS 上的 Safari
11.3 会把该成员应用到已安装应用；macOS 上的 Safari 17 把它应用到 Dock 应用（BCD
`html.manifest.display`）。桌面端 Firefox 157 不从清单安装 Web 应用，所以这个值在那里没有
消费者。回退链之外的模式（`window-controls-overlay` 与 `tabbed`）要通过 `display_override`
请求，`display` 本身表达不了。

## 成员

- **类型**：字符串，取 `fullscreen`、`standalone`、`minimal-ui`、`browser` 之一。
- **默认值**：`browser`。缺省与无法识别的值都解析为 `browser`；后者会让 Chromium 记录
  `unknown 'display' value ignored.`。
- **示例值**：`"standalone"`。

各个值去掉的界面，从多到少：

- `fullscreen` 占据整块屏幕，在平台允许的情况下连系统状态栏也隐藏。Android 上应用仍可能保留
  系统返回手势。
- `standalone` 打开独立窗口，没有地址栏与标签栏，但保留系统层面的界面，例如状态栏与窗口标题栏。
- `minimal-ui` 是 `standalone` 加上一组最少的导航控件；具体显示哪些控件由浏览器决定（MDN 列出
  的典型例子是后退、前进与重新加载）。iOS 上的 Safari 把它映射为 `standalone`（BCD 对 Safari
  iOS 的注记）。
- `browser` 在普通标签页里打开。Chromium 把它视为"不想成为应用"：可安装性检查报告
  `Manifest 'display' property must be one of 'standalone', 'fullscreen', or 'minimal-ui'`，
  不会提供安装提示，除非 `display_override` 先给出一个应用式模式。

回退链只向下走。请求 `fullscreen`，而平台没有全屏应用窗口时，你得到的是 `standalone`，再往下是
`minimal-ui`、`browser`；只需要写你想要的最高模式。`display` 只管辖 scope 内的页面：导航到
`scope` 之外时，无论什么模式，Chrome 都会重新显示地址栏，Safari iOS 16.4 则显示应用内横幅。

:::observed
Chrome 155（macOS 26，英文界面）的 DevTools > Application > Manifest：清单写
`"display": "browser"` 且没有 `display_override` 时，**Installability** 一节显示
`Manifest 'display' property must be one of 'standalone', 'fullscreen', or 'minimal-ui'`，
地址栏里的安装图标不出现。把值改为 `"standalone"` 并重新加载后，这一行消失，图标重新出现。
:::

## 示例

示例从清单声明一路走到运行中的页面能了解到的模式信息。

### 为游戏请求全屏并以 standalone 回退

一款游戏请求整块屏幕。平台拒绝时（桌面端 Chrome 给已安装应用的是窗口，不是 kiosk 模式），回退链
落到 `standalone`，游戏仍然在没有地址栏的窗口里运行。

```json
{
  "name": "Orbit",
  "start_url": "/play/",
  "scope": "/play/",
  "display": "fullscreen",
  "orientation": "landscape",
  "background_color": "#000000"
}
```

在 Android 上把 `fullscreen` 与 `orientation` 搭配使用很重要：方向锁定只在 `fullscreen`、
`standalone` 与 `minimal-ui` 下生效，同一份清单在浏览器标签页里不会锁定方向。

### 在运行时检测解析出的模式

浏览器不会暴露清单请求的值，但会通过 `display-mode` 媒体特性暴露它最终解析出的模式（MDN 的
[display-mode](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/display-mode) 页面）。用它在应用窗口里隐藏仅网页需要的页头；查询全都不匹配时保留页头，
这正是浏览器标签页会走的分支。

```js
const modes = ['window-controls-overlay', 'fullscreen', 'standalone', 'minimal-ui', 'browser'];

function resolvedDisplayMode() {
  const hit = modes.find((m) => matchMedia(`(display-mode: ${m})`).matches);
  if (hit) return hit;
  // iOS 13 之前的 Safari 只通过 navigator.standalone 暴露应用窗口。
  return navigator.standalone === true ? 'standalone' : 'browser';
}

document.documentElement.dataset.display = resolvedDisplayMode();
```

`matchMedia` 反映的是页面所在的窗口，所以同一段代码在标签页里打开的站点上返回 `browser`，
在已安装应用里返回 `standalone`；要在两种环境下核对布局，这就是你需要的测试工具。

### 只用 CSS 把网页页头挡在应用窗口之外

当变化只是视觉上的，跳过脚本，直接在媒体特性上切换。

```css
.site-header {
  display: block;
}

@media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
  .site-header {
    display: none;
  }
}
```

这条规则在浏览器标签页以及任何没有实现 `display-mode` 的引擎里都保留页头，对导航而言是安全
的默认行为。

## 另请参阅

- [display_override 清单成员](/zh/reference/manifest/display-override/)
- [scope 清单成员](/zh/reference/manifest/scope/)
- [orientation 清单成员](/zh/reference/manifest/orientation/)
- [可安装性标准：什么让 PWA 可安装](/zh/reference/installation/installability-criteria/)
- [Web Application Manifest: display member](https://www.w3.org/TR/appmanifest/#display-member)（w3.org）
- [display-mode](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/display-mode)（developer.mozilla.org）