• このエントリーをはてなブックマークに追加

【CSSアニメーション】ちょっと変わったテキストエフェクトをつくってみた

 こんにちは。ニジボックスでフロントエンドエンジニアをやっております、門脇と申します。

 さて、今回取り上げたいのはCSSアニメーションです。
 言わずもがな、ブラウザ上の要素を消したり現したり動かしたりといったアニメーションには欠かすことのできない技術です。
 しかし、欠かすことができないということは、いっぽうで基本的な使い方が既に定まっているということでもあるわけです。CSSには様々なプロパティが用意されているにも関わらず、実装の際にはごく限られた使い方になってしまう、これはもったいないことです。
 そういうわけで、今回、普段あまり使われないCSSのプロパティを使用したテキストエフェクトを自作してみました。CSSアニメーションで実装できるエフェクトの簡単な解説とともに、ご紹介したいと思います。

フェードイン

 CSSアニメーションで頻繁に使用されるエフェクトといえば、やはりフェードインでしょう。フェードインとは何ぞやという方のために、試しにサンプルをつくってみました。

 何もないところから要素がゆっくりと現れます。これがベーシックな形のフェードインです。
 CSSアニメーションは一般的に、@keyframesを使用して実装されます。
 特定の要素にanimationプロパティを指定し、@keyframesで設定したアニメーションを呼び出すことで、アニメーションが可能になります。
 今回つくったのは、margin-topの値を徐々に小さくしながら、opacity0から1に近づけていくアニメーションです。この2つの指定だけで、下からフワッと要素が登場するアニメーションを実装できます。
 サンプルでは擬似クラスの:focusを使用し、クリックしたときにアニメーションが開始されるよう設定しているのですが、例えば、JavaScriptで現在のスクロール位置に応じて要素にクラスを付与する等の処理をするだけで、スクロールするたびに要素が現れるというアニメーションを実装することができます。こちらは多くのウェブサイトで実装されているものですね。

 さて、CSSのプロパティには、普段あまり使われないものも多くあります。
 単に要素が現れるばかりでなく、もっと迫力ある登場ができないものかと思いまして、試しに文字が目の前を駆け抜けるようなエフェクトをつくってみましたので、ご紹介いたします。

 文字がすぐ目の前を横切って、駆け抜けていくようなアニメーションができました。
 サンプルでは、transform:perspective(200px)を使用しています。
 transform:perspective()は、要素の奥行きを指定するプロパティで、これによって遠近感を表現することができます。さらにtransform:rotateX(85deg)で、divを奥に85度傾け、地平線に見立てます。つぎに、divのなかのspanを逆にtransform:rotateX(-85deg)傾けることで、文字が真っ直ぐに立っている状態を表現します。そして、@keyframesで設定したアニメーションで、spanの位置を移動させながらdivtranform:rotate()で回転させる、という手順になっています。
 動きとしては単純なものですが、奥行きを与えることで、手軽に臨場感を出すことができます。
 ところで、要素を拡大したり傾けたり移動したりといった操作でしばしば使用されるtransformプロパティですが、こちらには複数の値を指定できます。
 サンプルではtransform:perspective(200px) rotateX(85deg) rotate(120deg)のように指定していますが、描画は記述の順、つまり左から順番に行われます。順番を変えると全く違った表示になってしまうことがありますので、注意が必要です。

フェードアウト

 フェードインとともに、頻繁に使用されるCSSアニメーションといえば、フェードアウトです。テキストがゆっくり消えていくようなアニメーションも、CSSで手軽に実装することができます。
 これもまた例によって、サンプルをつくってみました。

 先程のフェードインに、少々手を加えたものです。
 今回は、擬似クラスの:hoverを使用して、ポインタが要素の上にある場合に、要素が徐々に消えていくというエフェクトを実装しています。
 コードを見ていただければわかるのですが、@keyframesを使用せず、その代り、transitionプロパティでアニメーションの指定をしています。
 transitionは、要素に変化があった場合、その変化に関するアニメーションを指定するプロパティです。とくに複雑なアニメーションを実装しようとしない限りは、transitionを使用するほうが手軽ですし、コードもシンプルになります。
 サンプルでは、擬似クラス:hoverに、transform:scale(1.5)と、opacity:0を指定しています。簡単にいえば、1.5倍に拡大しながら消えていく、というアニメーションです。こちらはモーダル・ウインドウなどでしばしば使用されるものですね。

 さて、単に消えていくだけでは物足りないので、ここでも自作のエフェクトをご紹介したいと思います。消えていく過程を、もっとじっくり見せることができないかと、私が考えましたのが光学迷彩です。
 光学迷彩というのは、一般的にはカメレオンの擬態のようなもの、つまり外部の環境に徐々に溶け込んでいくような状態を指します。
 それをどうにかCSSで再現できないかと思いまして、つくってみました。

 マウスをホバーすると、テキストが光学迷彩のように消えていきます。
 今回は、background-clip:textを活用しました。
 こちらのプロパティは、backgroundで指定した背景画像もしくは背景色を、テキストの形にくり抜くというものです。colortransparentを指定し透過させることで、テキストの形の背景をつくることができます。
 まずはじめに、まったくおなじ大きさの親要素と子要素を用意します。そしてこれらにおなじ背景画像を指定し、background-clip:textを指定した子要素のbackgroundのみをアニメーションさせることで、光学迷彩のように、テキストがゆっくりと溶け込んでいく表現を可能にしています。
 見ていただければわかるのですが、アニメーションは二段階にわかれています。
 1、テキストの末端から消えていく。
 2、透過した文字が外部に溶けこむ。
 子要素のbackground-imageにはradial-gradient()で作成した黒い楕円と、親要素に指定した背景画像のふたつを重ねています。1で、楕円を徐々に小さくしていき、2で、あらかじめ拡大しておいた背景画像を等倍に近づけていく、という手法をとっています。
 ただ、難点を挙げれば、background-clip:textは、今のところ(2018年3月現在)Internet Explorerには対応していません(そもそもベンダープレフィックス無しでは、どのブラウザでも動きません)。
 IEで見ると、ただ背景がごちゃごちゃ動いているだけになってしまうので、 汎用的な使用には向きませんが、アイデア次第で変わった使い方ができるプロパティです。

おわりに

 これまで見てきたように、CSSアニメーションは多様な使い方ができるものですが、いざ実装するとなると、ごく限られた使い方になってしまうのが実際のところです。
 しかしながら、こうしてエフェクトをつくってみると、普段目を向けていないだけで、CSSには色んな使い方があるものだと思いますね。
 まだまだ学ぶことは、たくさんありそうです。