如何使用CSS Grid交换网格项并实现交换过渡效果?
问题1:布局错乱原因及修复
布局错乱的核心原因是 CSS 自定义标识符(grid-area 名称)不允许为纯数字,以数字开头的自定义标识符不符合语法规范,浏览器无法识别你定义的grid-template-areas规则,会自动生成多余的网格行/列来放置元素,最终导致布局混乱。
修复方案就是给所有 grid-area 名称加上非数字前缀,比如前缀a,修改后的CSS如下:
.container{ width: 30%; margin: auto; } .tiles-container{ display: grid; grid-template-columns: repeat(4, 1fr); /* 给所有区域名加前缀a,符合CSS命名规范 */ grid-template-areas: "a1 a2 a3 a4" "a5 a6 a7 a8" "a9 a10 a11 a12" "a13 a14 a15 a0"; width: 100%; aspect-ratio: 1/1; } /* 对应修改所有grid-area取值,和上面的命名对应 */ .tiles-container > div{ /* 瓦片基础样式,可根据需求调整 */ display: flex; align-items: center; justify-content: center; border: 1px solid #ccc; font-size: 24px; } .tiles-container > div:nth-child(1){grid-area: a10;} .tiles-container > div:nth-child(2){grid-area: a2;} .tiles-container > div:nth-child(3){grid-area: a14;} .tiles-container > div:nth-child(4){grid-area: a7;} .tiles-container > div:nth-child(5){grid-area: a8;} .tiles-container > div:nth-child(6){grid-area: a4;} .tiles-container > div:nth-child(7){grid-area: a3;} .tiles-container > div:nth-child(8){grid-area: a11;} .tiles-container > div:nth-child(9){grid-area: a15;} .tiles-container > div:nth-child(10){grid-area: a13;} .tiles-container > div:nth-child(11){grid-area: a0;} .tiles-container > div:nth-child(12){grid-area: a12;} .tiles-container > div:nth-child(13){grid-area: a6;} .tiles-container > div:nth-child(14){grid-area: a5;} .tiles-container > div:nth-child(15){grid-area: a9;} .tiles-container > div:nth-child(16){grid-area: a1;}
修改后即可正常显示4x4网格,瓦片位置也会按照你设定的规则排列。
问题2:网格项交换过渡效果实现
grid-area属性本身不支持直接过渡,要实现交换动画可以用自定义CSS变量结合@property注册可动画属性的方案,修改逻辑如下:
- 注册
--row和--col两个自定义属性,设置为可动画的整数类型 - 不用
grid-template-areas,改用grid-row-start和grid-column-start绑定这两个变量控制瓦片位置 - 给瓦片添加
transition属性,修改变量时就会自动触发过渡动画
修改后的完整CSS示例:
/* 注册可动画的自定义属性 */ @property --row { syntax: '<integer>'; initial-value: 1; inherits: false; } @property --col { syntax: '<integer>'; initial-value: 1; inherits: false; } .container{ width: 30%; margin: auto; } .tiles-container{ display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr); width: 100%; aspect-ratio: 1/1; } .tiles-container > div{ display: flex; align-items: center; justify-content: center; border: 1px solid #ccc; font-size: 24px; /* 绑定自定义变量控制位置 */ grid-row-start: var(--row); grid-column-start: var(--col); /* 加过渡效果 */ transition: --row 0.3s ease, --col 0.3s ease; } /* 给每个瓦片设置初始的行和列,对应你要的位置 */ .tiles-container > div:nth-child(1){--row:3;--col:2;} .tiles-container > div:nth-child(2){--row:1;--col:2;} .tiles-container > div:nth-child(3){--row:4;--col:2;} .tiles-container > div:nth-child(4){--row:2;--col:3;} .tiles-container > div:nth-child(5){--row:2;--col:4;} .tiles-container > div:nth-child(6){--row:1;--col:4;} .tiles-container > div:nth-child(7){--row:1;--col:3;} .tiles-container > div:nth-child(8){--row:3;--col:3;} .tiles-container > div:nth-child(9){--row:4;--col:3;} .tiles-container > div:nth-child(10){--row:4;--col:1;} .tiles-container > div:nth-child(11){--row:4;--col:4;} .tiles-container > div:nth-child(12){--row:3;--col:4;} .tiles-container > div:nth-child(13){--row:2;--col:2;} .tiles-container > div:nth-child(14){--row:2;--col:1;} .tiles-container > div:nth-child(15){--row:3;--col:1;} .tiles-container > div:nth-child(16){--row:1;--col:1;}
后续需要交换两个瓦片位置时,只需要用JS互换两个元素的--row和--col属性值,就会自动触发平滑的过渡动画。
内容的提问来源于stack exchange,提问作者sqmasep
相关产品推荐
相关产品推荐

