Skip to content

使用Sass的for循环进行区域变换

网格布局中的动画【渡一教育】

效果示例:https://codepen.io/vcxldk/pen/azbqBPm

利用Sass的for循环,可以很方便地生成多个依赖于索引的样式。

html
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>Implement Area Transformation by Sass For Loop</title>
  </head>
  <body>
    <div class="container">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
    <link
      rel="stylesheet"
      href="./style.css"
    />
  </body>
</html>
scss
.container {
  width: 300px;
  height: 300px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  gap: 10px;

  transition: all 0.3s ease;
}

@for $i from 1 through 9 {
  // 依据索引设置每个box的背景颜色
  .box:nth-child(#{$i}) {
    background-color: hsl($i * 30, 80%, 50%);
  }

  // 当box处于hover状态时,容器变换为对应的行列属性
  // 其计算方式是根据索引的
  .container:has(.box:nth-child(#{$i}):hover) {
    $row: floor(($i - 1) / 3 + 1);
    $col: ($i - 1) % 3 + 1;
    $arr: 1fr 1fr 1fr;
    $rows: set-nth($arr, $row, 2fr);
    $cols: set-nth($arr, $col, 2fr);
    grid-template-columns: $cols;
    grid-template-rows: $rows;
  }
}

scss编译后的CSS代码:

css
.container {
  width: 300px;
  height: 300px;
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 1fr 1fr;
      grid-template-columns: 1fr 1fr 1fr;
  -ms-grid-rows: 1fr 1fr 1fr;
      grid-template-rows: 1fr 1fr 1fr;
  gap: 10px;
  -webkit-transition: all 0.3s ease;
  transition: all 0.3s ease;
}

.box:nth-child(1) {
  background-color: #e6801a;
}

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

.box:nth-child(2) {
  background-color: #e6e61a;
}

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

.box:nth-child(3) {
  background-color: #80e61a;
}

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

.box:nth-child(4) {
  background-color: #1ae61a;
}

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

.box:nth-child(5) {
  background-color: #1ae680;
}

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

.box:nth-child(6) {
  background-color: #1ae6e6;
}

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

.box:nth-child(7) {
  background-color: #1a80e6;
}

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

.box:nth-child(8) {
  background-color: #1a1ae6;
}

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

.box:nth-child(9) {
  background-color: #801ae6;
}

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