contenteditable 元素必须设 tabindex="0" 才能键盘聚焦,否则无法点击或 tab 进入;仅接受 "true"、"false"、空字符串;需配合 spellcheck="false" 避免下划线干扰。

contenteditable 必须配 tabindex="0" 才能键盘聚焦,否则点不进去、Tab 跳不过去——这不是兼容性问题,是规范强制要求。
为什么加了 contenteditable 还是无法输入?
它只认三个值:"true"、"false"、空字符串(等价于 "true"),写成 contenteditable="on" 或 contenteditable="plaintext-only" 全部被浏览器忽略。
- 光标点不进去、按 Tab 也跳不过去 → 缺
tabindex="0" - 能聚焦但输不了中文/符号 → 子元素有
user-select: none或pointer-events: none - 拼写下划线干扰 UI → 忘加
spellcheck="false"
正确写法示例:
<div contenteditable="true" tabindex="0" spellcheck="false">编辑区</div>
tabindex 的数值不是“越大越靠前”,而是语义开关
它的值决定元素是否参与自然焦点流,也直接影响屏幕阅读器顺序:
-
tabindex="-1":只能用 JS 主动调el.focus(),不进 Tab 流(适合弹窗根节点) -
tabindex="0":按 DOM 顺序加入 Tab 流,95% 场景该用这个 -
tabindex="5"及正数:强制前置顺序,但会打乱辅助技术逻辑,WCAG 明确不推荐
对 contenteditable 元素,tabindex 缺失 = 键盘不可达 = 直接违反 WCAG 2.1 2.1.1。
data-* 读写时命名和类型陷阱最多
HTML 中写 data-user-id="123",JS 中必须用 el.dataset.userId 访问(连字符自动转驼峰,首字母小写);dataset.userid 或 dataset.Userid 都取不到值。
- 属性名含数字开头(如
data-1st-place)→ JS 中只能用dataset["1st-place"],不能用点语法 - 值始终是字符串,哪怕写
data-count="0",取出来也是"0",需手动转类型:Number(el.dataset.count) - 命名只允许 ASCII 字母、数字、连字符(
-)、点(.)、下划线(_),data-user:name会被静默忽略
hidden 不是 display: none 的 HTML 替代品
hidden 是布尔属性,存在即生效,值无关紧要——写成 hidden="false" 依然隐藏。但它在某些上下文完全无效:
- 放在
<script></script>或<meta>上,浏览器静默忽略 - 它不支持动画过渡,也不保留布局空间(等效于
display: none) - 新值
hidden="until-found"是例外:视觉隐藏但保留位置,等效于content-visibility: hidden,用于懒加载
真正容易被忽略的是:全局属性不是“写了就生效”,而是依赖组合与上下文。比如 contenteditable 单独存在毫无意义,tabindex 值为正数会破坏辅助技术体验,data- 属性名含大写字母会导致 JS 读取失败——这些细节不报错,但会让功能在真实用户场景中静默失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











