必须用 display: flex 实现分页器,因其天然撑高父容器、自动水平排列、支持 gap 和 justify-content,避免 float 塌陷和 inline-block 间隙问题;需用 flex-wrap、gap、精细化圆角与边框控制、响应式显隐及可访问性状态处理。

直接用 display: flex 实现分页器,比 float、inline-block 或 grid(在简单线性布局中)更轻量、可控且语义清晰;关键不是“能不能”,而是“怎么避免首尾边框重叠、gap 失效、响应式错位”。
为什么必须用 display: flex 而不是 float 或 inline-block
浮动会让 .pagination ul 高度塌陷为 0,背景色消失、点击区域丢失、外边距失效;inline-block 则因换行符/空格产生不可控间隙,hover 时视觉跳动明显。而 display: flex 天然撑高父容器、自动水平排列、支持 gap 和 justify-content,连清除浮动的 hack 都不用写。
常见错误现象:
- 页码按钮挤成一排后溢出容器,却没触发换行
- 鼠标悬停时按钮上下轻微跳动
- 首项左圆角和末项右圆角被相邻边框“吃掉”一半
解决办法:
立即学习“前端免费学习笔记(深入)”;
- 给
.pagination ul加display: flex+flex-wrap: wrap(小屏备用) - 用
gap: 8px替代margin控制间距——它只作用于 item 之间,无首尾冗余 - 禁用
vertical-align,它在 flex 下无效,强行加只会干扰对齐
如何正确控制边框与圆角,避免“圆角打架”
统一设 border: 1px solid #ccc 看似省事,但相邻 li 的左右边框会重叠,导致视觉变粗;圆角若全加在 a 上,还会被父 li 盒模型裁剪、响应区域变窄。
正确做法是精细化剥离:
- 首项:
.pagination li:first-child a { border-left: none; border-radius: 4px 0 0 4px; } - 末项:
.pagination li:last-child a { border-right: none; border-radius: 0 4px 4px 0; } - 中间项:
.pagination li:not(:first-child):not(:last-child) a { border-radius: 0; }
注意:圆角必须加在 a 上,而非 li,否则点击区域不包含圆角部分;border-radius 值需与 border-width 匹配,否则边缘模糊。
响应式断点下如何动态隐藏页码并保留可操作性
小屏不靠 JS 动态删 DOM,而用 CSS 控制显隐——既快又无障碍。核心是让“当前页+首尾页+上下页”始终可见,中间页用 … 占位。
典型断点策略:
- ≥768px:显示完整页码(如 1–5)
- 480px–767px:仅显示
«、1、当前页、最后页、»,中间页display: none - <480px:强制
flex-wrap: wrap,配合row-gap: 4px防止换行粘连
关键细节:
- 省略号用
<span class="ellipsis">…</span>,不能用伪元素,否则屏幕阅读器无法识别 - 所有隐藏项必须用
display: none,而非visibility: hidden或opacity: 0,否则键盘焦点仍可抵达 - 移动端需加
min-width: 32px和padding匹配line-height,防止点不准
active 和 disabled 状态必须同时满足视觉+交互+可访问性
仅改背景色或文字色,对色觉障碍用户不友好,也缺乏交互反馈强度。真正可用的状态必须组合多个属性。
.active 必须:
- 添加
aria-current="page"属性(非 class) - 用
z-index: 1或z-10(Tailwind)防止被相邻边框遮盖 - 排除 hover 样式:
a:hover:not(.active):not(:disabled)
:disabled 或禁用链接必须:
- 同时设置
opacity: 0.5+cursor: not-allowed+pointer-events: none - 不能只靠
tabindex="-1",要确保键盘用户无法聚焦到该元素 - 禁用态文案(如“上一页”在第一页)需保留语义,不可删 DOM
真正难的不是让分页器“看起来像”,而是让每种状态都可感知、可聚焦、可缩放、可键盘操作——这些细节一旦漏掉,PC 用户可能无感,但对屏幕阅读器用户就是功能缺失。


















