纯css提示动画需同时控制opacity和visibility:淡入时先设visibility:visible再过渡opacity;淡出时监听transitionend后设visibility:hidden,配合aria-live和role确保无障碍支持。

用 CSS transition 控制 opacity 和 visibility 的组合动画
纯 CSS 实现提示信息淡入淡出,关键不是只改 opacity,否则元素仍占布局空间、可能遮挡交互。必须配合 visibility(控制是否参与渲染)和 transition 触发时机。
常见错误是只写 opacity: 0 → 1,结果提示框“看不见但点不着后面的输入框”,或者淡出后仍能触发 :hover。
- 淡入时:先设
visibility: visible,再过渡opacity(延迟设 visibility 会导致闪一下) - 淡出时:用
transitionend事件监听 opacity 到 0 后,再设visibility: hidden;或用animation+animation-fill-mode: forwards配合 keyframes 精确控制 - 推荐用 class 切换(如
.hint--show),避免内联样式干扰可维护性
JavaScript 中何时触发显示/隐藏逻辑
表单提示不是一概而论地“聚焦就显示”,得看场景:实时校验提示、提交后集中提示、还是仅在用户操作后出现?过早显示会干扰输入,过晚又失去意义。
典型误用是给每个 <input> 绑定 onblur 就立刻 show 提示——但用户刚点进下一个输入框,上一个的提示还没 fade out 完,视觉混乱。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 显示时机建议:结合
input(防抖 300ms)、blur(确认离开)、或表单submit事件 - 隐藏时机建议:不是简单 hide,而是调用一个
hideHint(el)函数,在transitionend回调里移除 class 或清空内容 - 注意多个提示共存时的竞态:比如用户快速切换 input,要 abort 前一个未完成的 fade-out 动画(用
el.style.animationName = ''或 cancelAnimationFrame)
兼容性与无障碍(a11y)注意事项
淡入淡出对屏幕阅读器不透明——它不会自动 announce 提示文字,也不会感知 opacity: 0 后是否该忽略该元素。
最常被忽略的一点:用 aria-live="polite" 包住提示容器,才能让变化被读屏软件捕获;否则视力障碍用户完全不知道校验失败了。
- 提示容器必须有明确 role,例如
role="alert"(错误)或role="status"(一般状态),不能只是 div - 不要用
display: none或visibility: hidden隐藏提示后再淡入——这会让 a11y 树瞬间丢失节点,读屏器无法平滑过渡 - 动画 duration 建议 200–300ms:太短用户感知不到,太长(>500ms)会被判定为响应迟钝
避免用 setTimeout 模拟淡出延迟
有人用 setTimeout(() => el.remove(), 300) 配合 CSS fade-out,看似简单,实则埋雷:如果用户中途手动修改了 input,这个定时器还在跑,可能把刚更新的提示删掉。
更糟的是,CSS 动画若被强制重排(如父容器 resize),transitionend 可能不触发,导致提示永远挂在页面上、visibility 卡在 visible。
- 始终监听
transitionend,且检查event.propertyName === 'opacity',防止其他 transition 干扰 - 加兜底:设置一个最大等待时间(如 600ms),超时后强制 cleanup
- React/Vue 用户注意:不要在组件 unmount 时才清理定时器,要在 class 移除前就解绑 transitionend 监听器
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










