html
在Chrome中,用户常报告「输入框无闪烁竖线」「点击textarea后光标不出现」「聚焦后可输入但不可见光标」——这并非功能失效,而是视觉渲染层与焦点状态的错位。值得注意的是:键盘输入仍生效(说明focus事件已触发),DOM元素实际处于active状态(document.activeElement返回正确节点),但光标未绘制。该现象在v110+ Chrome中因Blink引擎对caret-color合成路径的优化而更易暴露。
- Caret-color透明化:
input, textarea { caret-color: transparent; }是最常见元凶;需注意继承链中父级color: transparent也会间接影响(因caret-color: auto默认取color值) - User-select阻断:
user-select: none虽不直接隐藏光标,但会禁用selection API,导致getSelection().toString()恒为空字符串,进而使Blink跳过光标合成帧 - Outline/border裁剪:当
outline: none配合border: 0且父容器overflow: hidden时,光标渲染区域被CSS盒模型裁切(尤其在缩放/高DPI屏下)
验证路径:DevTools → Elements → 选中元素 → Computed tab → 搜索caret-color、user-select、outline,观察来源(inline/style tag/UA stylesheet)及计算值。
element.focus()被Promise.then阻塞 执行
console.log(document.activeElement)在
setTimeout(() => {}, 0)中返回
body 改用
element.focus({preventScroll: true})并监听
focusin事件确认完成 React/Vue中受控组件未同步value
document.activeElement.value与state不一致,且
input事件未触发 检查
value prop是否为undefined或null,强制设置
defaultValue兜底
当启用硬件加速时,Chrome将光标作为独立图层合成。若存在以下情形,光标图层可能被丢弃或未参与合成:
/* 高风险CSS组合 */ .input-wrapper { transform: translateZ(0); /* 强制创建新层 */ overflow: hidden; /* 裁剪子层渲染边界 */ will-change: transform; /* 提前声明但未合理释放 */ }
复现方法:在DevTools → Rendering → 勾选「Paint flashing」和「Layer borders」,观察光标区域是否出现红色闪动(paint)但无绿色层边框(layer)。此时需临时移除will-change或添加contain: layout paint隔离影响域。
- 全局CSS重置中显式声明:
input, textarea { caret-color: auto !important; user-select: text !important; } - 焦点操作封装为hook:
useSafeFocus(ref, { delay: 16 }),内部使用requestAnimationFrame确保在下一帧执行 - CI阶段注入自动化检测脚本:遍历所有
input[type=text],断言getComputedStyle(el).caretColor !== ‘transparent’
Chrome 125+已引入chrome://flags/#enable-caret-blinking实验开关,但企业级项目应避免依赖flag,而通过CSS containment和焦点委托模式构建鲁棒性。
Blink引擎在M112(2023.Q2)后修改了光标合成策略:当caret-color为currentcolor且父级color为rgba(0,0,0,0)时,不再回退至默认黑色,而是完全透明。此变更导致大量历史CSS库(如Bootstrap 4.x)在暗色主题下批量失效。解决方案是升级至Bootstrap 5.3+或手动覆盖caret-color: #000。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/268552.html