vw/vh需配合min-font-size或媒体查询兜底,100vh在iOS/安卓存在跳变与溢出问题;媒体查询才是控制响应式行为的主力,应优先用max-width移动优先逻辑,并搭配JS监听matchMedia或visualViewport确保精准适配。

用 vw / vh 单位做基础缩放,但别全靠它
vw 和 vh 确实能让元素随视口宽高等比变化,比如 width: 50vw 表示宽度始终是屏幕宽度的一半。但它不是万能的:
- 小屏下
font-size: 4vw可能缩到 12px 难以阅读,大屏下又可能撑到 60px 失控 —— 必须配合min-font-size或媒体查询兜底 -
100vh在 iOS 地址栏收起/弹出时会跳变,安卓某些 WebView 里还会超出可视区域 - 它只响应“视口尺寸”,不感知设备类型、DPR、软键盘是否弹出 —— 比如底部按钮被键盘顶起,
bottom: 0+vh也救不了
媒体查询才是控制“消失/出现/换位”的主力
真正让元素根据屏幕尺寸动态改变行为(比如隐藏侧边栏、切换导航为汉堡菜单、调整列数),得靠 @media。关键不是写多少断点,而是写对逻辑:
- 优先用
max-width(如@media (max-width: 768px)),而不是min-width—— 移动优先更可控,避免桌面样式覆盖移动端 - 给要控制的元素加明确 class,比如
.main-nav,别用nav:first-child这类脆弱选择器,JS 动态插入内容后容易失效 - 如果元素内有定时器或 WebSocket,
display: none不会自动销毁 —— 必须在 JS 中监听matchMedia状态变化,手动清理资源 - 想加淡入淡出?不能直接
transition: display—— 浏览器不支持,得先用opacity+max-height动画,再用 JS 切换display
Flex/Grid 是“自动适应”的底层支撑,不是替代方案
display: flex 或 display: grid 本身不响应屏幕尺寸,但它们让媒体查询生效后布局更干净:
- 用
flex-wrap: wrap+flex-basis,比浮动 + 百分比宽度更可靠,不用手动清浮动 -
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))这种写法,比一堆@media更简洁,但要注意旧浏览器兼容性(IE 不支持) - Grid 的
fr单位依赖容器尺寸,如果父容器高度没撑开(比如只写了height: auto),1fr就无效 —— 得配min-height: 100vh或display: grid在根容器上
JS 监听 resize 或 matchMedia 是补漏关键
CSS 媒体查询无法触发 JS 逻辑(比如懒加载、重绘图表、销毁插件),这时候必须主动监听:
立即学习“前端免费学习笔记(深入)”;
- 别只绑
window.onresize—— 页面加载时不会触发,首次渲染就错位;得在 DOM ready 后立即执行一次判断逻辑 - 用
window.matchMedia("(max-width: 768px)").matches比window.innerWidth更精准,它直接读取 CSS 媒体查询状态,不受缩放、滚动条宽度干扰 - 监听
visualViewport(Chrome/Edge/Safari 支持)比window.innerHeight更准,尤其在软键盘弹出、地址栏收起时 —— 它反映的是用户真正看到的“视觉视口” - 如果用
position: fixed元素在折叠屏或横竖屏切换后错位,大概率是它锚定到了 layout viewport 而不是 visual viewport,这时候光靠 CSS 修不好,得 JS 重算位置


















