scss 实现网格布局动画

效果

Wangge

实现

  • 其实就是找到鼠标进入的元素,根据父元素的:has 伪类选择器选择到该元素,动态修改父元素的 grid-template-columns 和 grid-template-rows 属性
    html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>

scss

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #ffffff;
overflow: hidden;
}

.container {
width: 400px;
height: 400px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 10px;
background-color: #f2f2f2;
border-radius: 20px;
transition: 0.5s;
}

@for $i from 0 through 8 {
//为每个item设置背景颜色
.item:nth-child(#{$i + 1}) {
//hsl 色相环
background: hsl($i * 30%, 90%, 60%);
}
//选择到父元素动态修改子元素的大小
.container:has(.item:nth-child(#{$i + 1}):hover) {
$r: floor($i/3 + 1); //1-3 行
$c: $i%3 + 1; //1-3 列
$arr: 1fr 1fr 1fr; //默认大小
//改动元素大小 set-nth(目标数组,下标,新值) 是scss函数 动态修改数组元素
$rows: set-nth($arr, $r, 2fr);
$cols: set-nth($arr, $c, 2fr);
//设置行和列大小
grid-template-columns: $cols;
grid-template-rows: $rows;
}
}

编译后的 css

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #ffffff;
overflow: hidden;
}

.container {
width: 400px;
height: 400px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 10px;
background-color: #f2f2f2;
border-radius: 20px;
transition: 0.5s;
}

.item:nth-child(1) {
background: #f53d3d;
}

.container:has(.item:nth-child(1):hover) {
grid-template-columns: 2fr 1fr 1fr;
grid-template-rows: 2fr 1fr 1fr;
}

.item:nth-child(2) {
background: #f5993d;
}

.container:has(.item:nth-child(2):hover) {
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: 2fr 1fr 1fr;
}

.item:nth-child(3) {
background: #f5f53d;
}

.container:has(.item:nth-child(3):hover) {
grid-template-columns: 1fr 1fr 2fr;
grid-template-rows: 2fr 1fr 1fr;
}

.item:nth-child(4) {
background: #99f53d;
}

.container:has(.item:nth-child(4):hover) {
grid-template-columns: 2fr 1fr 1fr;
grid-template-rows: 1fr 2fr 1fr;
}

.item:nth-child(5) {
background: #3df53d;
}

.container:has(.item:nth-child(5):hover) {
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: 1fr 2fr 1fr;
}

.item:nth-child(6) {
background: #3df599;
}

.container:has(.item:nth-child(6):hover) {
grid-template-columns: 1fr 1fr 2fr;
grid-template-rows: 1fr 2fr 1fr;
}

.item:nth-child(7) {
background: #3df5f5;
}

.container:has(.item:nth-child(7):hover) {
grid-template-columns: 2fr 1fr 1fr;
grid-template-rows: 1fr 1fr 2fr;
}

.item:nth-child(8) {
background: #3d99f5;
}

.container:has(.item:nth-child(8):hover) {
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: 1fr 1fr 2fr;
}

.item:nth-child(9) {
background: #3d3df5;
}

.container:has(.item:nth-child(9):hover) {
grid-template-columns: 1fr 1fr 2fr;
grid-template-rows: 1fr 1fr 2fr;
}