折叠屏适配应优先使用 horizontal-viewport-segments 和 vertical-viewport-segments 媒体特性判断物理分屏状态,chrome/edge 119+ 支持,safari/firefox 尚未实现;需配合 @supports 降级,避免依赖 screen-spanning 或宽高媒体查询,并注意 js 监听防抖及 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表示设备处于竖折展开态(如 Z Fold),浏览器渲染两个并列水平视口,document.body.clientWidth返回单侧宽度(约 375–420px),不是总宽 -
vertical-viewport-segments: 2对应横折/翻盖式设备(如 Galaxy Z Flip 展开、华为 Pocket 系列),此时高度被物理分割 - 必须配合
@supports使用,避免旧浏览器解析失败:@supports (horizontal-viewport-segments: 2) - 不要同时写两个规则覆盖同一元素——
:root中变量会被后声明的覆盖,建议统一用--fold-state: horizontal或--fold-state: vertical
别信 screen-spanning,它在 Safari/Firefox 里根本不存在
screen-spanning 媒体查询(如 (screen-spanning: single-fold-vertical))只在 Chrome 119+/Edge 97+ 有限支持,且依赖系统跨屏渲染开关、无 iframe 干扰、非缩放状态等苛刻条件,真机上极易返回 not all 导致样式完全失效。
- 它描述的是“当前元素是否跨铰链渲染”,不是“设备是否展开”——即使匹配成功,
position: sticky也会失效,transform可能被截断,这是规范明确标注的限制 - 桌面模拟器或旧版 Android WebView 中该特性不可靠,华为 HarmonyOS Webview 默认屏蔽以保性能
- 如果非要尝试,必须降级:先查
screen-spanning,再 fallback 到@media (width > 700px) and (min-aspect-ratio: 1/2)组合判断
JS 监听必须加防抖,且读 visualViewport.width 而非 window.innerWidth
CSS 媒体查询只管静态状态,折叠过程中的半开、动画帧、系统延迟上报会导致 matchMedia 频繁触发 false positive,不加处理 UI 会疯狂抖动。
- 监听方式:
const mq = window.matchMedia('(horizontal-viewport-segments: 2)'); mq.addEventListener('change', debounce(handleFoldChange, 100)); - 回调中取尺寸要用
visualViewport.width—— 它反映真实可视区域,window.innerWidth在折叠动画中常滞后 2–3 帧 - 降级逻辑写在 JS 里:
if (!mq.matches && screen.width > 700) { /* 启用双栏 */ },不能只靠 CSS - 首次加载时也要手动调用一次
handleFoldChange,避免 onload 时机错过初始状态
Flex/Grid 布局怎么写才不卡在中间态
折叠屏切换不是“变大/变小”,而是视口结构突变,硬编码 display: none 或 width: 0 会破坏屏幕阅读器焦点流、键盘导航和 CSS 动画过渡。
- 侧边栏用
flex-basis: var(--sidebar-span); min-width: 0; overflow: hidden;替代display: none,确保可访问性 - 主内容区加
flex: 1 1 0; flex-wrap: nowrap;,防止 Flexbox 在双视口下因顺序线性导致模块错位 - Grid 布局更稳:
grid-template-columns: 1fr 300px在horizontal-viewport-segments: 2下天然铺满两侧,无需计算 hinge 缝隙 - 别对 CSS 变量做
calc(var(--sidebar-span) - 80px)运算——部分浏览器在媒体查询切换时无法重计算该表达式
最易被忽略的一点:所有媒体查询都得配降级。没匹配到任何分段时,:root 中必须显式设 --fold-state: single,否则 var(--fold-state) 是 unset,后续所有 calc() 或 if() 条件都会退化为空字符串,布局直接崩掉。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











