分页按钮点击区域必须≥44×44px,禁用态需加pointer-events:none,页码须动态裁剪(如前后各2个),并提供即时:active反馈。

分页按钮点击区域必须 ≥ 44×44px
移动端手指点击容易误触,系统级人机指南(iOS/Android)明确要求最小可触控区域不小于 44×44 像素。ThinkPHP 默认生成的 <a></a> 标签文字链接,若未加样式约束,实际点击热区往往只有字体高度 + 内边距,远低于标准。
实操建议:
- 给分页容器(如
<div class="pagination">)设置 <code>font-size: 16px,再用padding: 12px 16px补足尺寸,确保单个页码按钮物理尺寸达标 - 避免仅靠
line-height撑高热区——它不增加可点击范围,只影响文字垂直居中 - 用
min-width: 44px; min-height: 44px;强制兜底,配合display: inline-flex; align-items: center; justify-content: center;居中内容 - 在真机调试时打开 Chrome DevTools 的「Toggle device toolbar」,勾选「Show rasters」观察实际渲染热区
- 继承
Paginator后,在getLinks()中限制当前页前后最多各显示 2 个页码:比如总页数 20、当前页是 12,就只渲染「… 10 11 12 13 14 …」 - 用
$this->getUrlRange($start, $end)生成区间页码,而非遍历1到$this->lastPage - 始终保留首页
url(1)和尾页url($this->lastPage())按钮,但用图标(如«/»)代替文字,节省宽度 - 当总页数 ≤ 5 时,直接全量显示,不加省略号——此时裁剪反而增加认知负担
- 在禁用按钮的 HTML 中,显式添加
style="pointer-events: none;",或统一用 CSS 类:.disabled { pointer-events: none; } - 避免用
<a href="javascript:void(0)"></a>模拟禁用链接——它仍会触发 focus/blur,且语义错误 - 禁用态文案(如“上一页”)建议保留,但视觉上降低对比度(如
color: #999),兼顾可访问性(屏幕阅读器仍可读) - 对
home()和last()方法也做同样处理,不要漏掉首页/尾页的禁用逻辑 - 给所有分页链接加
transition: background-color 0.1s;,再设<a>:active { background-color: #e6f7ff; }</a> - 慎用
opacity变化作反馈——透明度变化在深色背景下可能不可见,且部分安卓 WebView 渲染异常 - 如果用了图标(如 Font Awesome),确保
:active下图标颜色同步变化,避免文字变色而图标不动的割裂感 - 不要依赖 JavaScript 绑定
touchstart来加类——原生:active更可靠、无延迟
页码数量要动态裁剪,别硬塞 10 个数字
小屏上显示「1 2 3 … 7 8 9 10 11」这种长串页码,不仅挤占空间,还会触发横向滚动或文字折行,破坏浏览流。ThinkPHP 的 render() 默认不控制显示个数,全靠自定义驱动类逻辑裁剪。
实操建议:
禁用状态要用 pointer-events: none 而非仅改颜色
ThinkPHP 分页驱动里常见写法是:当前页为 1 时,prev() 返回一个带 class="disabled" 的 <span></span>。但仅靠 CSS 灰色文字 + cursor: not-allowed 无法阻止用户误点,尤其在快速滑动后指尖悬停位置不准时。
实操建议:
触摸反馈必须有,哪怕只是背景色微变
没有即时视觉反馈的按钮,会让用户怀疑是否点中了。移动端点击延迟短,需在 :active 状态下立刻响应,不能等 hover 或 JS 事件。
实操建议:
真正难的不是写出能用的分页,而是让手指在 320px 宽的屏幕上准确点中那个「3」,且点完立刻知道生效了。所有样式和逻辑,都该围绕这个前提校验一遍——尤其是禁用态是否真的点不动、页码是否在横屏时依然可读、点击反馈是否在低端安卓机上不卡顿。











