keyframes(CSS3)とSassでイケてるアニメーションをシンプルなコードで実装する方法


keyframes(CSS3)とSassでイケてるアニメーションをシンプルなコードで実装する方法

こんにちは! フロントエンドエンジニアのせいとです。
最近のブログではまとめ記事中心に書いていたのですが、このまえ編集担当の朽木に「最近エンジニアっぽい記事書いてないよね。」というグサっとくる一言をもらったので、今回はそれっぽい記事を書いてみようと思います。

keyframes(CSS3)とSassでイケてるアニメーションをシンプルなコードで実装する方法

はじめに

モダンブラウザでは、CSS3のanimationプロパティ、@keyframesの2つを使ってイケてるアニメーションがJS抜きで実装できます。
そいつあすごいぜって話なんですが、1つ心配なことが。
それは、アニメーションのバリエーションが複数ある場合、コード量が長くなりがちという問題。
ただでさえ各ブラウザのベンダープレフィックス付ける必要があるので、その上アニメーションパターンをいくつも書こうとしたらもう…(´Д`)

実践その1

というわけで、Sassを使って簡潔に書くことにしましょう。
試行錯誤を繰り返し、いろんなサイトにインスパイアされた結果、私が辿り着いた書き方は以下の3つを守ることです。

1. @mixin,@contentでkeyframesの関数を用意する

@mixin keyframes($animation-name) {
  @-webkit-keyframes $animation-name {
    @content;
  }
  @-moz-keyframes $animation-name {
    @content;
  }  
  @keyframes $animation-name {
    @content;
  }
}

2. @mixinでanimationプロパティの関数を用意する

@mixin animation($animation-name) {
  -webkit-animation: $animation-name;
  -moz-animation: $animation-name;
  animation: $animation-name;
  -webkit-animation-fill-mode: both;
  -moz-animation-fill-mode: both;
  animation-fill-mode: both;
}

3. 1,2で用意した関数を使ってアニメーションを書く

@include keyframes(animationSample){
	0% {
		opacity:0;
	}
	100% {
		opacity:1;
	}
}

#hoge{
	@include animation(animationSample 1.2s ease 0.15s);	
}

これらの実行結果がこちら↓です。(※アニメーションに直接関係ないHTMLやCSSは省きました)

一見すると「opacityいじってるだけの割に記述量長くねえ?」と思われるかもしれません。
ただ、バリエーションがたくさんある場合は最初に1,2の@mixinを記述しておけば、後は3のような記述を書くだけなので楽ができるはずです。
また、このようなやり方だと、いろんなバリエーションが出せるようになります。

そのサンプルを2つほど挙げてみたいと思います。

実践その2

今度は先ほどの正方形を10個用意して、連続で透明度を変えてみます。

@for $i from 1 through 10{
	$DELAY: $i * 0.15s;
	@include keyframes(animationFadeIn#{$i}){
		0% {
			opacity:0;
		}
		100% {
			opacity:1;
		}
	}

	#demo2>li:nth-child(#{$i}){
		@include animation(animationFadeIn#{$i} 1.2s ease $DELAY);	
	}
}

上記の例ではfor文を使って同じ処理を繰り返してます。
ただしその際、変数$iを使って微妙にdelayの値をズラすことで、連続してアニメーションを発生させています。

せっかくなので、opacity以外のプロパティも入れて動きをちょい工夫してみます。

@for $i from 1 through 10{
	$DELAY: $i * 0.1s;
	
	@include keyframes(animationFloat#{$i}){
		0% {
			opacity: 0; 
			-webkit-transform: translateY(100%);
			transform: translateY(100%);
		}
		100% {
			opacity: 1;
			-webkit-transform: translateY(0);
			transform: translateY(0);
		}
	}

	#demo3{
		>li{
			&:nth-child(#{$i}){
				@include animation(animationFloat#{$i} 1.6s ease $DELAY);
			}
		}
	}
}

上記の例ではデモ2のスタイルにさらにtranslateYを追加して、要素が下からふわっと上がってくるようにしています。

実践その3

最後はJSもちょっと書きつつ、複数のkeyframesを使ってロード時のアニメーションっぽいものを作ってみようと思います。

SCSS

@include keyframes(animationLayoutY){
	0% {
		opacity: 0;
		-webkit-transform: translateY(-30px);
		transform: translateY(-30px);
	}
	100% {
		opacity: 1;
		-webkit-transform: translateY(0);
		transform: translateY(0);
	}
}
@include keyframes(animationLayoutX){
	0% {
		opacity: 0;
		-webkit-transform: translateX(30px);
		transform: translateX(30px);
	}
	100% {
		opacity: 1;
		-webkit-transform: translateX(0);
		transform: translateX(0);
	}
}
.animating{
	#header{
		@include animation(animationLayoutY 1s ease 0.5s);
	}
	#nav{
		@include animation(animationLayoutY 1s ease 0.6s);
	}
	#side{
		@include animation(animationLayoutX 1s ease 0.7s);
	}
	#main{
		@include animation(animationLayoutX 1s ease 0.8s);
	}
	#footer{
		@include animation(animationLayoutY 1s ease 0.9s);
	}
}

JS

$(function(){
	$(window).one('load', function() {
	    $('#loading').fadeOut(1000);
		$('body').addClass('animating');
	});
});

HTML

<body>
    <div id="loading"><span>Loding...</span></div>
    <header id="header"><!--省略--></header>
    <nav id="nav"><!--省略--></nav>

    <div id="contents">
        <div class="container">
            <div id="main"><!--省略--></div>
            <aside id="side"><!--省略--></aside>
        </div>
    </div>

    <footer id="footer"><!--省略--></footer>

    <script src="./js/jquery.js"></script>
    <script src="./js/common.js"></script>
</body>

↑のコードでは、以下のようなことをしています。

  1. あらかじめ、bodyタグにクラス”animating”があればアニメーションするようSCSSを書いておく
  2. あらかじめ、loading要素(#loading)を全面に表示配置しておく
  3. ロード完了時にloading要素をfadeOutさせると同時に、bodyタグにクラス”animating”を付与する
  4. loading要素が消えると同時にアニメーション発動

SCSSはちょっと長くなってしまいましたが、普通に書くよりは短く、わかりやすくなったかと思います。

まとめ

いかがでしたでしょうか。
Sassで効率的にkeyframesを記述することで、さまざまなアニメーションがシンプルに書けるようになりました。
簡単に実装できるので、どんなサイトでも入れてみたくなりますよね。ぜひ試してみてください!

この記事を書いた人

せいと
せいと フロントエンドエンジニア 2012年入社
最近フロントエンドエンジニアになりました。
第一回HTML5カルタ大会で優勝しました。
休日の過ごし方は、"Jazz Barでスコッチを片手に『世界の終りとハードボイルド・ワンダーランド』を読む"です。