# iOS 状态栏颜色与页面几何

> 复现 iOS 18.6.2 如何选择主屏幕 Web App 的状态栏颜色，并用安全区处理 black-translucent 布局。

iOS 主屏幕 Web App 可以设置系统状态图标背后条带的颜色，也能把 CSS 视口延伸到条带下面。2026-10-20 的设备测试使用 iPhone 16 Pro 和 iOS 18.6.2 (22G100)：页面存在 `theme-color` meta 时，条带采用页面声明；`black-translucent` 与 `viewport-fit=cover` 同时使用时，页面获得全屏高度和顶部安全区 inset。

排查状态栏颜色或刘海区域布局时，可以按下面的步骤复现测试。你需要 HTTPS 页面、Web App Manifest、可将页面加入主屏幕的 iPhone，以及用于读取布局数据的 Mac Safari Web Inspector。文中的具体尺寸只对应这次归档测试（[研究数据包](https://openpwa.net/research/2026-10-ios18-home-screen-web-apps/data/)，openpwa.net）。

## 支持范围（Support）

实测结果适用于 iPhone 16 Pro 上的 Safari 和 iOS 18.6.2 主屏幕 Web App。WebKit 在 Safari 15 中加入 HTML meta 与 Web Manifest 的 `theme-color`，并说明它会改变 iOS Safari 的状态栏和 overscroll 区域颜色（[New WebKit Features in Safari 15](https://webkit.org/blog/11989/new-webkit-features-in-safari-15/)，webkit.org）。Web Application Manifest 允许页面的 `theme-color` meta 覆盖 manifest 的 `theme_color`，但没有要求浏览器必须覆盖（[Web Application Manifest，`theme_color`](https://www.w3.org/TR/appmanifest/#theme_color-member)，w3.org）。

颜色优先级和尺寸是 iOS 18.6.2 的实测结果，不能外推到所有 iOS 版本。这次测试没有分别安装 `default` 和 `black` 样式的 App，没有覆盖横屏、深色外观，也没有单独测试不带 `viewport-fit=cover` 的 `black-translucent`。

## 示例

分别运行颜色探针和几何探针，避免把最终渲染颜色与视口测量混为一项结果。

### 声明两处颜色

在文档中写入页面颜色，并保留 manifest 颜色作为应用上下文的默认值。归档测试的 M1 App 故意使用两个不同颜色，以便从截图判断浏览器选择了哪一处声明。

```html
<head>
  <meta name="theme-color" content="#00a050">
  <link rel="manifest" href="/manifest.webmanifest">
</head>
```

```json
{
  "name": "Status bar probe",
  "start_url": "/",
  "display": "standalone",
  "theme_color": "#d00000"
}
```

在 Safari 中将页面加入主屏幕，再从图标启动并截图。M1 条带内所有采样点都是 `#00a050`。M2 没有 manifest 颜色，采用 meta 的 `#d00000`；M3 没有页面 meta，采用 manifest 的 `#00a050`。因此，在这个系统版本上，页面 meta 优先，manifest 值用于页面没有 meta 的情况（[iOS 主屏幕 App 的状态栏颜色来源](/zh/lab/behaviour/status-bar-colour-source/)）。

先检查声明，再分析视觉差异。下面的代码会报告可用的来源；两处都没有时，它会明确进入浏览器默认颜色分支。

```js
const meta = document.querySelector('meta[name="theme-color"]');
const manifestLink = document.querySelector('link[rel="manifest"]');

if (meta?.content) {
  console.log({ source: 'document', colour: meta.content });
} else if (manifestLink) {
  console.log({ source: 'manifest', href: manifestLink.href });
} else {
  console.log({ source: 'none', action: 'use browser default' });
}
```

在 M1 文档中，预期输出是 `{ source: "document", colour: "#00a050" }`。这段代码检测声明，不读取条带最终渲染颜色；最终结果仍要用截图或设备测试确认。

:::caution
不要从 iOS 18.6.2 的这次测试推断 `default` 或 `black` 的表现。测试没有安装这两种 App，实验记录也撤回了早先关于它们的操作员回答。颜色优先级证据来自已记录的默认样式页面，几何证据只对应 `black-translucent` 与 `viewport-fit=cover` 的组合（[状态栏颜色来源](/zh/lab/behaviour/status-bar-colour-source/)；[black-translucent 视口几何](/zh/lab/behaviour/status-bar-black-translucent-geometry/)）。
:::

### 把内容延伸到状态栏下方

Apple 的归档 meta 文档说明，`black-translucent` 会让 Web 内容占据整个屏幕，并由状态栏遮住一部分；这个设置需要全屏 Web App 才生效（[Supported Meta Tags](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html)，developer.apple.com）。配合 `viewport-fit=cover` 使用后，用安全区环境变量让控件避开遮挡。CSS 规范从视口边缘定义安全区 inset，`cover` 则让视口采用包围屏幕的矩形（[CSS Environment Variables](https://drafts.csswg.org/css-env-1/#safe-area-insets)，csswg.org；[CSS Round Display，`viewport-fit`](https://drafts.csswg.org/css-round-display/#viewport-fit)，csswg.org）。

```html
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<style>
  .app-header {
    padding-top: env(safe-area-inset-top, 0px);
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }
</style>
```

不提供 inset 的浏览器会采用回退值 `0px`。归档的主屏幕 App 返回 402 x 874 的内部视口、62 px 顶部 inset 和 34 px 底部 inset。默认样式的对照页面返回 402 x 812，顶部 inset 为 0；对照页面加上 `viewport-fit=cover` 后，底部 inset 变为 34 px，顶部边界没有移动（[black-translucent 视口几何](/zh/lab/behaviour/status-bar-black-translucent-geometry/)）。

### 读取当前布局

让已安装 App 显示在前台，再连接 Web Inspector。创建临时固定定位元素，让计算样式解析环境变量，随后输出视口与 padding。

```js
const probe = document.createElement('div');
probe.style.cssText = [
  'position:fixed',
  'padding-top:env(safe-area-inset-top, 0px)',
  'padding-bottom:env(safe-area-inset-bottom, 0px)'
].join(';');
document.body.append(probe);

const style = getComputedStyle(probe);
console.log([innerWidth, innerHeight, style.paddingTop, style.paddingBottom]);
probe.remove();
```

iOS 18.6.2 的归档 App 读取输出 `[402, 874, "62px", "34px"]`。同一 URL 在 Safari 标签页中输出 `[402, 678, "0px", "0px"]`。比较数据之前，检查 `matchMedia('(display-mode: standalone)').matches` 或 `navigator.standalone`。两者都是 false 时，应先安装页面并从图标启动，因为标签页属于另一种显示环境。

如果使用 `black-translucent` 后 header 仍位于状态栏下方，先在当前文档中检查解析后的状态栏 meta 和 viewport 字符串。如果页面已经覆盖条带，但文字或控件碰到系统图标，保留全高视口，并把 `env(safe-area-inset-top)` 应用到内容容器。记录设备、系统 build、方向、meta 值、视口输出和截图，让结果始终绑定到测试配置。

## 另请参阅

- [Web Application Manifest，`theme_color`](https://www.w3.org/TR/appmanifest/#theme_color-member) (w3.org)
- [Supported Meta Tags](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html) (developer.apple.com)
- [iOS 主屏幕 App 的状态栏颜色来源](/zh/lab/behaviour/status-bar-colour-source/)
- [iOS 上的 black-translucent 视口几何](/zh/lab/behaviour/status-bar-black-translucent-geometry/)
- [`theme_color` 与 `background_color`](/zh/reference/manifest/theme-background-color/)