本文约 3,613 字,预计阅读 10 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:电脑上看挺好,手机上全乱了
开发者用电脑调试,一切正常;客户拿手机一打开:整页被压缩成缩小版、文字小得看不清、轮播图只露出一半、点汉堡菜单没反应、长串英文或 URL 把容器撑到屏幕外,页面可以左右横向拖动。
这类问题排查起来费劲,是因为”移动端显示”其实是三层问题叠加:视口层(有没有 viewport meta)、布局层(CSS 是否响应式、是否有溢出)、交互层(JS 是否加载、点击区域是否可用)。三层逐层排除,比对着 CSS 乱改高效得多。
原理分析:三层各自的表现与成因
视口层:<meta name="viewport" content="width=device-width, initial-scale=1"> 告诉移动浏览器按设备宽度渲染。缺了它,移动浏览器会假定页面宽度约 980px 再整体缩放,于是出现”整页缩小、字很小、可双指放大”的典型症状。这个标签必须在 header.php 的 <head> 里,且由 wp_head() 之前或之后输出都可以,但不能被缓存插件的 HTML 压缩移除。
布局层:常见症状是横向溢出。成因包括:固定宽度(如 width: 1200px)、图片未限制 max-width: 100%、长英文单词或 URL 不换行、表格列数过多、position: absolute 元素超出容器。对应手段是媒体查询、max-width、以及 overflow-wrap: break-word 与表格容器 overflow-x: auto。
交互层:移动端菜单无响应通常是脚本未加载或报错;点击区域太小则是 CSS 问题(导航项高度不足 44px 时触屏体验很差)。另外 wp_is_mobile() 只能区分设备类型,不能替代 CSS 断点,且它与页面缓存天然冲突——同一份 HTML 缓存会同时服务手机和桌面。
| 症状 | 所属层 | 首要检查 |
|---|---|---|
| 整页缩小、字极小 | 视口 | viewport meta 是否存在 |
| 页面可左右滑动 | 布局 | 固定宽度、长单词、绝对定位元素 |
| 表格/代码块出界 | 布局 | 容器 overflow-x |
| 汉堡菜单没反应 | 交互 | 控制台报错、脚本是否排队 |
| 手机显示桌面版菜单 | 交互/缓存 | 缓存是否为桌面 HTML |
保姆级实操
- 先查 viewport:在手机上或 DevTools 设备模拟里查看页面源码的
<head>,确认有 viewport 声明。 - 用 DevTools 定位溢出元素:在控制台逐段隐藏区块,找出撑破容器的那个元素;Chrome 的设备工具栏可以直接看视口宽度下的实际渲染。
- 修布局:给图片设
max-width: 100%与height: auto;长文本加overflow-wrap: break-word;表格外层包一个可横向滚动的容器。 - 核对断点:确认主题的媒体查询断点覆盖了 782px(WordPress 后台断点)与常见手机宽度,统一用
max-width或统一用min-width,混用最容易出问题。 - 查交互脚本:在移动设备上打开控制台(或用
vconsole之类的调试面板),看切换脚本是否报错、是否依赖未加载的 jQuery。 - 检查点击区域:导航链接的
padding撑到至少 44px 高,避免手指点不中。 - 真机验证:模拟器只能看渲染,触摸与滚动惯性必须真机测;同时关掉缓存或用无痕窗口验证。
<!-- header.php 的 <head> 中必须有这一行 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 若主题已声明,勿重复添加;也不要加 user-scalable=no,会损害可访问性 -->
/* 1) 基础防溢出 */
img,
video,
iframe,
embed {
max-width: 100%;
height: auto;
}
/* 2) 长英文、URL 不撑破容器 */
.entry-content,
.widget,
.comment-content {
overflow-wrap: break-word;
word-wrap: break-word;
}
/* 3) 宽表格改为容器内横向滚动 */
.table-wrap {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.table-wrap table {
min-width: 640px;
}
/* 4) 移动端断点统一用 max-width */
@media ( max-width: 782px ) {
.site-header .container {
width: 100%;
padding: 0 16px;
}
/* 触摸目标至少 44px */
.primary-menu a {
display: block;
padding: 12px 16px;
min-height: 44px;
}
.hero-title {
font-size: 1.5rem;
line-height: 1.4;
}
}
// 5) 用 matchMedia 判断是否移动端,仅用于非渲染类逻辑
// 不要用 wp_is_mobile() 来输出不同 HTML,那样会与页面缓存冲突
const isNarrow = window.matchMedia( '(max-width: 782px)' );
function syncMenuState( event ) {
const nav = document.getElementById( 'site-navigation' );
const btn = document.querySelector( '.menu-toggle' );
if ( ! nav || ! btn ) {
return;
}
if ( ! event.matches ) {
nav.classList.remove( 'is-open' );
btn.setAttribute( 'aria-expanded', 'false' );
}
}
isNarrow.addEventListener( 'change', syncMenuState );
syncMenuState( isNarrow );
常见踩坑
- 主题
header.php缺 viewport,却去改一堆 CSS,越改越乱。 - 用了
user-scalable=no或maximum-scale=1,损害可访问性,也会被部分审查工具扣分。 - 用
wp_is_mobile()输出两套 HTML,配合页面缓存后桌面用户看到手机版。 - 移动端菜单脚本依赖 jQuery,但 jQuery 被延迟加载或合并出错,报
$ is not defined。 - 案例:某站手机上一直显示桌面版导航,清了插件缓存、换了 CDN 都没用。最后发现主题用
wp_is_mobile()在header.php里输出了不同的菜单结构,而整站开启了页面缓存,第一份缓存是桌面访问生成的。改成纯 CSS + JS 控制、HTML 结构统一之后,问题彻底消失。 - 表格直接放进正文,窄屏下把整个页面撑宽,出现横向滚动条。
- 只在 Chrome 模拟器里测,没在真机上验证触摸与滚动,上线后才发现点击不灵敏。
总结
移动端排查按”视口 → 布局 → 交互”三层走,先确认 viewport 存在,再用 DevTools 找出溢出元素,最后验证脚本与点击区域。判断标准是”手机上页面不能横向拖动、菜单能点开、表格不撑破容器”。行动清单:① 确认 viewport 声明;② 图片加 max-width;③ 长文本加 overflow-wrap;④ 表格包滚动容器;⑤ 不要用 wp_is_mobile() 分支输出 HTML;⑥ 真机验证。延伸阅读 lumen-mimangfei 主题菜单配置、主题自定义 JS 添加 与 lumen-mimangfei 主题缓存兼容。
