horizontal-viewport-segments: 2 是唯一能准确识别 Z Fold 展开态的媒体特性,必须单独使用且包裹于 @supports 中,值为整数 2,不可比较或嵌套;vertical-viewport-segments: 2 专用于竖折设备如 Pocket,二者不可混用。

horizontal-viewport-segments: 2 是唯一能识别 Z Fold 展开态的媒体特性
写 @media (min-width: 720px) 或 @media (orientation: landscape) 根本抓不住 Z Fold 展开时的真实状态——它返回的是单侧宽度(约 390px),不是总宽,布局会错乱。只有 horizontal-viewport-segments: 2 能明确告诉浏览器:“当前左右两个物理视口已就绪”,Chrome/Edge 119+ 稳定支持。
常见错误现象:
-
@media (horizontal-viewport-segments > 1)写法无效,值必须是整数2,不能带比较符或单位 - 嵌套在其他查询里,比如
@media (min-width: 768px) and (horizontal-viewport-segments: 2),部分浏览器直接丢弃整条规则 - 没加
@supports,Safari/Firefox 和旧版 Chrome 会静默跳过,样式完全不生效
实操建议:
- 单独使用:
@media (horizontal-viewport-segments: 2),不要拼接其他条件 - 搭配
@supports (horizontal-viewport-segments: 2)包裹整个块,确保降级安全 - 匹配时
document.body.clientWidth返回单侧宽度(如 375px),别用它算“总宽”,双栏布局应基于grid-template-columns: 1fr 1fr或固定列宽
vertical-viewport-segments: 2 专用于翻盖式设备(如 Pocket)
vertical-viewport-segments: 2 不是 orientation: portrait 的替代品,而是物理铰链水平切割屏幕后的信号:上下两个独立视口已激活。华为 Pocket、Galaxy Z Flip 展开后才匹配,此时高度被分割,height 相关布局才有意义。
立即学习“前端免费学习笔记(深入)”;
常见误用:
- 混用
screen-spanning: single-fold-vertical—— 这个特性已被 Chromium 废弃,DevTools 里根本看不到匹配状态 - 对 Z Fold 写
vertical-viewport-segments: 2,它只响应水平铰链,竖折设备永远不匹配 - 写成
vertical-viewport-segments: 1或3,合法值只有1(单屏)和2(双段)
典型布局:
- 顶部工具栏设为
height: 50vh,底部内容区同理,避免依赖父容器高度 - 慎用
height: 50%,父级可能未定义高度,导致计算为 0 - 与
horizontal-viewport-segments规则分开维护,不要共用同一组 CSS 变量
JS 监听必须防抖且读 visualViewport.width
CSS 媒体查询只响应静态状态,但折叠过程有半开、动画帧、系统延迟上报等中间态,matchMedia 会频繁触发 false positive。直接监听 window.onresize 更糟——Pixel Fold 上常只触发 1 次。
正确做法:
- 用
const mq = window.matchMedia('(horizontal-viewport-segments: 2)'),不是 resize - 回调里读
visualViewport.width,不是window.innerWidth—— 后者在折叠动画中常滞留旧值 - 必须加至少 300ms 防抖,否则 UI 会疯狂重排;建议用
requestAnimationFrame批量更新类名 - 脚本需在加载时立即执行,不能等
DOMContentLoaded,折叠状态可能已在 DOM 构建前确定 - iframe 内无法访问
visualViewport,确保逻辑运行在顶层上下文
@supports 降级不是可选项,是上线前提
不加 @supports,Safari、Firefox 和 Chrome 118- 就直接跳过整块 @media,你的双栏样式等于不存在。这不是“优雅降级”,是“有没有样式”的分水岭。
实操要点:
- 把整个媒体查询块包进
@supports (horizontal-viewport-segments: 2),别只包选择器 - 默认样式必须是单栏(移动优先),只在
@supports内激活双栏逻辑 - 避免同时声明
horizontal-viewport-segments和vertical-viewport-segments规则覆盖同一元素——CSS 变量如--fold-state会被后声明的覆盖,统一在:root设更安全 - 真机调试时,Chrome DevTools 的 Rendering 面板可手动模拟
horizontal-viewport-segments: 2,但 Safari 无此功能,得靠真机验证
真正麻烦的不是语法写对了没,而是 Chrome 刚报告 horizontal-viewport-segments: 2 的那一刻,Safari 里还卡在 1——这种跨浏览器状态不同步,没法靠一套 JS 逻辑兜底,只能靠降级样式守住底线。


















