最终效果概述
- 页面为 3x3 的彩色格子网格;
- 当鼠标悬停任意格子,所在的行和列被放大;
- 使用纯 CSS 实现,无需 JavaScript;
- 利用 SASS 的模块能力大幅减少冗余代码。
HTML 结构
我们使用非常基础的结构,9 个 .item
放在 .container
容器中:
<!DOCTYPE html>
<html lang="zh-CN">
<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>
SASS + CSS Grid 样式详解
1. 设置基本布局
body {
background-color: #23262d;
}
.container {
width: 480px;
height: 400px;
margin: 50px auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 10px;
transition: 0.5s;
}
我们为 .container
设置了一个固定尺寸的 3x3 网格,并加了 transition
来实现动画过渡。
2. 为每个格子设置不同颜色
@for $i from 1 through 9 {
.item:nth-child(#{$i}) {
background: hsl($i * 40deg, 100%, 60%);
}
}
利用 HSL 色彩空间,我们为每个格子设置了不同色相,让它们具有渐变的彩虹效果。
3. 交互式动态布局(核心逻辑)
@use "sass:list";
@use "sass:math";
@for $i from 1 through 9 {
.container:has(.item:nth-child(#{$i}):hover) {
$r: math.floor(math.div($i - 1, 3) + 1);
$c: ($i - 1) % 3 + 1;
$arr: 1fr 1fr 1fr;
$rows: list.set-nth($arr, $r, 2fr);
$cols: list.set-nth($arr, $c, 2fr);
grid-template-columns: $cols;
grid-template-rows: $rows;
}
}
解释一下这段代码的巧妙之处:
@for
循环处理每一个.item
;- 通过 SASS 的数学模块计算出第几个格子对应的行($r)和列($c);
- 使用
list.set-nth()
将第 $r 行和第 $c 列的比例设为2fr
,其他保持1fr
; - 利用
:has()
选择器监听每个格子的hover
状态,进而修改.container
的布局。
完整代码
index.scss
@use "sass:list";
@use "sass:math";
body {
background-color: #23262d;
}
.container {
width: 480px;
height: 400px;
margin: 0 auto;
margin-top: 50px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 10px;
transition: 0.5s;
}
@for $i from 1 through 9 {
.item:nth-child(#{$i}) {
background: hsl($i * 40deg, 100%, 60%);
}
// 选择子元素,更改父元素:当容器的子元素被鼠标移入时,父元素样式生效
.container:has(.item:nth-child(#{$i}):hover) {
// 移入某个子元素时,改变父元素的行列比例
$r: math.floor(math.div($i - 1, 3) + 1);
$c: ($i - 1) % 3 + 1;
$arr: 1fr 1fr 1fr;
$rows: list.set-nth($arr, $r, 2fr); // 将第 $c 行的宽度改为 2fr
$cols: list.set-nth($arr, $c, 2fr); // 将第 $c 列的宽度改为 2fr
grid-template-columns: $cols;
grid-template-rows: $rows;
}
}
总结
技术点 | 说明 |
---|---|
CSS Grid | 实现基本的行列布局和比例控制 |
SASS 循环 + 模块 | 自动生成 9 套不同的布局规则 |
:has() 选择器 |
CSS4 的新特性,实现“父级根据子级状态变化” |
transition |
平滑过渡布局变化 |
浏览器兼容性提示
:has()
是一个 CSS4 选择器,目前主流浏览器如 Chrome、Edge 和 Safari 已支持,但 Firefox 仍不支持(截至 2025 年)。部署到生产环境前,请根据用户群体权衡。