screen-spanning 媒体查询根本不存在且被废弃,应改用 horizontal-viewport-segments 和 vertical-viewport-segments(Chrome/Edge 119+ 支持),二者值为 2 表示双屏渲染,需配合 @supports 使用并以 visualViewport.width 校验,Grid 布局更适配折叠态切换。

别用 screen-spanning,它根本不存在,浏览器会直接忽略;真正能上线的是 horizontal-viewport-segments 和 vertical-viewport-segments,只在 Chrome/Edge 119+ 稳定支持,Safari 和 Firefox 完全不认。
为什么 screen-spanning 媒体查询完全不可用
这个媒体特征压根没进标准,也没被任何浏览器正式实现。你写 @media (screen-spanning: single-fold-vertical),DevTools 里看不到匹配状态,控制台无报错,样式就是不生效——不是你语法错,是它根本没被解析。Chromium 内部早把它标记为“废弃实验性特性”,连 MDN 都已移除文档条目。
-
screen-spanning描述的是“当前元素是否跨铰链渲染”,不是“设备是否展开”,语义和使用场景都错位 - 即使强行启用(比如通过 chrome://flags),在华为 Mate X3、三星 Z Fold 6 等真实设备上也返回
not all或直接静默失败 - 所有基于它的 polyfill 或 JS 检测库(如
fold-detectv2.x)在 2026 年已全部弃用,维护者明确建议切换至viewport-segments
怎么用 horizontal-viewport-segments 和 vertical-viewport-segments
这两个才是当前唯一反映物理双视口分割的可靠信号。值为 2 表示系统正在以双屏模式渲染,1 表示单屏(折叠态或普通手机)。
-
horizontal-viewport-segments: 2→ 竖折设备(如 Galaxy Z Fold)展开后,左右两个独立 viewport,document.body.clientWidth返回单侧宽度(约 375–420px) -
vertical-viewport-segments: 2→ 横折设备(如 Mate X3)展开后,上下两个独立 viewport,此时用height相关布局才合理 - 必须搭配
@supports (horizontal-viewport-segments: 2)使用,避免旧浏览器解析失败导致整条规则失效 - 不要混用
min-width:比如@media (min-width: 768px) and (horizontal-viewport-segments: 2)是错的——前者匹配视口总宽,后者只在单侧渲染时为真,逻辑冲突
JS 监听必须加防抖且校验 visualViewport
CSS 媒体查询只能静态响应,但折叠过程有中间态(半开、动画帧、系统延迟上报),仅靠 CSS 会漏掉关键过渡帧。
立即学习“前端免费学习笔记(深入)”;
- 用
matchMedia('(horizontal-viewport-segments: 2)')创建监听器,而不是window.onresize - handler 必须加 100ms 防抖:Z Fold 展开瞬间可能触发 4–6 次 change 事件,不防抖会导致布局反复重绘
- 校验值优先取
visualViewport?.width,不是window.innerWidth——后者在折叠动画中常滞后 1–2 帧,导致判断偏差 - 降级 fallback 要写在 JS 里:
if (!mediaQueryList.matches && screen.width > 700) { /* 用 width/height 组合兜底 */ }
Grid 布局比 Flexbox 更适配折叠态切换
Flexbox 的线性流在双视口切换时容易因主轴方向突变导致元素错位(比如右侧内容被挤到顶部),而 Grid 可显式定义区域关系,不依赖 DOM 顺序。
- 推荐写法:
.layout { display: grid; grid-template-areas: 'sidebar main'; },再用媒体查询更新grid-template-areas: 'sidebar' 'main' - 避免对跨铰链元素强求视觉连续:给导航栏加
@media (spanning: single-fold-horizontal)会让position: sticky失效,且合成层压力陡增,滚动卡顿是规范明确允许的行为 - 侧边栏宽度别硬编码,用 CSS 变量透传:
:root { --sidebar-width: 320px; },再在@media (horizontal-viewport-segments: 2)里设为600px,配合flex-basis: var(--sidebar-width)实现平滑过渡
真正麻烦的不是写对那几行媒体查询,而是设备厂商对 viewport-segments 的启用策略不统一——华为部分机型需开启“开发者选项 > 启用跨屏 Web 渲染”,三星则默认关闭,这些细节不会出现在 DevTools 的媒体查询面板里,只能靠真机 + matchMedia 日志确认。


















