button 默认 type 为 submit,需显式设为 button 避免误提交;必须重置 appearance、border、background 样式;需完整定义 hover/active/focus/disabled 状态以保障可访问性;禁用 div 或 a 模拟按钮。

button 默认 type 是 submit,不写就容易误提交
直接放一个 <button>点我</button>,用户点它或按回车,表单立刻提交——不是 bug,是浏览器规范行为。哪怕 JS 还没加载完,请求已经发出去了。
必须显式声明:<button type="button">点我</button> 才纯触发 JS;要提交表单,才用 type="submit",且确保它在 <form></form> 内部。
-
type="reset"只在表单内有意义,会清空所有控件值,慎用 - 别依赖
event.preventDefault()拦截:脚本失败或延迟时,拦截就失效 - 服务端校验不能代替这个前端约束——提交前拦住比事后纠错成本低得多
appearance: none、border: none、background: none 必须三件套起步
浏览器对 <button></button> 有强 UA 样式:Safari 死守 padding 和 border,Firefox 加阴影,Chrome 继承父级 font-size 导致文字大小飘忽。只改 background 或 color 常常没效果。
起步重置样式必须包含:
-
appearance: none;(补-webkit-appearance: none;和-moz-appearance: none;) border: none;background: none;
文字居中别只靠 text-align: center——<button></button> 是 inline-level 元素,建议用 display: flex; align-items: center; justify-content: center; 或配 line-height 匹配高度。
:hover/:active/:focus/:disabled 必须单独定义
光写 :hover 不够。键盘用户 Tab 进入时看不到焦点,触摸屏上 :active 可能一闪而过,:disabled 若只靠 opacity 模拟,仍可被点击或聚焦。
-
:focus必须保留可见轮廓,比如outline: 2px solid #007bff;;删掉outline是可访问性硬伤 -
:active建议用transform: scale(0.98)或改背景色,避免只靠颜色变化(色盲用户难感知) -
:disabled要同步设置cursor: not-allowed;、opacity: 0.6;和pointer-events: none; - 移动端需加
@media (hover: none) and (pointer: coarse)降级:hover效果,否则手指按下去没反馈
别用 <div> 或 <code><a></a> 模拟按钮
用 <div onclick="..."> 或 <code><a href="#"></a> 做按钮,会丢失默认可聚焦性、不响应 Enter 键、无障碍属性缺失、SEO 权重弱——这些不是“看起来像就行”的问题,而是实际使用中必然暴露的缺陷。
真正可用的按钮,必须用 <button></button> 标签,再配合语义化 type 和完整伪类状态控制。复杂交互(如下载进度、数字键盘)确实需要 JS,但按钮本身的基础行为,不该靠 JS 补救。
最容易被忽略的点:伪类状态不是“锦上添花”,而是输入设备切换时的必填项——键盘、触屏、鼠标各自依赖不同状态,漏掉任何一个,都可能让某类用户完全无法操作。











