SCSSでfor構文を使って等間隔で動くアニメーションを作る方法
はじめに
以前「Sassでクラス名を連番で書く方法(@for構文と@if構文)」というものを紹介しました。
今回はそれの応用で、SCSSのfor
構文を使用して、等間隔で動作するCSSアニメーションを作ってみましたので、その方法を紹介します。
仕上がりイメージ
目次
等間隔で動くアニメーションを作る
for
構文についての基本は前回の投稿をご確認下さい。
今回は「等間隔で非表示(opacity: 0;
)から表示(opacity: 1;
)に切り替わるボックス」を作ってみます。
HTML
ボックスを作るだけなので、div
の中には何も記述していません。
p-box01_item
を等間隔に並べたいので、親要素でp-box01
を作り、これをFlexBoxで並べています。
<div class="p-box01"> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> <div class="p-box01_item"></div> </div>
SCSS
.p-box01 { display: flex; align-items: stretch; justify-content: center; flex-wrap: wrap; gap:10px; .p-box01_item { display: block; width: 80px; height: 80px; background: #aaa; animation-name:box01_item_animation; animation-duration: 1s; animation-fill-mode: forwards; opacity: 0; @for $box01_number from 1 through 14 { &:nth-of-type( #{$box01_number} ) { animation-delay: calc(#{$box01_number}s * 0.1); } } @keyframes box01_item_animation { 0% { opacity: 0; } 100% { opacity: 1; } } } }
SCSSが長くなってしまったので分割して説明します。
SCSS(1~6行目)
p-box01_item
要素を入れる親要素です。
.p-box01 { display: flex; align-items: stretch; justify-content: center; flex-wrap: wrap; gap:10px;
先述のとおりFlexBoxで等間隔に並べています。また、p-box01_item
の間隔はgap:10px;
としています。
SCSS(7~15行目)
主にp-box01_item
の形状について設定しています。
.p-box01_item { display: block; width: 80px; height: 80px; background: #aaa; animation-name:box01_item_animation; /*アニメーションの名前を設定(あとで使用)*/ animation-duration: 1s; /*アニメーションの動きを1秒で設定*/ animation-fill-mode: forwards; /*アニメーションが100%に達したらそこで止める*/ opacity: 0; /*初期値では要素を表示させない*/
各々のプロパティ等についてはソースに追記していますのでご確認下さい。
animation-fill-mode: forwards;
にしておかないと、アニメーションが終わった後、opacity: 0;
に戻ってしまいます。
SCSS(16~20行目)
ここが今回の本題となるfor
構文です。
@for $box01_number from 1 through 14 { &:nth-of-type( #{$box01_number} ) { animation-delay: calc(#{$box01_number}s * 0.1); } }
今回、$box01_number
と名称を付けて、p-box01_item
の個数分くりかえし処理するよう設定しています。
さらに、疑似要素nth-of-type()
と、animation-delay
にその繰り返しの数値を代入させています。
animation-delay: calc(#{$box01_number}s * 0.1);
とすることで、要素の個数が増えるごとに「〇番目の要素 × 0.1」となるように設定しています。
これをCSSに直すと以下のようになります。
CSS
.p-box01_item:nth-of-type(1) { animation-delay: 0.1; } .p-box01_item:nth-of-type(2) { animation-delay: 0.2; } .p-box01_item:nth-of-type(3) { animation-delay: 0.3; } ・ ・ ・ .p-box01_item:nth-of-type(14) { animation-delay: 1.4; }
SCSS(21~26行目)
最後はアニメーションの動きに関する処理です。
ここは本題ではないので簡単に説明しますが、opacity: 0;
からopacity: 1;
へ要素が変化することで徐々に表示されるアニメーションができます。
@keyframes box01_item_animation { 0% { opacity: 0; } 100% { opacity: 1;
これで、「p-box01_item要素の数×0.1秒」ごとに等間隔で要素が表示されるアニメーションが完成しました。
できあがったもの
おまけ
要素をウェーブさせてみました。
基本的には上の作り方と同じで、今回はopacity
ではなくtransform: translateY
を使用しています。
また、animation-iteration-count: infinite;
として、繰り返しアニメーションされるように設定しています。
HTML
<div class="c-box_normal"> <div class="p-box02"> <div class="p-box02_item"></div> <div class="p-box02_item"></div> <div class="p-box02_item"></div> ・ ・ ・ <!-- 同じものを合計23個作っています --> <div class="p-box02_item"></div> </div> </div>
SCSS
.p-box02 { display: flex; align-items: stretch; justify-content: center; flex-wrap: wrap; gap: 4px; .p-box02_item { display: block; width: 20px; height: 20px; background: #aaa; animation-name:box02_item_animation; animation-duration: .5s; animation-iteration-count: infinite; @for $box02_number from 1 through 23 { &:nth-of-type( #{$box02_number} ) { animation-delay: calc(#{$box02_number}s * 0.1); } } @keyframes box02_item_animation { 0% { transform: translateY(0); } 50% { transform: translateY(10px); } 100% { transform: translateY(0); } } } }
できあがったもの
SCSSのfor構文を活用すれば、同じ要素がたくさん並ぶ時でも、一つ一つ計算や記述をしなくてよいから大変便利だと思います。