SVG中实现悬停小方块触发大小方块脉动动画的问题
解决方案:仅悬停小方块时触发两者脉动
使用 :has() 选择器的正确实现
你之前的 :has() 用法逻辑错误,.rect_large 并不包含 .rect_small,二者是同一父容器下的兄弟元素。正确的做法是通过父容器 .wrapper 检测子元素 .rect_small 的悬停状态,再同时控制两个方块的动画:
/* 当 wrapper 包含悬停的小方块时,触发两个方块的脉动动画 */ .wrapper:has(.rect_small:hover) .rect_small { animation: pulsate 2s ease forwards; transform-origin: center; } .wrapper:has(.rect_small:hover) .rect_large { animation: pulsate 2s ease forwards 1s; transform-origin: center; } /* 保留原有旋转动画 */ .g_large { animation: rotate_large 5s linear infinite; transform-origin: center; } @keyframes rotate_large { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .g_small { animation: rotate_small 5s linear infinite; transform-origin: center; } @keyframes rotate_small { 0% { transform: rotate(0deg); } 100% { transform: rotate(720deg); } } @keyframes pulsate { 0% { fill: black; transform: scale(1); } 5% { fill: red; transform: scale(1.5); } 100% { fill: black; transform: scale(1); } }
HTML 结构无需修改,保持原层级即可。
不使用 :has() 的兼容方案(JavaScript)
针对不支持 :has() 的浏览器(如旧版 Firefox),可以通过 JavaScript 监听小方块的悬停事件,为父容器添加/移除类来触发动画:
CSS 修改:
/* 用类替代 :has() 检测逻辑 */ .wrapper.pulse-active .rect_small { animation: pulsate 2s ease forwards; transform-origin: center; } .wrapper.pulse-active .rect_large { animation: pulsate 2s ease forwards 1s; transform-origin: center; } /* 原有旋转动画保留 */ .g_large { animation: rotate_large 5s linear infinite; transform-origin: center; } @keyframes rotate_large { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .g_small { animation: rotate_small 5s linear infinite; transform-origin: center; } @keyframes rotate_small { 0% { transform: rotate(0deg); } 100% { transform: rotate(720deg); } } @keyframes pulsate { 0% { fill: black; transform: scale(1); } 5% { fill: red; transform: scale(1.5); } 100% { fill: black; transform: scale(1); } }
JavaScript 代码:
const smallRect = document.querySelector('.rect_small'); const wrapper = document.querySelector('.wrapper'); smallRect.addEventListener('mouseenter', () => { wrapper.classList.add('pulse-active'); }); smallRect.addEventListener('mouseleave', () => { // 等待动画完全结束后移除类,避免中途打断动画 setTimeout(() => { wrapper.classList.remove('pulse-active'); }, 3000); // 总动画时长:小方块2s + 大方块延迟1s = 3s });
该方案通过添加类触发动画,鼠标离开小方块后等待动画完成再移除类,确保动画正常执行完毕。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

