使用JavaScript实现鼠标悬停卡片时单独控制其余卡片的CSS动画效果
实现方案
思路说明
需求可通过少量JS配合CSS类实现,整体逻辑如下:
- 抽离卡片通用CSS样式,减少冗余代码
- 自定义非悬停卡片的@keyframes动画效果
- 通过JS监听卡片悬停事件,给未被悬停的卡片添加动画触发类
步骤1:修改CSS代码
把原来重复的ID样式替换为通用类,同时添加自定义动画规则:
#container { display: flex; justify-content: space-around; height: 100vh; align-items: center; } /* 通用卡片样式,替换原重复的ID样式 */ .flip-box { background-color: transparent; width: 300px; height: 200px; perspective: 1000px; } .flip-box-inner { position: relative; width: 100%; height: 100%; text-align: center; transition: transform 0.8s; transform-style: preserve-3d; } /* 保留自身悬停翻转效果 */ .flip-box:hover .flip-box-inner { transform: rotateY(180deg); } .flip-box-front, .flip-box-back { position: absolute; width: 100%; height: 100%; -webkit-backface-visibility: hidden; backface-visibility: hidden; background-size: contain; background-repeat: no-repeat; } .flip-box-back { transform: rotateY(180deg); } /* 单独设置每个卡片的背景图 */ #flip-box-front-1 { background-image: url("//picsum.photos/300/200?c=f1"); } #flip-box-back-1 { background-image: url("//picsum.photos/300/200?c=b1"); } #flip-box-front-2 { background-image: url("//picsum.photos/300/200?c=f2"); } #flip-box-back-2 { background-image: url("//picsum.photos/300/200?c=b2"); } #flip-box-front-3 { background-image: url("//picsum.photos/300/200?c=f3"); } #flip-box-back-3 { background-image: url("//picsum.photos/300/200?c=b3"); } /* 自定义未悬停卡片的动画,可按需修改参数 */ @keyframes otherCardAnimation { 0% { transform: scale(1) translateY(0); opacity: 1; } 50% { transform: scale(0.9) translateY(-10px); opacity: 0.7; } 100% { transform: scale(1) translateY(0); opacity: 1; } } /* 动画触发类 */ .hover-other .flip-box-inner { animation: otherCardAnimation 1s ease-in-out infinite; }
步骤2:修改HTML代码
给所有卡片元素添加通用类,兼容原有逻辑:
<div id="container"> <div id="flip-box-1" class="flip-box"> <div id="flip-box-inner-1" class="flip-box-inner"> <div id="flip-box-front-1" class="flip-box-front"></div> <div id="flip-box-back-1" class="flip-box-back"></div> </div> </div> <div id="flip-box-2" class="flip-box"> <div id="flip-box-inner-2" class="flip-box-inner"> <div id="flip-box-front-2" class="flip-box-front"></div> <div id="flip-box-back-2" class="flip-box-back"></div> </div> </div> <div id="flip-box-3" class="flip-box"> <div id="flip-box-inner-3" class="flip-box-inner"> <div id="flip-box-front-3" class="flip-box-front"></div> <div id="flip-box-back-3" class="flip-box-back"></div> </div> </div> </div>
步骤3:添加JS逻辑
在HTML末尾插入如下脚本即可实现需求:
// 获取所有卡片元素 const allCards = document.querySelectorAll('.flip-box'); allCards.forEach(card => { // 监听鼠标进入事件 card.addEventListener('mouseenter', () => { allCards.forEach(item => { // 给非当前悬停的卡片添加动画类 if(item !== card) { item.classList.add('hover-other'); } }) }) // 监听鼠标移出事件 card.addEventListener('mouseleave', () => { allCards.forEach(item => { // 移除所有卡片的动画类 item.classList.remove('hover-other'); }) }) })
自定义调整说明
你可以按需修改@keyframes otherCardAnimation里的属性,实现位移、旋转、灰度、透明度等任意需要的动画效果,也可以调整动画时长、循环次数、缓动函数等参数。
内容的提问来源于stack exchange,提问作者Luke Cody
相关产品推荐
相关产品推荐

