文章摘要
文章核心内容:作者反对开发者用<div>代替<button>的做法,指出<div>无法被屏幕阅读器识别为交互元素、不支持键盘聚焦和操作,严重影响可访问性。尽管某些知名开发者支持这种模式,但作者坚持认为应该正确使用语义化的<button>元素。
文章总结
标题:直接使用按钮元素就好
在框架热衷开发者中,我经常遇到一个奇怪的"争论":用<div>替代<button>是否"同样好"。
剧透答案:并非如此。让我们深入探讨。
问题现状
在React和HTMX社区中,常见以下写法: ```html
打开弹窗
``
这种写法存在三个核心问题:
1. 屏幕阅读器无法识别这是可交互元素
2.
`无法通过键盘获得焦点
3. 仅响应鼠标点击,不响应Enter或空格键事件
我曾与某位知名React意见领袖(名字以R开头)争论,对方坚称这种写法"更具可访问性",甚至以Twitter采用此模式为例。
这完全错误。
所谓的"修复方案"
虽然可以通过以下方式部分修复: ```html
打开弹窗
``` 但这会带来新问题: - 破坏正常的焦点顺序 - 仍需额外监听键盘事件 - 需要编写复杂的事件过滤代码
本质问题
这些"修复"实际上是在手动实现<button>原生具备的功能:
1. 自动具有button角色
2. 天然可聚焦
3. 自动响应键盘事件
最终建议
作为开发者,应该选择最高效的方案:
html
<button onclick="showSignIn()">打开弹窗</button>
使用正确的HTML元素,既能保证可访问性,又能减少不必要的代码量。这才是真正的"懒惰"智慧。
评论总结
评论内容总结:
支持使用语义化HTML元素(如
<button>和<a>)- 观点:应优先使用符合原始设计意图的HTML元素(如按钮用于交互,锚标签用于导航)。
- 引用:"Use elements as close to their original intention as possible"(评论3)
- 引用:"Just use a damn anchor tag, which gets you correct link behavior for free"(评论8)
- 论据:语义化元素自带无障碍支持、浏览器默认行为和功能(如中键打开新标签页)。
- 观点:应优先使用符合原始设计意图的HTML元素(如按钮用于交互,锚标签用于导航)。
质疑
<div>的无障碍兼容性问题- 观点:部分开发者认为现代屏幕阅读器已能识别带
onclick的<div>为可交互元素。- 引用:"screen readers have obviously become sophisticated enough to recognize a div with an onclick handler"(评论5)
- 引用:"Screen readers should be able to detect a div with a onclick as interactable"(评论10)
- 反驳:其他评论坚持语义化元素的必要性,认为
<div>仍需额外属性(如role="button")才能确保无障碍。
- 观点:部分开发者认为现代屏幕阅读器已能识别带
开发者选择
<div>的潜在原因- 观点:浏览器默认样式(如按钮的
align-items: flex-start)或框架文化导致开发者回避原生元素。- 引用:"I got bitten by... 'button {align-items: flex-start}'... using divs everywhere makes my small side projects easier"(评论13)
- 引用:"React thought-leader-guy crowd preferred div over button because of built-in styles"(评论11)
- 观点:浏览器默认样式(如按钮的
对HTML语义知识的普遍缺乏
- 观点:许多开发者不熟悉HTML元素的设计初衷,倾向于重复造轮子。
- 引用:"Your average SPA developer doesn't understand what even a quarter of the HTML elements are meant for"(评论12)
- 引用:"The type of developers that would go with div... know very little about semantic HTML"(评论16)
- 观点:许多开发者不熟悉HTML元素的设计初衷,倾向于重复造轮子。
其他技术建议
- 按钮类型:建议明确设置
type="button"以避免表单误提交(评论7)。 - 组件抽象:通过封装组件统一按钮和锚标签的样式与行为(评论15)。
- 未解决问题:
<input type="button">的使用场景未明确讨论(评论14)。
- 按钮类型:建议明确设置
争议焦点:
- 无障碍支持:屏幕阅读器是否能完全识别
<div>的交互性存在分歧。 - 开发便利性:原生元素的默认行为(如样式)是否阻碍了开发效率。
- 行业现状:部分评论批评现代Web开发过度复杂化(评论16)。