网格布局中可折叠行的过渡动画同步优化问题
解决Grid布局整行同步折叠/展开的过渡动画异常问题
问题背景
使用Grid布局展示多行内容,每行包含图片、标签、SVG三列,需要实现整行的隐藏/显示切换。当前方案已解决元素居中,但过渡动画存在以下问题:
- 内容与网格移动速度不一致
- 图片、文本、SVG各自独立消失
- 行的收尾部分消失方向相反
需要修改实现整行同步折叠的效果。
解决方案
核心思路是移除子元素的独立动画,让行的高度过渡成为唯一的动画驱动源,利用行的overflow:hidden属性自然裁剪内容,实现整行同步的折叠/展开效果。
修改后的代码
JavaScript(无需修改)
function toggleRow() { const i = d3.select('#row').property('value'); const row = d3.select('.grid-row:nth-child(' + i +')'); row.classed('visible', !row.classed('visible')); }
CSS(关键修改)
:root { --transitionLength: 0.4s; --transitionTiming: ease; } .grid { display: inline-grid; grid-template-columns: 110px minmax(200px, max-content) 1fr; row-gap: 5px; } .grid-row { display: grid; grid-template-columns: subgrid; grid-template-rows: 0fr; grid-column: 1 / 4; align-items: center; column-gap: 10px; overflow: hidden; background-color: lightgray; /* 仅保留行的高度过渡,作为唯一动画源 */ transition: grid-template-rows var(--transitionLength) var(--transitionTiming); } .grid > .visible { grid-template-rows: 1fr; } /* 移除子元素的独立动画,让行的overflow:hidden自然控制显示 */ .grid-item { min-height: 0; } /* 确保图片和SVG不会超出容器 */ .grid-item img, .grid-item svg { display: block; max-width: 100%; height: auto; }
HTML(无需修改)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script> <div class="grid"> <div class="grid-row visible"> <div class="grid-item img"><img src="https://picsum.photos/100" alt="Placeholder Image"/></div> <div class="grid-item label"> <h2>Can be a long Line with several words...</h2> </div> <div class="grid-item svg"> <svg xmlns="http://www.w3.org/2000/svg" width="163.63" height="100" viewBox="0 0 18 11"> <rect width="18" height="11" fill="#fff" /> <path d="M0,5.5h18M6.5,0v11" stroke="#002F6C" stroke-width="3" /> </svg> </div> </div> <div class="grid-row"> <div class="grid-item img"><img src="https://picsum.photos/100" alt="Placeholder Image" /></div> <div class="grid-item label"> <h2>...or very short</h2> </div> <div class="grid-item svg"> <svg xmlns="http://www.w3.org/2000/svg" width="163.63" height="100" viewBox="0 0 18 11"> <rect width="18" height="11" fill="#fff" /> <path d="M0,5.5h18M6.5,0v11" stroke="#002F6C" stroke-width="3" /> </svg> </div> </div> </div> <br> <input type="number" id="row" name="number" min="1" max="3" value="1" /> <button onclick="toggleRow()">Toggle Row</button>
修改说明
- 移除子元素的独立动画:删除了
.grid-item的transform、visibility及相关过渡属性,避免子元素和行的动画冲突,让行的高度变化成为唯一的动画控制源。 - 利用行的overflow:hidden裁剪内容:当行的
grid-template-rows从1fr变为0fr时,行的高度会平滑收缩,内部内容会被overflow:hidden自然裁剪,实现整行同步折叠的效果。 - 优化媒体元素显示:添加了图片和SVG的样式,确保它们不会超出容器,避免布局错乱。
内容的提问来源于stack exchange,提问作者thothal
相关产品推荐
相关产品推荐

