こんにちは! LIGフィリピン支社代表のせいとです。
最近のブログではまとめ記事中心に書いていたのですが、このまえ編集担当の朽木に「最近エンジニアっぽい記事書いてないよね。」というグサっとくる一言をもらったので、今回はそれっぽい記事を書いてみようと思います。
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);
}
一見すると「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>
↑のコードでは、以下のようなことをしています。
- あらかじめ、bodyタグにクラス”animating”があればアニメーションするようSCSSを書いておく
- あらかじめ、loading要素(#loading)を全面に表示配置しておく
- ロード完了時にloading要素をfadeOutさせると同時に、bodyタグにクラス”animating”を付与する
- loading要素が消えると同時にアニメーション発動
SCSSはちょっと長くなってしまいましたが、普通に書くよりは短く、わかりやすくなったかと思います。
まとめ
いかがでしたでしょうか。
Sassで効率的にkeyframesを記述することで、さまざまなアニメーションがシンプルに書けるようになりました。
簡単に実装できるので、どんなサイトでも入れてみたくなりますよね。ぜひ試してみてください!
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。