horizontal-viewport-segments: 2 专用于检测竖折折叠屏展开后的双视口物理分割状态,返回单侧宽度,需配合 spanning 特征识别跨铰链渲染,Grid 布局最适配,JS 必须监听 matchMedia change 事件确保响应式生效。

用 @media (horizontal-viewport-segments: 2) 检测双列折叠态
折叠屏展开后不是“变大了的手机”,而是被硬件铰链物理分割成两个独立视口——CSS 新增的 horizontal-viewport-segments 就是为此而生。它比 min-width 或 aspect-ratio 更可靠,因为只在真实双列渲染时触发,不会误判宽屏平板或横屏手机。
- 值为
2表示设备处于垂直折叠姿势(如 Galaxy Z Fold 展开后),此时浏览器实际渲染两个并列的 viewport,document.body.clientWidth返回的是单侧宽度(约 375–420px),而非总宽 - 必须配合
vertical-viewport-segments区分方向:横折(盖子式)用vertical-viewport-segments: 2,竖折(书本式)才用horizontal-viewport-segments: 2 - 注意兼容性:Chrome 119+、Edge 119+ 支持;Safari 和 Firefox 尚未实现,需降级到
screen.width > 700px+matchMedia('(max-aspect-ratio: 1/1)')组合判断
别只靠媒体查询,用 spanning 特征识别跨屏元素行为
CSS 的 spanning 媒体特征(如 (spanning: single-fold-horizontal))才是真正描述“内容是否跨过铰链”的能力。它不关心屏幕尺寸,只回答一个问题:“当前这个元素,有没有被强制渲染在两个物理屏幕上?”
-
spanning: none→ 元素完全落在单侧视口内(默认状态) -
spanning: single-fold-horizontal→ 元素横跨垂直铰链(即从左屏延伸到右屏),此时position: sticky会失效,transform可能被截断 - 典型误用:给导航栏加
spanning: single-fold-horizontal期望它横跨两屏,结果发现滚动时卡顿严重——因为浏览器需实时重绘跨屏合成层,性能代价高,应优先用布局规避跨铰链
Grid 布局 + grid-template-areas 是折叠适配最稳的组合
Flexbox 在折叠场景下容易因顺序线性导致错位(比如中间模块被挤到顶部),而 Grid 的命名区域可以显式声明“展开时大纲在左、编辑区在右;折叠时全堆叠”,无需改 DOM 结构。
- 基础写法:
.container { display: grid; grid-template-areas: "main"; } @media (horizontal-viewport-segments: 2) { .container { grid-template-areas: "sidebar main"; } } - 关键细节:每个
grid-area名称必须唯一,且不能含空格或特殊字符,否则解析失败静默忽略 - 性能提示:避免在
@media中频繁切换grid-template-areas配合大量animate,某些 Android WebView 会触发 layout thrashing
JavaScript fallback 必须监听 change 事件,不能只靠 onload
CSS 媒体查询无法响应用户中途折叠/展开的动作,JS 必须补位。但直接轮询 window.innerWidth 或监听 resize 会漏掉铰链状态切换(例如 Z Fold 从展开态合上时,resize 可能不触发)。
立即学习“前端免费学习笔记(深入)”;
- 正确做法:使用
window.matchMedia('(horizontal-viewport-segments: 2)')并监听其change事件 - 常见错误:
matchMedia返回对象未保存引用,导致后续无法removeEventListener,内存泄漏风险 - 兼容兜底:若
matchMedia不支持该特性,降级监听orientationchange+screen.orientation.angle变化,再结合window.screen.width粗略判断
spanning 特征也显示为 unsupported,必须连真机用 adb logcat 或远程调试查看实际媒体查询匹配结果。










