Sassでfor文を使ったページローダーのようなものを作る方法

##はじめに
Sass記法にはなんと**for文**も存在するということで、どういう使い方をするのか一例としてページローダーのようなものをCSSで表現してみたいと思います。
Sassでは他にも**if文**なんかも使えます。

Sassと言ってますが、基本的にはscss記法で書いていきます。そちらの方が個人的には見やすいので。

この記事ではSassについての詳しい解説は行いません。

##ちなみに
[SassMeister](https://www.sassmeister.com/)というサイトで、CSSにコンパイルされた記述も同時に見ながらコードを書くことができるので、サクッと書いてみたい場合はこちらが便利です。
![スクリーンショット 2020-03-29 16.56.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/4c136e96-c395-2942-eb14-88980575dc1f.png)
左のSassのスペースにSassまたはscss記法で書いていくと、CSSのスペースに表示されます。

##Sassのfor文の記載方法

基本的な書き方

```scss:scss
@for $i from 1 through 5 {
  nth-child(#{$i}) {
    animation-delay: -0.3s / $i ;
  }
}
```
`@for`でfor文の宣言をし、`$i`で可変する数字部分の変数宣言を行います。ここまでは一般的なfor文とほぼ変わりません。
`from 1``through 5`で1〜5までをループするという意味になります。
で、そのnth-child（）のカッコ内に変数宣言をした`$i`を入れてあげます。
**セレクター内や、文字列内に変数を使う場合**は`#{}`で変数を囲む必要があります。
プロパティの値にその変数を使用する場合はそのまま使えます。

```scss:scss
@for $i from 1 to 5 {
  nth-child(#{$i}) {
    animation-delay: -0.3s / $i ;
  }
}
```
ちなみに`from 1``to 5`という書き方をすることもでき、こちらは**5を抜いた1〜４まで**という意味になります。


##ページローダーっぽいやつの作り方
Sassのfor文と、animationプロパティを用いて作っていきます。

さっそくですが、こんな感じのやつです。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="fumu238" data-slug-hash="oNXJRPr" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="oNXJRPr">
  <span>See the Pen <a href="https://codepen.io/fumu238/pen/oNXJRPr">
  oNXJRPr</a> by fumu (<a href="https://codepen.io/fumu238">@fumu238</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


以下、簡単な解説。

```html:html
<div class="three-dot">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>
```
htmlは特になんてことないですね。ローダー部分の要素となるdivを4つ作り、親要素の中に入れておきます。

```scss:scss
.three-dot {
    text-align: center;

    & div{
        display: inline-block;
        width: 18px;
        height: 18px;
        background-color: black;
        border-radius: 50%; 
        animation-name: delay;
        animation-duration: 1.4s;
        animation-iteration-count: infinite;
    }
}
```
まず4つの子要素を`display:inline-block`で横並びにし、黒い●状にします。
これにあとは動きをつけるために

```scss:scss
@keyframes delay {
    0% {
        transform: scale(0);
    }
    40% {
        transform: scale(1);
    }
    80% {
        transform: scale(0);
    }
    100% {
        transform: scale(0);
    }
}
```
`@keyframes`を使用して指定をしていきます。0%〜100%までの中でどような変化をするか%を指定して細かく指定できます。
ここでは`transform:scale()`を用いて0%~40%で開いて、あとは閉じる。みたいな動きにします。

`animation-name`で`@keyframes`の名前を指定し、`animatino-duration`で何秒かけてその動作を行うか指定し、`animation-iteration-count: infinite;`でそれを無限に行うように指定します。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="fumu238" data-slug-hash="eYNbwvX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="eYNbwvX">
  <span>See the Pen <a href="https://codepen.io/fumu238/pen/eYNbwvX">
  eYNbwvX</a> by fumu (<a href="https://codepen.io/fumu238">@fumu238</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

そうすると、この段階では4つの●が同時にちっちゃくなったり大きくなったりします。
ここでfor文の出番です。

```scss:scss
.three-dot {
    text-align: center;

    & div{
        display: inline-block;
        width: 18px;
        height: 18px;
        background-color: black;
        border-radius: 50%; 
        animation-name: delay;
        animation-duration: 1.4s;
        animation-iteration-count: infinite;

        @for $i from 1 through 3 {
            &:nth-child(#{$i}) {
                animation-delay: -0.4s + $i * 0.1;
            }
        }
    }
}
```
**子要素のdivのn番目**にそれぞれCSSを追加するための`:nth-child`でfor文を作ります。
今回は4つdivがあるので、その1〜3つめに`animation-delay`をマイナスの値で設定します。マイナスでdelayを設定すると、delayせずむしろ早く変化を始めることになります。
そしてその設定した値を変数を使って計算すると

ループの1回目は`-0.4s + 1 * 0.1 = -0.3s`
ループの2回目は`-0.4s + 2 * 0.1 = -0.2s ...`

となり、数が増えるたびに値が変わっていくことになります。

CSSにコンパイルされるとこう。

```css:css
nth-child(1) {
    animation-delay: -0.3s;
}
nth-child(2) {
    animation-delay: -0.2s;
}
nth-child(3) {
    animation-delay: -0.1s;
}
```

これで0.1秒ごとに変化をつけることができるようになり、見本のような動きになります。

ちなみに。for文の中で計算を行いましたが、Sassで四則演算を行うときには**単位を気にせず計算**することができます。
`px`なんかも単位をつけたまま計算することができるので、余計な事を考えなくて済みますね。

##おわりに
以上、Saasでfor文を使ったページローダーっぽいものの作り方でした。
他にもtransformを使って回転させたり、丸ではなく四角で作ったり、要素を重ねたりと、いろんなパターンが作れそうです。