如何实现CSS鼠标悬停时的网格3D凸起(Bulge out/Pop)效果
实现Themekaverse网站Discord区域网格悬停3D凸起特效的最佳方案
我想复刻Themekaverse网站中「Join our Discord」区域的CSS特效——该区域背景是网格结构,鼠标悬停时会呈现平滑的3D凸起(Bulge out/Pop)变换动画。我之前尝试用div创建网格,再添加transform: matrix3d()属性来实现,但效果不对,请问最佳实现方式是什么?
特效示意图:
核心实现思路
不用大量DOM元素构建网格(性能差且难控制),改用CSS渐变绘制网格背景,配合JS监听鼠标位置+CSS 3D变换实现跟随鼠标的平滑凸起效果,这是还原原特效的最优方案。
代码实现示例
HTML结构
<div class="discord-section"> <div class="grid-background"></div> <div class="section-content">Join our Discord</div> </div>
CSS样式
.discord-section { position: relative; width: 100%; height: 400px; overflow: hidden; perspective: 1200px; /* 开启3D透视空间,数值越大凸起效果越平缓 */ display: flex; align-items: center; justify-content: center; background-color: #161932; /* 匹配原网站深色背景 */ color: #fff; font-size: 2rem; } .grid-background { position: absolute; inset: 0; /* 用线性渐变绘制横竖网格线 */ background-image: linear-gradient(rgba(255, 255, 255, 0.08) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.08) 1px, transparent 1px); background-size: 36px 36px; /* 控制网格间距 */ transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); /* 平滑过渡动画 */ transform-style: preserve-3d; /* 保留3D变换层级 */ } .section-content { position: relative; z-index: 1; /* 确保内容在网格上方 */ }
JS交互逻辑
const section = document.querySelector('.discord-section'); const gridBg = document.querySelector('.grid-background'); section.addEventListener('mousemove', (e) => { const rect = section.getBoundingClientRect(); // 计算鼠标在区域内的相对坐标(范围0-1) const relX = (e.clientX - rect.left) / rect.width; const relY = (e.clientY - rect.top) / rect.height; // 计算凸起强度:鼠标越靠近中心,凸起越高 const distanceFromCenter = Math.sqrt(Math.pow(relX - 0.5, 2) + Math.pow(relY - 0.5, 2)); const maxZ = 50; // 最大凸起高度 const currentZ = maxZ * (1 - distanceFromCenter * 2); // 计算缩放系数:凸起区域中心轻微放大,边缘收缩,增强3D感 const scaleFactor = 1 + (0.06 * (1 - distanceFromCenter * 2)); // 应用3D变换 gridBg.style.transform = ` perspective(1200px) translateZ(${Math.max(0, currentZ)}px) scale3d(${scaleFactor}, ${scaleFactor}, 1) `; }); // 鼠标离开时恢复原状 section.addEventListener('mouseleave', () => { gridBg.style.transform = 'perspective(1200px) translateZ(0) scale3d(1, 1, 1)'; });
关键细节说明
- 网格绘制:用CSS渐变替代DOM网格,减少节点数量,提升渲染性能,同时方便调整网格颜色、间距。
- 3D变换:通过
perspective创建透视空间,translateZ控制凸起高度,scale3d增强立体变形感,配合缓动函数实现平滑过渡。 - 鼠标跟随:通过计算鼠标与区域中心的距离,动态调整凸起强度,让效果更贴合原网站的交互逻辑。
内容的提问来源于stack exchange,提问作者code_it
相关产品推荐
相关产品推荐


