应优先用 <a> 实现真实跳转,用 <button> 处理 JS 交互;二者均需设 display: block、可聚焦及键盘支持,禁用状态用 disabled,伪元素图标应基于卡片元素定位,移动端热区不小于 44×44px。

用 <a> 还是 <button>?先看跳转意图
整卡点击是否真要跳转到新页面或锚点?是,就用 <a href="...">;否(比如展开详情、切换状态、弹窗),必须用 <button type="button">。混用会破坏无障碍:屏幕阅读器把无跳转的 <a> 读作“链接”,键盘用户按 Enter 却没反应,会被 axe 等工具标为严重问题。
常见错误:<div onclick="doSomething()"> —— 它既不能聚焦,也不响应 Space/Enter,还缺失 role 和 tabindex,纯属不可访问。
正确做法:
- 真实跳转 →
<a class="card" href="/dashboard">...,并确保href值有效(非#或空字符串) - JS 交互 →
<button type="button" class="card" data-action="open-modal">...,加aria-label补充语义(如aria-label="查看项目详情") - 禁用状态 → 用
disabled属性(<button disabled>),别只靠 CSS 加opacity: 0.5
display: block 是基础,但别漏掉可聚焦和键盘支持
卡片元素(<a> 或 <button>)默认是内联元素,必须显式设为块级才能撑满内容区域。光靠 display: block 不够,还得让它能被键盘聚焦、支持 Enter/Space 触发。
立即学习“前端免费学习笔记(深入)”;
关键设置:
-
<a>默认可聚焦,但若加了href="#",需阻止默认跳转:event.preventDefault(),否则页面会滚顶 -
<button>默认可聚焦且响应 Enter/Space,无需额外tabindex - 若用
<a>且无href(比如仅 JS 驱动),必须加tabindex="0"才能聚焦 - 监听
click的同时,也得监听keydown,判断event.key === 'Enter' || event.key === ' '
示例片段:
<button type="button" class="card" data-action="toggle-detail"> <h3>项目概览</h3> <p>点击展开详细配置</p> </button>
CSS 中确保它行为像卡片容器:.card { display: block; width: 100%; padding: 1rem; border-radius: 8px; }
伪元素图标右上角定位,别依赖嵌套结构
想在卡片右上角加个「→」或「↗」图标?别写 <a><div class="card">...</div></a> 再用 .card.--linked::before,这样伪元素会基于内部 <div> 渲染,位置难控,还容易被截断。
正确方式:让卡片本体(即 <a> 或 <button>)自己承担样式职责。
- 给卡片元素加
position: relative - 用
::before直接作用于该元素:.card.--linked::before { content: "→"; position: absolute; top: 0.5rem; right: 0.5rem; } - 通过
data-pseudo-text动态控制内容:<a class="card --linked" data-pseudo-text="↗" href="...">,CSS 中用content: attr(data-pseudo-text) - 避免文本外溢:加
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;到伪元素上
移动端热区与事件绑定位置必须精准
在手机上,整卡点击失效常因两点:触控热区太小,或事件绑错位置。
热区要求:
- 最小尺寸 ≥ 44×44px(iOS/Android 无障碍规范)
- 用
padding扩展可点区域,别只靠height/min-height - 禁用
user-select: none,否则长按可能触发复制菜单干扰点击
事件绑定陷阱:
- 通知类卡片里,按钮点击没反应?检查
onclick是否写在父<div class="notification">上 —— 应直接绑定在<button>元素本身 - 多张卡片共用 JS 逻辑?用事件委托(监听父容器)时,务必用
event.target.closest('button.card')精准识别目标,避免冒泡误触发 - 动态插入的卡片?别用
onclick="..."行内属性,统一用addEventListener并注意清理(尤其 SPA 场景)
最易被忽略的一点:卡片若含图片或懒加载内容,首次点击可能因布局抖动导致点击坐标偏移 —— 建议卡片容器设固定宽高或用 aspect-ratio 预留空间。



















