env()无法区分内外屏,因其仅提供安全区偏移;唯一可靠信号是@media (horizontal-viewport-segments: 2),需配合@supports校验、visualViewport.width读取和devicePixelRatio辅助判断。

直接用 env() 适配安卓折叠屏内外屏分辨率,行不通——env() 只提供安全区偏移(如 env(safe-area-inset-bottom)),不暴露屏幕物理分割、DPR 或内外屏切换状态。真正能区分内外屏的,是视口分段媒体特性 + DPR 组合判断。
为什么 env() 不能用于分辨内外屏
env() 是安全区环境变量,只在有物理遮挡(刘海、挖孔、铰链折痕)时返回非零值,且仅限于“避开不可交互区域”,和“当前渲染在哪块屏”完全无关。Z Fold 内屏展开态、外屏全屏态、半开态三者 env(safe-area-inset-bottom) 值可能完全相同,但逻辑分辨率、DPR、可用宽度天差地别。
- 内屏展开:逻辑宽约
420px,devicePixelRatio === 3,horizontal-viewport-segments: 2 - 外屏全屏:逻辑宽约
375px,devicePixelRatio === 3,horizontal-viewport-segments: 1 - 半开态(内屏竖折):
visualViewport.width ≈ 375–420px,但horizontal-viewport-segments不匹配,env()无变化
@media (horizontal-viewport-segments: 2) 是唯一可靠信号
这是目前 Chromium 系列(Chrome/Edge 119+)、Samsung Internet 支持的、能稳定识别“内屏已物理展开为双视口”的标准媒体特性。它不依赖 UA、不看宽高、不靠 DPR,只反映浏览器是否被系统告知“当前渲染需跨两个物理面板”。
- 必须配合
@supports (horizontal-viewport-segments: 2)使用,否则旧浏览器直接跳过整条规则 - 匹配时
document.body.clientWidth返回单侧宽度(不是总宽),所以不要用它算栅格总列数 - 典型用法是透传状态到 CSS 变量:
@supports (horizontal-viewport-segments: 2) { :root { --screen-mode: inner-dual; } } - 未匹配时,
:root中必须显式设默认值,例如--screen-mode: outer-single;,否则var(--screen-mode)为unset
结合 devicePixelRatio 区分内外屏渲染密度
Z Fold 系列内外屏 DPR 均为 3,但 Pixel Fold 外屏 DPR=2.8、内屏 DPR=3.5;华为 Mate X5 内屏 DPR=3.0、外屏 DPR=2.6。仅靠 DPR 不足以判断内外屏,但可辅助校验:
本地 Ollama 文生图工具。使用 x/z-image-turbo 模型生成图片,分辨率 1024x1024,每张图约耗时 90 秒。当用户说"生成图片"、"文生图"、"画一张图"、或提交中文提示词生成图像时使用。
- 当
horizontal-viewport-segments: 2匹配且devicePixelRatio >= 3.3→ 高概率为内屏展开(如 Pixel Fold) - 当
horizontal-viewport-segments: 1且window.visualViewport.width 且devicePixelRatio → 更倾向外屏全屏态 - JS 中应读
visualViewport.width而非window.innerWidth,后者在折叠动画中严重抖动 - 避免用
matchMedia回调直接改样式,加requestAnimationFrame批量更新类名更稳
实际布局建议:用 Grid + 变量控制区域锚定
Flexbox 在内外屏切换时容易因 flex-basis 计算错位导致模块重排;Grid 的命名区域(grid-template-areas)能稳定绑定内容位置,更适合折叠场景。
- 内屏双视口态:
@supports (horizontal-viewport-segments: 2) { .layout { grid-template-areas: "sidebar main"; } } - 外屏单视口态:
.layout { grid-template-areas: "main"; } - 所有区域用
min-width: 0+overflow: hidden防止内容撑破容器 - 不要对
env()做calc()运算(如calc(16px + env(safe-area-inset-bottom))),部分浏览器切换时不会重算
最易被忽略的一点:安卓折叠屏的“内外屏”不是纯 CSS 能推断出来的概念——它由系统渲染管线决定,而 CSS 只能响应浏览器暴露的有限信号。真正健壮的适配,永远是 @supports + visualViewport + devicePixelRatio 三层校验,缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










