如何将CSS Grid子元素tracklist置于目标album所在行之后?
实现iTunes风格专辑网格曲目列表交互
核心思路
要实现点击专辑后,曲目列表(tracklist)显示在该专辑所在行的正下方,关键是找到当前点击专辑所在行的最后一个元素,然后将tracklist插入到这个元素之后。利用元素的offsetTop属性可以判断是否处于同一行(同一行的元素顶部偏移量一致)。
修改后的完整代码
HTML
<div id="grid-parent"></div>
CSS
#grid-parent { display: grid; grid-template-columns: repeat(auto-fill, 10rem); grid-gap: 1rem; justify-content: space-between; } .album { width: 10rem; height: 10rem; background-color: aqua; border: none; cursor: pointer; } .album:before { content: "Album cover"; } .tracklist { grid-column: 1 / -1; background-color: darkseagreen; height: 15rem; display: flex; align-items: center; justify-content: center; } .tracklist:before{ content: "Tracks here"; }
JavaScript
const parent = document.getElementById("grid-parent"); const tracklist = document.createElement("div"); tracklist.classList.add("tracklist"); parent.appendChild(tracklist); // 创建专辑元素 for (let i = 0; i < 10; i++) { const album = document.createElement("button"); album.classList.add("album"); parent.insertBefore(album, tracklist); // 先把专辑放在tracklist前面 album.addEventListener("click", (event) => { const clickedAlbum = event.target; const rowTop = clickedAlbum.offsetTop; const allAlbums = Array.from(parent.querySelectorAll(".album")); // 找到当前行的最后一个专辑 const lastInRow = allAlbums.filter(album => album.offsetTop === rowTop).pop(); // 将tracklist插入到该行最后一个元素之后 parent.insertBefore(tracklist, lastInRow.nextSibling); }); }
关键逻辑解释
- 判断同一行元素:通过
offsetTop属性获取元素相对于父容器的顶部偏移量,同一行的专辑元素这个值是相同的。 - 定位行尾元素:筛选出所有和点击专辑同
offsetTop的元素,取最后一个就是当前行的末尾元素。 - 插入tracklist:使用
insertBefore将tracklist插入到行尾元素的下一个位置,结合CSS的grid-column: 1 / -1,tracklist会自动占满整行,显示在目标行的正下方。 - 初始布局优化:创建专辑时直接插入到tracklist前面,避免初始状态下tracklist在顶部的问题。
注意事项
- 如果专辑元素有动态高度变化,需要用
getBoundingClientRect().top替代offsetTop,确保行判断的准确性。 - 可以添加选中状态样式,让用户更清楚当前选中的专辑。
内容的提问来源于stack exchange,提问作者goose_lake
相关产品推荐
相关产品推荐

