应使用 horizontal-viewport-segments 和 vertical-viewport-segments 媒体特性识别折叠屏真实分屏状态,chrome/edge 119+ 支持,需配合 @supports 降级,避免嵌套查询与 screen-spanning 等废弃特性,并用 visualviewport.width 防抖监听。

别用 @media (min-width: 720px) 或 @media (orientation: landscape) —— 这些根本不能识别折叠态,只会把平板、横屏手机全卷进来,真正的半开 Z Fold 或展开 Pocket 反而漏掉。
用 horizontal-viewport-segments 和 vertical-viewport-segments 判断物理分屏
这两个媒体特性才是当前唯一能反映铰链真实分割状态的信号,Chrome/Edge 119+ 稳定支持,Safari/Firefox 尚未实现。
-
horizontal-viewport-segments: 2表示竖折设备(如 Galaxy Z Fold)已展开,浏览器渲染左右两个独立视口,document.body.clientWidth返回单侧宽度(约 375–420px),不是总宽 -
vertical-viewport-segments: 2对应横折/翻盖式设备(如华为 Pocket 展开),高度被物理分割,此时用height相关布局才合理 - 值只能是整数
1或2,不能写>1、=2或min-horizontal-viewport-segments - 不要嵌套在其他查询里,比如
@media (min-width: 768px) and (horizontal-viewport-segments: 2)会失效
必须配合 @supports 降级,否则旧浏览器直接忽略整条规则
不加 @supports,Safari、Firefox 以及旧版 Chrome 会跳过整个 @media 块,导致样式完全不生效。
- 正确写法:
@supports (horizontal-viewport-segments: 2) { @media (horizontal-viewport-segments: 2) { ... } } - 避免同时定义
horizontal-viewport-segments和vertical-viewport-segments规则覆盖同一元素——CSS 变量如--fold-state会被后声明的覆盖,建议统一用:root设一个变量 - 别信
screen-spanning:它压根没进标准,DevTools 里看不到匹配状态,Chromium 内部已标记为“废弃”,连 MDN 都移除了文档
JS 监听要防抖,且读 visualViewport.width 而非 window.innerWidth
CSS 媒体查询只响应静态状态,但折叠过程有半开、动画帧、系统延迟上报等中间态,matchMedia 会频繁触发 false positive。
- 监听方式:
const mq = window.matchMedia('(horizontal-viewport-segments: 2)'),不是window.onresize - 必须加至少 100ms 防抖,否则 UI 会疯狂抖动
- 取值要用
visualViewport.width:它反映当前渲染视口的实际宽度;window.innerWidth在折叠过渡期常返回错误值(比如仍维持展开前尺寸) - 注意:iframe 内无法访问
visualViewport,需确保脚本运行在顶层上下文
真正麻烦的不是怎么写对,而是怎么让不同浏览器在不同阶段都给出可预测的反馈——horizontal-viewport-segments 在 Chrome 里返回 2 的那一刻,Safari 里可能还卡在 1,而用户手指刚松开铰链,页面已经重绘了三次。这种时间差没法靠 CSS 消除,得靠 JS 校验 + 视觉容错设计兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











