viewport标签必须写全为<meta name="viewport" content="width=device-width, initial-scale=1.0">并置于<head>顶部,否则iOS Safari按980px渲染导致错位模糊;根字体应内联calc()设置,多列需媒体查询重置为单列,Flex/Grid不可混用且老iOS对min-width有兼容问题。

viewport 标签没写对,页面就永远缩在左上角、文字小得看不清——这不是兼容性问题,是渲染开关根本没打开。
必须写全 viewport meta 标签
只写 <meta name="viewport" content="width=device-width"> 是无效的。iOS Safari 会按 980px 宽度先渲染,再缩放,导致 touch 事件错位、字体模糊、布局闪动。
- 正确写法:
<meta name="viewport" content="width=device-width, initial-scale=1.0"> -
width=device-width必须拼写准确,device_width或deviceWidth都不生效 - 该标签必须放在
<head>最顶部,早于任何 CSS/JS,否则 iOS 可能已按桌面宽度开始解析 - 除非是 Kiosk 场景,否则别加
maximum-scale=1.0和user-scalable=no,否则违反可访问性要求
根字体用 calc() 内联设置,别用 JS
用 document.documentElement.style.fontSize 在 DOMContentLoaded 里设 rem 基准,会导致闪屏:浏览器先按默认 16px 渲染,再重绘变大。
- 可靠做法:在
<head>顶部加内联<style>,用calc()直接算死:html { font-size: calc(100vw / 375 * 16px); }(以 375px 设计稿为基准) - Safari 旧版(iOS 12 及更早)不支持
calc(100vw / 375 * 1rem)这类混单位写法,必须统一用px - 别依赖
window.innerWidth动态读宽——横竖屏切换或双击放大后,值可能滞后或不准
多列内容用 column-width,但手机必须切回单列
column-count 和 column-width 只适合正文、条款、说明文档这类流式内容,不是通用布局方案。
立即学习“前端免费学习笔记(深入)”;
- 推荐组合:
column-width: 16rem; column-gap: 1.5rem; column-rule: 1px solid #eee; - 必须加
break-inside: avoid到h2、p、img等子元素上,防标题/图片被劈成两半 - 移动端务必用媒体查询重置:
@media (max-width: 768px) { .content { column-count: 1; column-gap: 0; } } - 忘了重置
column-gap会导致小屏下留大片空白;在<body>上全局设多列,会让导航、页脚也被分栏
Flex/Grid 别混用,且老 iOS 对 min-width 有坑
在 iOS 12 及更早系统中,flex: 1 容器里的子元素设了 min-width: 200px,会被强行压缩到 0 宽——这不是 bug,是老 flex 算法忽略 min-width。
- 绕过方式:给该子元素加
flex-shrink: 0,强制不收缩 - 或改用
width: max-content; flex: 0 0 auto,比min-width更受老 iOS 尊重 - Flex 适合一维排列(如导航栏),Grid 适合二维区域(如后台仪表盘),同一容器里混用会导致 Android 4.4 WebView 等环境行为不可控
- 别在
display: flex容器里再套display: grid子元素做主布局——语义混乱,调试困难
真正难的不是写对那几行 CSS,而是判断「这段内容是否真的适合多列」或「这个容器到底该用 flex 还是 grid」。很多所谓“适配失败”,其实是布局模型选错了,而不是代码写漏了。



















