必须配对使用@media (orientation: portrait)和@media (orientation: landscape),否则未声明方向会回退初始值导致冲突;需删掉margin、改用gap,并同步调整颜色、可访问性等要素。

直接用 @media (orientation: portrait) 和 @media (orientation: landscape) 配合 flex 或 grid 布局,就能解决 90% 的旋转错乱问题;但必须配对写、删掉 margin、用 gap 替代间距控制,否则布局会“看起来像切换了,实则错位”。
为什么只写 @media (orientation: landscape) 不生效?
因为 orientation 是二元状态,不是单向开关。浏览器不会默认给“非横屏”应用样式——你得显式定义竖屏规则,否则竖屏下会回退到未声明的初始值(比如 flex-direction: row),和横屏的 column 冲突。
- 必须成对出现:
@media (orientation: portrait) { ... }和@media (orientation: landscape) { ... } - 不能只靠一个断点“覆盖”,另一个方向没声明 = 没约束
- 尤其注意:iPad 横屏时
screen.width > screen.height,但 orientation 仍可能返回portrait-primary(取决于系统设置),所以不能混用min-width和orientation
flex-direction 切换后子元素间距错乱?
根本原因是 margin 是绝对方向的:你写了 margin-bottom: 12px,竖排时它在下方起作用;横排时主轴变成水平,margin-bottom 变成“往下压”,反而把元素挤出容器。
- 全部删掉子项上的
margin,尤其是margin-bottom/margin-right - 统一改用
gap:它会随flex-direction自动适配主轴方向 - 如果内容顶部对不齐,加
align-items: flex-start,别依赖align-items: stretch(它会让所有子项拉高,破坏文字基线)
为什么 iOS Safari 里布局偶尔闪一下或不触发?
旧版 Safari(≤12.1)不支持 matchMedia().addEventListener('change', ...),但现代版(≥12.2)已全面支持;不过 CSS 媒体查询本身无兼容问题——闪动或不触发,大概率是 JS 干预了 DOM 或用了废弃 API。
- 别用
window.addEventListener('orientationchange', ...):iOS Safari 早已不触发该事件 - 别读
window.orientation:Chrome 95+、Safari 16.4+ 已废弃,值恒为 0 - 纯样式调整优先走 CSS,JS 只用于需要 DOM 操作的场景(如动态加载组件)
- 若必须用 JS 监听,用
matchMedia('(orientation: landscape)')+addEventListener('change', ...),首次调用mql.matches就能拿到当前状态
竖屏下按钮文字看不清,算布局问题吗?
不算布局崩坏,但它是用户第一眼失败点——媒体查询改了结构,却漏了颜色对比度校验。
-
color: #999在白色背景 + 强光直射下对比度不足,不满足 WCAG AA(最低 4.5:1) - 每个
@media块内都要检查所有状态色:active、pending、done - 别只调
font-size或padding,忽略color和background-color的组合是否达标
真正麻烦的不是怎么写 media query,而是所有方向切换都得同步验证:flex/gap/颜色/可访问性标签/焦点顺序——少一环,用户转屏那一刻就卡住。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











