Chrome中html标签设置scroll-behavior:smooth时HTML5表单验证消息不显示
Chrome 下
scroll-behavior: smooth 与 HTML5 原生表单验证冲突问题 这是Chrome浏览器的已知原生bug,大量开发者都遇到过同类场景。
问题原因
Chrome的表单校验错误提示气泡的定位计算逻辑,是在校验失败触发滚动动作之前同步完成的。当你设置了scroll-behavior: smooth时,页面滚动到错误字段的动作为异步执行,提示气泡会基于滚动前的视口位置计算坐标,最终气泡会渲染到视口外,所以用户看不到提示。
Firefox、Safari的校验逻辑是先完成滚动动作再计算气泡位置,因此不存在该问题。
修复方案
方案1:表单校验时临时关闭平滑滚动(侵入性最小,推荐)
监听全局invalid事件,在原生校验触发滚动前临时关闭平滑滚动,滚动完成后再恢复配置,代码如下:
document.addEventListener('invalid', function(e) { // 仅处理表单字段的校验失败事件 if (!e.target.form) return const root = document.documentElement const body = document.body // 存储原有平滑滚动配置 const originalScrollVal = getComputedStyle(root).scrollBehavior // 临时关闭平滑滚动 root.style.scrollBehavior = 'auto' body.style.scrollBehavior = 'auto' // 等原生滚动执行完成后恢复配置 requestAnimationFrame(function() { setTimeout(function() { root.style.scrollBehavior = originalScrollVal body.style.scrollBehavior = originalScrollVal }, 0) }) }, true) // 捕获阶段触发,早于浏览器默认校验行为
方案2:自定义表单校验逻辑
完全接管表单的校验事件,阻止原生校验的默认行为,自行实现错误提示展示和滚动逻辑,从根源上避免原生逻辑的冲突,适合本身就需要自定义校验样式的场景。
方案3:仅在Chrome下针对性关闭全局平滑滚动
如果可以接受Chrome下没有全局平滑滚动的效果,也可以用浏览器嗅探单独处理:
/* 仅Chrome生效的CSS hack */ @supports (-webkit-appearance: none) and (not (-moz-appearance: none)) { html, body { scroll-behavior: auto !important; } }
内容的提问来源于stack exchange,提问作者Darren Greer
相关产品推荐
相关产品推荐

