SVG实现对勾描边动画最稳:先用getTotalLength()获取路径真实长度,设stroke-dasharray和stroke-dashoffset均为该值隐藏路径,再通过CSS transition将stroke-dashoffset减至0实现绘制效果。

直接用 SVG + CSS 是最稳的方案,伪元素或纯 CSS 画勾容易在高 DPI 屏、缩放 125% 或 Chrome 渲染下边缘发虚、错位;SVG 是矢量,缩放无损,还能加 fill、stroke-dasharray 动画,无障碍也更友好。
用 SVG 实现带描边动画的对勾
核心是把对勾路径拆成「描边动画」:先隐藏整个路径(stroke-dasharray 设为路径总长),再通过 stroke-dashoffset 从末尾往回拉,视觉上就是“画出来”的效果。
常见错误是直接写死 stroke-dasharray 值,但不同 SVG 路径长度不同,必须动态计算或用 JS 获取 getTotalLength()。
<svg viewBox="0 0 24 24" width="48" height="48"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" fill="none" stroke="#28a745" stroke-width="2"/></svg>- 给
<path>加 class,比如class="check-path" - CSS 中设
stroke-dasharray: 40; stroke-dashoffset: 40;(40 是示例,实际应等于该 path 的getTotalLength()) - :checked 触发时,加过渡并改
stroke-dashoffset: 0;
用伪元素 ::after 做简单对勾动画(慎用)
适合静态、低交互场景,比如表单提交成功后的状态提示。不推荐用于复选框或高频点击控件——旋转 + border 拼出的对勾,在 Chrome 120+ 和 macOS Safari 缩放时大概率出现 1px 锯齿或定位偏移。
立即学习“前端免费学习笔记(深入)”;
关键约束条件必须满足,否则 ::after 会飘走或不显示:
- 父元素必须有
position: relative; -
::after必须设content: "";、display: block;、position: absolute; - transform 旋转角度建议用
rotate(45deg),别用负角(如-135deg),部分旧版 Android WebView 解析异常 - 动画用
transform+opacity组合,别只靠visibility切换,否则无法触发过渡
input[type="checkbox"] 点击后对勾闪一下就消失?
这是最常见的 DOM 同步问题:你监听了 click,但没阻止默认行为,或者 checkbox 状态还没更新,CSS 选择器(比如 :checked + label .icon::after)就已尝试渲染。
根本原因是浏览器渲染时机与 JS 执行顺序不一致。解决方式只有两种:
- 用
:checked伪类驱动样式,完全交给 CSS 控制(推荐)——确保 HTML 结构是<input type="checkbox" id="x"><label for="x">...</label>,且 label 紧跟 input - 若必须用 JS 控制,得在
setTimeout(() => {}, 0)或requestAnimationFrame里读取input.checked,再操作 DOM
别在 click 回调里直接改 class 后立刻查 DOM 样式,此时 :checked 还没生效,CSS 也没重绘。
圆圈包对勾的动画怎么对齐中心?
圆圈和对勾不在同一坐标系里,硬套 transform: translate(-50%, -50%) 容易偏移,尤其当 SVG viewBox 和宽高比不一致时。
正确做法是统一锚点:
- SVG 外层用
display: inline-flex; align-items: center; justify-content: center; - 圆圈用
<circle cx="12" cy="12" r="10">(假设 viewBox="0 0 24 24") - 对勾
<path>的起点尽量靠近 (12,12),比如用d="M8 12 L11 15 L16 9",再整体transform="translate(0,0)" - 避免对
<path>单独设transform-origin,它会干扰 SVG 内部坐标系
最麻烦但最准的方式:把圆圈和对勾都包进一个 <g transform="translate(12,12)">,所有坐标按中心为原点写。



















