viewport meta 标签必须正确写在 head 中,且内容为 width=device-width, initial-scale=1;css 应采用流体结构、相对单位和弹性布局,避免固定像素值破坏响应式效果。

viewport meta 标签漏写或写错,页面直接不响应
没加 <meta name="viewport" content="width=device-width, initial-scale=1">,或者写了但放在 里、拼错单词(比如写成 viewprot),iOS Safari 和安卓 Chrome 都会忽略响应式行为,强制按桌面宽度渲染。这个标签必须放在 中,且是第一个 <meta>(至少在所有 CSS 加载前生效)。
- 常见错误:用
width=320或user-scalable=no锁死缩放——这会让可访问性崩溃,也违反 WCAG - 必须写
width=device-width,不能只写initial-scale=1;后者在某些 Android WebView 下无效 - 如果项目要支持横屏 iPad,
device-width是动态值,无需额外适配;但别用max-device-width做媒体查询依据,它已被现代浏览器弃用
CSS 中用 px 写死宽度,媒体查询就形同虚设
响应式不是靠一堆 @media 堆出来的,而是靠流体结构打底。如果容器写 width: 320px,哪怕加了 @media (max-width: 480px),它也不会变窄——因为固定像素值优先级高于媒体查询里的声明(除非用 !important,那更糟)。
- 主容器优先用
max-width+width: 100%,而不是width: 1200px - 文字大小别全用
px,改用rem或em,配合根字体缩放(html { font-size: clamp(16px, 4vw, 20px); }) - 图片记得加
max-width: 100%; height: auto;,否则溢出容器时不会自动缩放
Flexbox / Grid 布局中 flex-basis 或 grid-template-columns 写死 px,一换屏幕就崩
很多人以为用了 Flexbox 就算响应式了,结果在小屏上发现卡片堆成一列后还撑满整行、间隙过大、文字换行异常——问题常出在 flex-basis 设了 300px,或 grid-template-columns: 300px 300px。这些值不会随视口变化,等效于固定布局。
-
flex-basis推荐用0+flex-grow控制占比,或直接用flex: 1 - Grid 列推荐用
fr单位(如grid-template-columns: 1fr 2fr)或minmax(300px, 1fr),避免纯 px - 慎用
flex-wrap: nowrap,小屏下内容溢出时不会折行,而overflow: hidden只是掩盖问题
伪响应式:用 JS 监听 window.resize 改 class,性能差还漏事件
有人写 window.addEventListener('resize', () => { document.body.className = getDeviceClass(); }),看似能切换“mobile”/“desktop”类名,但 resize 事件高频触发(尤其拖拽窗口时),容易卡顿;更关键的是,移动端旋转屏幕、横竖屏切换、系统字体放大时,这个监听可能错过真实尺寸变化,导致样式错乱。
立即学习“前端免费学习笔记(深入)”;
- 纯 CSS 方案永远优于 JS 判断设备尺寸——用
@media (hover: hover) and (pointer: fine)区分鼠标/触控,比navigator.userAgent可靠得多 - 如果真需 JS 响应尺寸,用
matchMedia()(如const mql = window.matchMedia('(max-width: 768px)');),它支持监听且只在断点真正跨越时触发 - 不要在 resize 里直接操作 style,优先切 class,让 CSS 引擎批量重排
最常被忽略的其实是字体和行高的响应性——font-size 变了,line-height 没跟上,小屏上文字挤在一起,用户得手动缩放才能看清。这不是布局问题,是阅读体验的硬伤。











