iOS 状态栏颜色与页面几何
发布于
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。文中的具体尺寸只对应这次归档测试(研究数据包,openpwa.net)。
支持范围(Support)
链接到“支持范围(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,webkit.org)。Web Application Manifest 允许页面的 theme-color meta 覆盖 manifest 的 theme_color,但没有要求浏览器必须覆盖(Web Application Manifest,theme_color,w3.org)。
颜色优先级和尺寸是 iOS 18.6.2 的实测结果,不能外推到所有 iOS 版本。这次测试没有分别安装 default 和 black 样式的 App,没有覆盖横屏、深色外观,也没有单独测试不带 viewport-fit=cover 的 black-translucent。
分别运行颜色探针和几何探针,避免把最终渲染颜色与视口测量混为一项结果。
声明两处颜色
链接到“声明两处颜色”一节在文档中写入页面颜色,并保留 manifest 颜色作为应用上下文的默认值。归档测试的 M1 App 故意使用两个不同颜色,以便从截图判断浏览器选择了哪一处声明。
<head> <meta name="theme-color" content="#00a050"> <link rel="manifest" href="/manifest.webmanifest"></head>{ "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 的状态栏颜色来源)。
先检查声明,再分析视觉差异。下面的代码会报告可用的来源;两处都没有时,它会明确进入浏览器默认颜色分支。
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" }。这段代码检测声明,不读取条带最终渲染颜色;最终结果仍要用截图或设备测试确认。
把内容延伸到状态栏下方
链接到“把内容延伸到状态栏下方”一节Apple 的归档 meta 文档说明,black-translucent 会让 Web 内容占据整个屏幕,并由状态栏遮住一部分;这个设置需要全屏 Web App 才生效(Supported Meta Tags,developer.apple.com)。配合 viewport-fit=cover 使用后,用安全区环境变量让控件避开遮挡。CSS 规范从视口边缘定义安全区 inset,cover 则让视口采用包围屏幕的矩形(CSS Environment Variables,csswg.org;CSS Round Display,viewport-fit,csswg.org)。
<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 视口几何)。
读取当前布局
链接到“读取当前布局”一节让已安装 App 显示在前台,再连接 Web Inspector。创建临时固定定位元素,让计算样式解析环境变量,随后输出视口与 padding。
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(w3.org) - Supported Meta Tags (developer.apple.com)
- iOS 主屏幕 App 的状态栏颜色来源
- iOS 上的 black-translucent 视口几何
theme_color与background_color