contenteditable不是“加了就能编辑”的开关,缺tabindex="0"就等于没加——键盘根本进不去,WCAG 2.1 2.1.1直接不通过;它只认true、false、空字符串三个合法值,其他如"on"或"plaintext-only"均被忽略。

contenteditable 不是“加了就能编辑”的开关,缺 tabindex="0" 就等于没加——键盘根本进不去,WCAG 2.1 2.1.1 直接不通过。
为什么 contenteditable 加了却点不进去、输不了字?
它只认三个值:true、false、空字符串(等价于 true),其他如 "plaintext-only" 或 "on" 全部被忽略。常见卡点:
- 光标点不进去、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 缺失 = 键盘不可达 = 违反可访问性底线。
data-* 和 id 看似都能标识元素,但用途完全错开
混淆它们会导致数据取不到、样式失效或脚本报错:
-
data-user-id="123"→ JS 中必须用el.dataset.userId访问(连字符自动转驼峰) -
id="user-123"→ 是文档唯一锚点,CSS 选中用#user-123,JS 用document.getElementById("user-123") -
data-命名必须全小写+连字符,不能含大写字母或下划线;id首字符只能是字母或下划线
data- 存运行时数据,不参与样式、无障碍或 SEO;id 影响 ARIA 关联(比如 aria-labelledby)、页面内跳转和 CSS 优先级。
hidden 不只是“看不见”,它分两种行为模式
默认 hidden 等价于 display: none,不占布局空间;但新值 hidden="until-found" 是例外:
-
hidden(无值或hidden="hidden")→ 完全移出渲染流,内外边距、宽高都不计算 -
hidden="until-found"→ 视觉隐藏但保留布局位置,等效于content-visibility: hidden,用于懒加载场景
注意:hidden 在 <script></script> 或 <meta> 上无效,浏览器直接忽略;它也不是 CSS 替代品,别用来做动画显隐。
真正容易被忽略的,是 contenteditable 和 tabindex 的绑定关系 —— 不是“可选搭配”,而是硬性依赖;还有 data- 属性在 JS 中的驼峰转换规则,写错名字就拿不到值。这些点不实操几遍,很容易在上线后才发现聚焦失败或数据丢失。



















