Skip to content

Implement Area Transformation by Sass For Loop

Grid Layout Animation【渡一教育】

Example: https://codepen.io/vcxldk/pen/azbqBPm

Using Sass's for loop, it is very convenient to generate multiple styles that depend on the index.

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 {
  // set each box background color based on the index
  .box:nth-child(#{$i}) {
    background-color: hsl($i * 30, 80%, 50%);
  }

  // set the container change the grid template columns and rows when the box is hovered
  // the row and column are calculated based on the index
  .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 compiled CSS code:

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;
}