实现CSS Grid网格项Hover时的平滑位置过渡效果
实现CSS Grid布局切换时的平滑过渡效果
需求说明
- 默认是3列2行(3x2)的CSS Grid网格布局
- 鼠标悬停时切换为2列3行(2x3)布局
- 切换过程中每个网格项要平滑移动到目标位置,鼠标移出时原路返回
- 当前实现要么是静态切换布局,要么用transform导致元素跑出网格,没法实现正确的平滑过渡
默认布局(3x2):
| 🐱 Pig | 🐦 Pidgeon | 🐢 Turtle |
| 🐟 Fish | 🐱 Cat | 🐶 Dog |
hover时布局(2x3):
| 🐱 Pig | 🐦 Pidgeon |
| 🐢 Turtle | 🐟 Fish |
| 🐱 Cat | 🐶 Dog |
解决方案
要搞定这个问题,得让网格容器尺寸稳定,同时精准算出每个元素在两种布局下的位置差,用transform补位实现平滑移动,具体代码修改如下:
HTML(保持原结构即可)
<div class="main"> <div class="root"> <div class="col"> <label>pig 🐱</label> </div> <div class="col"> <label>pidgeon 🐦</label> </div> <div class="col"> <label>turtle 🐢</label> </div> <div class="col"> <label>fish 🐟</label> </div> <div class="col"> <label>cat 🐱</label> </div> <div class="col"> <label>dog 🐶</label> </div> </div> </div>
CSS(关键修改部分)
.main { width: 80%; display: flex; justify-content: center; align-items: center; margin: 0 auto; } .root { display: grid; border: solid 1px black; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 1fr; gap: 0; width: 600px; aspect-ratio: 3/2; transition: grid-template-columns 0.3s ease; } .root:hover { grid-template-columns: repeat(2, 1fr); aspect-ratio: 2/3; } .col { border: solid 1px black; background-color: red; display: flex; align-items: center; justify-content: center; transition: transform 0.3s ease; position: relative; } /* 逐个计算每个元素的偏移量,对应目标位置 */ .root:hover .col:nth-child(1) { transform: translate(0, 0); } .root:hover .col:nth-child(2) { transform: translate(0, 0); } .root:hover .col:nth-child(3) { /* 从第1行第3列 → 第2行第1列:左移1列宽,下移1行高,抵消边框宽度 */ transform: translate(calc(-100% - 2px), calc(100% + 2px)); } .root:hover .col:nth-child(4) { /* 从第2行第1列 → 第2行第2列:右移1列宽,抵消边框宽度 */ transform: translate(calc(100% + 2px), 0); } .root:hover .col:nth-child(5) { /* 从第2行第2列 → 第3行第1列:左移1列宽,下移1行高,抵消边框宽度 */ transform: translate(calc(-100% - 2px), calc(100% + 2px)); } .root:hover .col:nth-child(6) { /* 从第2行第3列 → 第3行第2列:下移1行高,抵消边框宽度 */ transform: translate(0, calc(100% + 2px)); }
关键要点
- 用
aspect-ratio固定网格容器的宽高比例,避免布局切换时容器尺寸突变 - 计算
transform偏移时要考虑网格项的边框宽度,确保元素精准对齐目标位置 - 给
grid-template-columns和transform都加过渡动画,让容器布局切换和元素移动同步 - 网格项设置
position: relative,保证transform的偏移基于自身原始位置
内容的提问来源于stack exchange,提问作者Y-A-U-grey
相关产品推荐
相关产品推荐

