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