button不加type默认为submit导致表单提交;disabled不阻止键盘焦点,需配合tabindex="-1"和keydown监听;innerhtml含富文本需防xss;样式重置须覆盖ua默认值。

button 元素不加 type 属性会触发表单提交
很多新手写 <button>提交</button> 放在 <form></form> 里,一点击页面就刷新——不是 JS 没绑上,是浏览器默认把没声明 type 的 button 当成 type="submit" 了。
必须显式写清楚行为:
-
type="button":纯 UI 按钮,点击不触发任何表单动作 -
type="submit":明确用于提交表单(即使不在<form></form>内也安全) -
type="reset":仅在表单内有效,清空字段值
漏写 type 是最常被忽略的兼容性陷阱,尤其在 React/Vue 动态渲染按钮时,容易因条件分支漏掉属性。
disabled 状态下按钮仍能被 focus 和键盘触发
disabled 只禁用鼠标点击和表单提交,但不会阻止键盘焦点进入(尤其在 Safari 和旧版 Edge),用户按 Tab 键仍可能 focus 到它,再按空格或回车,某些浏览器会意外触发 click 事件。
立即学习“前端免费学习笔记(深入)”;
更稳妥的做法是组合使用:
- 加上
disabled属性(视觉禁用 + 阻止大部分交互) - 同时加
tabindex="-1"(移出焦点流) - 监听
keydown过滤空格/回车(防御性兜底)
单纯靠 CSS pointer-events: none 不可靠——它不影响键盘行为,也不影响屏幕阅读器语义。
button 里的 innerHTML 会被当作富文本解析
写 <button><span>删除</span></button> 是合法的,但要注意:
- 嵌套元素会参与可访问性树(a11y),屏幕阅读器会读出所有子内容,可能重复或混乱
- 部分老版本 Android WebView 对 inline 元素支持不稳定,出现文字截断
- 如果按钮内容来自用户输入,直接插入 HTML 有 XSS 风险,应优先用
textContent或转义后注入
简单操作建议:纯文本按钮用 textContent;需要图标+文字,用 <svg></svg> + aria-hidden="true" + 显式 aria-label。
button 样式重置必须覆盖 user agent stylesheet
不同浏览器对 <button></button> 有差异极大的默认样式:Chrome 加阴影、Firefox 有内边距、Safari 默认圆角。不重置的话,CSS 里写的 padding: 0 可能被 UA 样式覆盖。
最小必要重置项(推荐放在项目基础样式里):
-
border: none(否则 Safari 默认有深色边框) -
background: transparent(避免 Firefox 默认灰底) -
padding: 0(各浏览器默认值不同) -
font: inherit(继承父级字体,否则可能用系统默认等宽字体) -
line-height: normal(防止文字垂直偏移)
别只写 all: unset——它会干掉 cursor: pointer 和可访问性语义,反而让按钮“不可见”于辅助技术。











