本文约 4,740 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:手机上「点十次错八次」的主题不是个例
朋友的公司站换了新主题后,销售反馈最多的问题是:手机上看产品目录,手指点分类标签经常点空,或者误触到旁边的「加入询价」;老年人客户打开文章页,正文字号只有 13px,双击放大后排版错位。这类问题在桌面浏览器里完全复现不出来,本地用鼠标点也一切正常,于是被当成「用户手抖」搁置了几个月,直到移动端跳出率明显升高才被重视。
根子不在浏览器,而在主题本身:大多数商业主题把视觉重心放在桌面端截图上,移动端只做到「不横向滚动」就算完成。判断标准其实非常明确——可点击元素的实际触控面积、正文字号与行高的下限、以及缩放后布局是否塌掉。这三项都有公开可查的量化标准,不需要凭感觉调。
原理分析:三条标准各自管什么
行业里被引用最多的三组数字,来源与适用范围不同,混用会调错方向。
| 标准 | 数值 | 出处 | 适用点 |
|---|---|---|---|
| 最小目标尺寸 | 24×24 CSS px | WCAG 2.2 SC 2.5.8(AA) | 无障碍合规底线 |
| 增强目标尺寸 | 44×44 CSS px | WCAG 2.2 SC 2.5.5(AAA) | 推荐做到 |
| 触控控件 | 44×44 pt | Apple iOS 人机界面指南 | iOS 原生与 Web |
| 可点击元素 | 48×48 dp | Material Design 3 | Android 侧建议 |
| 文本缩放 | 放大 200% 不丢内容 | WCAG 2.2 SC 1.4.4 | 字号与容器 |
注意 24px 与 44px 的关系:24px 是「不违规」,44px 才是「好用」。二者之间还有一条豁免规则——如果目标间距足够(24px 直径的圆不与其他目标圆相交),小控件也可以放行。所以密集的标签云、分页数字这类无法做到 44px 的元素,靠拉开间距来补救是合规且现实的。
字号方面,多数主题的问题是「用了 rem 但基准被外层容器改小」。WordPress 块主题的外观由 theme.json 统一声明,只要在该文件里改字号预设,编辑器和前端会同步生效;经典主题则是 style.css 里硬编码 px。两者的修改入口完全不同,先判断自己是哪一类再动手。
保姆级实操
步骤 1:确认主题类型
块主题根目录有 theme.json,经典主题没有。也可以看后台「外观 → 站点编辑器」是否存在。这一步决定后面改哪里。
步骤 2:给交互元素补齐热区(经典主题,加到子主题 style.css)
/* 小屏统一最小触控尺寸,不改变视觉大小 */
@media (max-width: 782px) {
.site-header .menu-toggle,
.nav-links a,
.wp-block-button__link,
.woocommerce ul.products li a.button,
input[type="submit"],
.pagination .page-numbers {
position: relative;
min-height: 44px;
min-width: 44px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 10px 14px;
}
/* 用伪元素把热区撑开到 44px,视觉尺寸不变 */
.nav-links a::before {
content: "";
position: absolute;
inset: -10px -6px;
}
/* 去掉点击时的灰色闪烁,改用自定义反馈 */
.nav-links a {
-webkit-tap-highlight-color: transparent;
}
.nav-links a:active { opacity: .6; }
}
782px 不是随手写的,它是 WordPress 后台 wp-admin 断点(wp_is_mobile() 与 admin-bar 也用这个宽度)附近的值,与主题移动端表现对齐度最好。
步骤 3:块主题改用 theme.json 声明流体字号
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 2,
"settings": {
"typography": {
"fluid": true,
"fontSizes": [
{
"slug": "body",
"size": "1.0625rem",
"name": "正文",
"fluid": { "min": "1rem", "max": "1.125rem" }
},
{
"slug": "small",
"size": "0.9375rem",
"name": "辅助",
"fluid": { "min": "0.875rem", "max": "1rem" }
}
]
},
"spacing": {
"units": ["px", "rem", "em", "%"]
}
},
"styles": {
"typography": {
"fontSize": "var(--wp--preset--font-size--body)",
"lineHeight": "1.75"
}
}
}
fluid: true 之后,块编辑器里同名字号会在前台渲染成 clamp(),小屏不会掉到 13px 以下。行高 1.75 对中文正文比西文常用的 1.5 更合适,因为汉字没有升降部,行间过密会糊成一片。
步骤 4:给正文区域兜底,防止外层容器缩放
/* 防止主题外层用 transform: scale() 或固定 px 造成缩放失效 */
@media (max-width: 600px) {
.entry-content,
.wp-block-post-content {
font-size: max(16px, 1em);
line-height: 1.75;
word-break: normal;
overflow-wrap: anywhere;
}
.entry-content p { margin-bottom: 1.2em; }
}
max(16px, 1em) 是关键:iOS Safari 会对小于 16px 的输入框在聚焦时自动放大页面,正文若低于 16px 同样会触发,用 max() 可以从根上避免。
步骤 5:密集小控件用间距豁免
/* 分页数字无法做到 44px,改用间距满足豁免条件 */
.pagination { display: flex; gap: 24px; flex-wrap: wrap; }
.pagination .page-numbers { min-width: 24px; }
步骤 6:验证
Chrome DevTools 设备模拟里打开「显示触控点」,配合 Ruler 类工具量热区;再用 Lighthouse 移动端的 Accessibility 分类跑一遍,其中 tap-targets 审计项会直接列出不合格元素。真实机验证别省,模拟器量的是 CSS 盒模型,真机还要考虑系统手势区。
常见踩坑
- 只改
a标签不改父级li:很多菜单的可点击区域实际由li:hover触发,改了a的尺寸但父级没撑开,热区看起来大了实际点不到。 - 用
transform: scale()放大整站:会让「200% 缩放」测试直接失效,WCAG 1.4.4 判定不通过,也会让 iOS 输入框聚焦时二次放大。 min-height加在display: inline元素上:行内元素忽略高度,必须先改成inline-flex或inline-block。- 伪元素
::before撑热区后盖住了相邻链接:两个热区重叠时后写的在上层,密集列表里会出现「点 A 跳到 B」,需要给容器加position: relative; z-index分层。 - 案例: 某外贸站给
.product-title a加了 44px 热区,同时给外层.product-card绑了整卡跳转的 JS。结果手机上点标题常常跳到详情页又立刻被整卡事件二次触发,出现「连跳两页、返回键要点两次」。排查方法是给整卡事件加e.target.closest('a')判断,命中链接就直接return。 - 改了
theme.json却没清缓存:块主题的字号预设存在wp_global_styles文章里,改文件后需要在「站点编辑器」里保存一次或清对象缓存,否则前台仍是旧值。 - 忽略表单控件:
input[type="checkbox"]、select在移动端同样受 44px 约束,Flamingo 或 Contact Form 7 生成的默认复选框往往只有 16px。
总结
判断一个主题的小屏体验是否合格,可以用三条硬指标过一遍:所有可点击元素实测热区 ≥44×44 CSS px(密集控件至少 24px 且间距 ≥24px);正文在 375px 宽度下实测字号 ≥16px、行高 ≥1.7;浏览器缩放到 200% 后没有内容被裁切或重叠。三条都有现成的自动化审计,不必靠主观感受。
落地顺序建议:先修热区(点击失败直接丢转化),再修字号(影响停留时长),最后处理缩放(合规与极端场景)。如果主题本身把字号硬编码在十几处,改三处仍压不住,就该考虑换成以 theme.json 为唯一来源的块主题,长期维护成本会低一个量级。可同时对照 WordPress主题加载的资源请求数精简 与 主题性能优化的度量方式 一起做,避免为了加 CSS 反而拖慢移动端首屏。
