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構文を活用すれば、同じ要素がたくさん並ぶ時でも、一つ一つ計算や記述をしなくてよいから大変便利だと思います。
