折叠屏响应式需确保viewport标签正确置于head顶部、用screen-spanning媒体查询识别铰链状态、动态重算rem基准并避免依赖window.innerwidth。

折叠屏响应式模板不是加个 viewport 标签就完事——它必须在展开/折叠瞬间不抖动、不裁切、不卡顿,否则用户一合盖就白屏或错位。
viewport meta 必须写对且放最顶上
很多页面在 Z Fold 上一展开就文字糊成一团,根本原因是 <meta name="viewport"> 写错位置或参数缺失:
-
width=device-width拼成device_width或width=deviceWidth→ 整个媒体查询链失效 - 漏掉
initial-scale=1.0→ iOS Safari 首次渲染按 980px 宽度兜底,再重排闪屏 - 加了
maximum-scale=1.0或user-scalable=no→ 折叠态下无法双指放大查看细节,WCAG 可访问性直接不通过 - 标签被塞在
<link rel="stylesheet">后面 → 渲染引擎已按错误宽度解析 DOM,补救无效
正确写法只有一行,且必须出现在 最顶部:
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
viewport-fit=cover 是折叠屏关键:它让内容真正撑满折痕区和刘海下方的安全区域,否则展开后左右边缘会被系统 UI 裁掉。
别用 window.innerWidth 判断折叠状态
折叠动画过程中 window.innerWidth 会跳变(比如从 720px → 1440px → 720px),单靠它做布局切换,按钮会点不中、侧边栏会闪现两次。
- 优先用
screen.width和screen.height算宽高比:aspect-ratio: 21/9基本只出现在展开态超宽屏 - 监听
screen.orientationchange事件二次校验,但注意字符串值不可靠(landscape-primaryvslandscape-secondary因厂商而异) - Android Chrome 115+ 中
screen.width可能卡在折叠前的值,此时改用visualViewport.width辅助判断
真机测试时发现:Pixel Fold 在半折叠状态(铰链未完全闭合)下,window.innerWidth 和 screen.width 差值常超 100px,必须用差值阈值过滤抖动。
用 screen-spanning 媒体查询识别铰链物理状态
固定断点如 @media (min-width: 1024px) 在折叠屏上毫无意义——Z Fold 展开是 1440px,iPad Pro 横屏也是 1024px,但两者交互逻辑完全不同。
- Chromium 119+ 支持
@media (screen-spanning: single-fold-horizontal),这是唯一能真实反映“铰链是否水平展开”的 CSS 特性 -
single-fold-horizontal匹配 Z Fold 展开、Pixel Fold 横置等场景;single-fold-vertical对应 Flip 合盖状态,此时应回退到单栏流式布局 - 桌面浏览器或旧版 Chrome 中该查询返回
not all,必须配合 JS 回退:window.matchMedia('(screen-spanning: single-fold-horizontal)')的matches属性要手动监听change
注意:不能在 change 回调里直接操作大量 DOM。用 requestAnimationFrame 批量更新 class,否则折叠动画期间会卡顿。
rem/vw 基准必须动态重算,不能一次设死
折叠屏展开后视口宽度可能达 1800px,若 rem 基准仍按 375px 设计稿比例硬算,字体和间距会突然放大两倍以上。
- JS 中不要写死
document.documentElement.style.fontSize = '16px',而是每次触发resize或orientationchange后重算 - 计算逻辑建议用
document.documentElement.clientWidth / 375 * 16,而非依赖window.innerWidth(键盘弹出时它不变,但实际可用宽度被压缩) - 某些安卓 WebView 不触发
resize,得用window.matchMedia('(min-width: 0px)')监听变化作为 fallback - PostCSS 的
vw转换要设为设计稿基准(如 375),但最终效果仍取决于viewport是否生效——如果viewport-fit=cover没起作用,100vw就只是“可见视口”,不是“物理全屏”
最容易被忽略的是初始化时机:CSS 加载完成前就读取 clientWidth,会因缓存返回旧值;务必等 DOMContentLoaded 后再执行 setRem(),且首次调用不能省略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











