用 transform: rotate() 配合 :active 或 :hover 可实现图标旋转,但需在常态样式中添加 transition(如 transition: transform 0.3s ease)才能有动画效果;内联元素需设 display: inline-block/block;:active 适合按住旋转+松开回弹,移动端需加 :focus 和 touch-action: manipulation;累加旋转角度必须用 JS 控制 class 或 CSS 自定义属性;避免重排、大模糊阴影或 opacity 同时动画以防卡顿。

用 transform: rotate() 配合 :active 或 :hover 最简单
直接加在图标元素上就行,不需要 JS。但要注意:默认是瞬时旋转,没有过渡效果——得手动加 transition 才能“转起来”。
常见错误是只写 rotate(90deg) 却忘了声明过渡属性,结果图标“啪”一下就转到位,毫无动画感。
-
transition必须写在常态样式里(不是:active里),否则第一次点击没动画 - 推荐用
transition: transform 0.3s ease,避免影响其他属性 - 如果图标是
<i class="icon"></i>这类内联元素,确保它有明确的display: inline-block或display: block,否则transform可能不生效
需要“按住旋转 + 松开回弹”?用 :active + transition 组合
这种交互更符合物理直觉,但得注意浏览器对 :active 的触发时机和持续时间——移动端可能不触发,或松手延迟才触发。
示例写法:
立即学习“前端免费学习笔记(深入)”;
.icon {
display: inline-block;
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.icon:active {
transform: rotate(90deg);
}
-
cubic-bezier(0.34, 1.56, 0.64, 1)是个轻微过冲再回弹的缓动,比默认ease更有反馈感 - 别用太长的
transition时间(比如 >0.4s),否则松手后还在转,用户会困惑“是不是卡了” - 移动端建议同时加
:focus和touch-action: manipulation提升响应一致性
想让图标“点击一次转 90°,再点再转”?必须用 JS 控制 class
CSS 本身无法记录点击次数,:active 和 :hover 都是瞬态伪类,没法维持状态。这时候得靠 JS 切换一个标记 class,比如 .rotated。
- HTML 中给图标加
data-rotation="0"初始值,JS 每次点击 +90,再设style.transform = `rotate(${deg}deg)` - 或者更轻量:JS 只负责 toggle
.is-rotated,CSS 里写.is-rotated { transform: rotate(90deg); }——但这样只能二值切换(0/90),不能累加 - 如果用 CSS 自定义属性(
--rotate),配合 JS 更新element.style.setProperty('--rotate', deg),就能实现任意角度累加,且仍走 GPU 加速
旋转动画卡顿?检查是否触发了重排(reflow)
旋转本身是合成属性,一般很流畅,但如果父容器或图标自身有 width/height 动态变化、box-shadow 模糊值过大、或用了 filter: drop-shadow(),就可能掉帧。
- 优先用
transform: rotate(),别用left/top+position: absolute模拟旋转 - 避免在旋转元素上同时做
opacity动画,尤其在低端 Android 上容易糊 - 真要调试性能,打开 Chrome DevTools → Rendering → 勾选 “Paint flashing”,看旋转时是否频繁重绘
真正麻烦的是 SVG 图标内部有 <use> 引用或复杂渐变——那种情况下,transform 可能被降级到 CPU 渲染。得拆出来单独包裹一层 <g> 再旋转。


















