用 css ::after 伪元素插入 unicode 箭头(▲/▼)最轻量可靠,不改 html、不依赖 js,兼容 ie8 且无障碍友好;直接写入字符会破坏语义、导致图标丢失及 aria-sort 脱节。

直接用 CSS ::after 伪元素插入 Unicode 箭头(▲/▼)是最轻量、最可靠的做法,不用改 HTML 结构,也不依赖 JS 插入文本,可访问性好,IE8 都能跑。
为什么不能直接往 th 里写 ▲ 或 ▼ 字符
硬塞进 textContent 或用 innerHTML 覆盖内容,会破坏原有表头文字的语义和屏幕阅读器播报;而且一旦 JS 重绘或 DOM 更新,图标容易丢失或错位。更关键的是:这类操作会让 aria-sort 属性与视觉状态脱节,无障碍体验直接打折。
- 别写成
▲或↑—— 这些是 HTML 实体,在某些环境里渲染不稳定 - 别用
↑/↓这类旧符号 —— 字形窄、基线高,和文字对不齐 - Unicode 箭头必须是
▲(U+25B2)和▼(U+25BC),复制粘贴即可,不要转义
::after 伪元素怎么写才不踩坑
伪元素看着简单,但几个细节没设对,图标就歪、挤、看不见:
- 必须设
display: inline-block,否则width/height/vertical-align全无效 -
content: '▲'前后加空格(如content: ' ▲'),不然紧贴文字难分辨 - 一定要配
vertical-align: middle,否则图标挂在文字下半截,像掉了一样 - 隐藏未排序状态的图标,用
visibility: hidden,别用display: none—— 后者会破坏行内流布局,导致表头宽度跳变
示例 CSS:
th.sortable::after {
content: '▽';
color: #999;
font-size: 0.8em;
display: inline-block;
vertical-align: middle;
visibility: visible;
}
th.sorted-asc::after {
content: ' ▲';
color: #007bff;
}
th.sorted-desc::after {
content: ' ▼';
color: #007bff;
}
JS 切换排序状态时只动 class,不动 DOM 内容
图标只是反馈,核心是维护排序状态。每次点击表头,JS 只做三件事:
- 读当前
th的 class 和aria-sort值,判断是未排序、升序还是降序 - 清除所有
th的sorted-asc/sorted-desc类,只给当前列加对应 class - 同步更新
aria-sort属性:aria-sort="ascending"、"descending"或"none"
千万别用 el.innerHTML = '姓名 ▲' 这种方式——焦点会丢失,屏幕阅读器可能重复读两次,React/Vue 组件里还容易触发不必要的 re-render。
最易被忽略的点:伪元素里的空格和 vertical-align 必须一起存在,少一个图标就偏得离谱;aria-sort 和 class 不同步,等于把无障碍支持关掉了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











