簡単CSSアニメーション&デザイン20選(ソースコードと解説付き)

537,251View
酒井琢郎のプロフィール画像
エンジニア酒井琢郎

CSSは使いようによっては様々な表現が可能な奥深い言語です。しかし、アニメーションなど凝った動きをするものに関してはコードは見れても実装方法を詳しく解説している記事は多くないように思えます。

この記事では、私(さかっちょ)がTwitterで過去にツイートしたCSSの技術をCodePenで改めて実装し、Twitterでは解説しきれなかった実装方法をより詳しく説明しています。CSS初学者の方にもわかりやすいように解説していますので、ぜひ参考にしてみてください。

その1. 一文字ずつ登場するテキストアニメーション

See the Pen [CSS Tips] Text Show-up Motion by Takuro Sakai (@sakaccho) on CodePen.

一文字ずつtransformで移動させています。文字が途切れることなく流れるようにtransition-delayを調整するのがポイントです。

文字はそれぞれ<span>でくくり、親要素.titledisplay: flex;を指定して横並びにします。半角スペースは&nbsp;で対応します。

.title span {
  display: block;
  transform: translate(0, 105%);
  transition: transform cubic-bezier(0.215, 0.61, 0.355, 1) 0.5s;
}

<span>は通常時にtransform: translate(0, 105%);で下に移動させておきます。Y方向に「105%」としているのは「100%」だと文字の上端がはみ出て見えてしまうので少し多めに移動させています。ただし、この移動幅を大きくしすぎるとイージングの緩急が見えなくなってしまうので注意が必要です。

.title span:nth-child(2) {
  transition-delay: 0.06s;
}
.title span:nth-child(3) {
  transition-delay: 0.12s;
}
...

<span>ごとにtransition-delayを設定して0.06秒ずつ登場を遅延させます。Sassの場合は以下のように@forを使うと良いです。

.title span {
  @for $i from 1 through 13 {
    &:nth-child(#{$i + 1}) {
      $delay: $i * 0.06 + s;
      transition-delay: $delay;
    }
  }
}

最後に、.titie.-visibleクラスがついたらtransformの値をもとに戻します。

その2. スライドで登場するテキストアニメーション

See the Pen [CSS Tips] Text Slide Motion by Takuro Sakai (@sakaccho) on CodePen.

スライドのアニメーションは、親要素と子要素が同じ速度で逆に移動することで、移動が相殺されるのを利用して実装します。

親と子で逆方向に移動させるので要素は二重にします。通常時にtransformで親要素.titleを左へ100%、子要素<span>を右へ100%移動します。親要素が左にずれますが、子要素も同じ分だけ右にずれるので文字は元の位置にあります。ただし、親要素のoverflow: hidden;によって子要素は見えなくなっています。

TEXT ANIMATION

登場させるときに.-visibleクラスをつけ、transform: translate(0, 0);で元の位置に戻します。反対の位置にいる両者が元の位置に戻ろうとすることで動作が相殺され、あたかもその場で文字がスライドして表示されるように見えます。

その3. 幕のように背景が上がるアニメーション

See the Pen [CSS Tips] 幕のように背景が上がるアニメーション by Takuro Sakai (@sakaccho) on CodePen.

上がってくる背景は:beforeposition: absolute;で要素いっぱいにして表示します。なお初期位置はtransform: translate(0, 100%);で自分自身の高さ分、下に移動して隠します。

.-visibleが付与されたときにtransform: translate(0, 0);で元の位置に戻すことで上がってくるような動作を実現できます。上記では連動してテキストも表示していますが、それぞれ表示タイミングをtransition-delayで数ミリ秒遅らせています。気持ちの良い登場アニメーションにするには、このような連動するタイミングの調整が重要になってきます。

その4. テキストを蛍光ペンでハイライト

See the Pen [CSS Tips] 蛍光ペン by Takuro Sakai (@sakaccho) on CodePen.

テキストを蛍光ペンでハイライトするCSSです。ハイライトしたい部分を<span>でくくり、backgroundにグラデーションを指定することで実現しています。

backgroundにはlinear-gradient(transparent 40%, yellow 40%)という値を指定しています。これは下図のように「上から下方向にかけて0~40%部分は透明、40~100%は黄色」という内容です。黄色いエリアを縮めたり拡げたりしたい場合はこのパーセンテージを変更してください。inline要素なので、行の折り返しにも対応していて使い勝手の良いパーツです。

背景にグラデーション指定したときの配分イメージ

その5. 別窓アイコン

See the Pen [CSS Tips] 別窓アイコン by Takuro Sakai (@sakaccho) on CodePen.

画像を使わずにCSSのみで実装します。ブロック要素を1つ用意し、:before:afterを使用します。

いずれもposition: absolute;で配置しborderで線を描画します。:beforeには四角形を、:afterには右辺と底辺のみ描画してL字にし、:beforeに重ならないように位置調整して完成です。四角形の中抜きなどは透過状態なので、どんな背景色のページにも使用可能です。

その6. 矢印アイコン

See the Pen [CSS Tips] 矢印アイコン by Takuro Sakai (@sakaccho) on CodePen.

矢印もCSSだけで作成できます。こちらもblock要素で40pxの正方形を作成し、borderで右辺と底辺に線を描画します。最後にtransform: rotate(45deg);で45度傾けます。要素の大きさや線の太さは、使う場所に合わせて適宜変更してください。

<a>タグの中でリンクテキストの横に置くことが多いので、display: inline-block;にしておくと扱いやすいでしょう。

その7. ローディングアイコン

See the Pen [CSS Tips] ローディングアイコン by Takuro Sakai (@sakaccho) on CodePen.

色違いのbox-shadowを8種類設定し、animationをパラパラ漫画の要領で指定して再現します。

まずはbox-shadowのもとになる15pxの真円を作成します。そこに以下のようにカンマ区切りでbox-shadowを色違いで指定しましょう。コメントアウトの通り、8つの方角に配置されるようにXとYの位置を指定しています。くっきりした影にしたいので広がりの値は0にします。影だけ利用し、最初に作成した円要素は見えない状態のまま、ということですね。

box-shadow:
  0 -30px 0 #eee,     /*  上  */
  21px -21px 0 #ddd,  /* 右上 */
  30px 0 0 #ccc,      /*  右  */
  21px 21px 0 #bbb,   /* 右下 */
  0 30px 0 #aaa,      /*  下  */
  -21px 21px 0 #999,  /* 左下 */
  -30px 0 0 #666,     /*  左  */
  -21px -21px 0 #000; /* 左上 */

最後に、animation: rotate 1s steps(8) 0s infinite;でアニメーションを設定します。「rotate」という@keyframesを1秒間で繰り返し再生します。ここでsteps(8)という値を設定していますが、これはanimation-timing-functionの値で、(n)で指定した回数でアニメーションを等分して実行するというものです。つまり「rotate」を8等分にして、0%のときに0度、12.5%のときに45度の位置...のようにアニメーションが実行され、8コマのパラパラ漫画となるのです。

その8. ファイルアップロードのボタンカスタマイズ

See the Pen bGBwgyb by Takuro Sakai (@sakaccho) on CodePen.

ファイルアップロードのUIはデフォルトの「ファイルを選択」や「選択されていません」という文言(Google Chromeの場合)を変更できません。これらを任意のデザインに変更するには<input>を非表示にし、<label>を活用します。

input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
}

ただし、単純にdisplay: none;visibility: hidden;などで非表示にしてしまうと、スクリーンリーダーなどの音声読み上げ時に読み上げられない可能性があるので、以下のようにclipで1pxの正方形に切り抜き、擬似的に見えなくする方法を用います。position: absolute;clipプロパティを有効化するために指定しています。

その9. ラジオボタンのアニメーション

See the Pen [CSS Tips] ラジオボタン by Takuro Sakai (@sakaccho) on CodePen.

クリックされたら中心から拡大するアニメーションでチェック状態になるラジオボタンです。こちらも仕組みは前出のチェックボックスと同様で、<input>を非表示にして<label>の疑似要素でカスタマイズしています。

チェック状態の黄色い丸は、デフォルトでtransform: scale(0);で拡大率0%にします。今回はtransform-originの設定をしていないので中心が基準となります。

input:checked + label:after {
  transform: scale(1);
}

チェックがついたときにscale(1)に戻すことで中心から拡大するアニメーションとなります。

その10. チェックボックスのアニメーション

See the Pen oNYzBQq by Takuro Sakai (@sakaccho) on CodePen.

ペンで書いたようにチェックマークを表示するアニメーションです。デフォルトのままでは色や形をカスタマイズできないので、先程紹介した方法で<input>を非表示にし、<label>とその疑似要素でチェックボックスを再現しています。

まず<label>の左側にpaddingをとり、:beforeでグレーの枠線、:afterでチェックマークを作成します。どちらもposition: absolute;で配置しましょう。<input>にチェックが入ったときのスタイルは下記のようにinput:checkedに隣り合うlabelで指定します。

input:checked + label:before {
  background-color: #074DBF;
  border-color: #074DBF;
}

input:checked + label:after {
  transform: rotate(-45deg) scaleX(1);
}

チェックマークのアニメーションですが、transformscaleX(0)でX方向だけに伸び縮みさせることで実現しています。また、デフォルトだと拡大の起点は中心になってしまうため、transform-origin: left;で起点を左端にします。チェックマークを-45度傾けているため、左下から右上にかけて元の形に戻りながら登場します。スローで再生した下図を見ていただくとわかりやすいと思います。

チェックマークが表示されるところをスローで再生した画像

その11. Flexで上下位置を揃える

See the Pen [CSS Tips] Flexで上下位置を揃える by Takuro Sakai (@sakaccho) on CodePen.

画像やテキストを横並びに配置して、上下位置を中央にしたいこと、よくありますよね。Flexを使えばかんたんに実現できます。

上の例では<div>の中に<img>とテキストを入力した<span>を並べていますが、親<div>をflexにしてalign-items: center;を指定するだけで自動で上下中央に配置してくれます。例えば、右の文字が複数行で画像より高さをとるようになっても、自動的に上下中央を維持してくれます。なにより、子要素にレイアウトに関するスタイルを何も指定しないのがシンプルで良いですよね。

その12. paddingで正方形

See the Pen WNovxRE by Takuro Sakai (@sakaccho) on CodePen.

ブラウザ幅を変えても常に正方形を維持します。webサイトをコーディングしていると案外使う機会が多いので知っていると便利です。

HTMLは二重構造で、子要素spanbackground-imageで画像を指定します。<span>の代わりに擬似要素を用いても問題ありません。

.image {
  width: 25%;
  margin: 0 2%;
}

.image span {
  display: block;
  width: 100%;
  padding-top: 100%;
  background-image: url(画像パス);
  background-size: cover;
}

親要素.imageに幅を%で、そして子要素<span>padding-top: 100%;を指定します。こうすることでpadding-topは親の幅を基準にして設定されるので正方形になります。また、指定するpadding-topの値を工夫すれば任意の縦横比を保つことができます。たとえば、calc(100% / 16 * 9)と指定すれば16:9の縦横比になります。

その13. column-countで上→下配置

See the Pen [CSS Tips] column-countで上→下配置 by Takuro Sakai (@sakaccho) on CodePen.

CSSの横並びレイアウトは、FloatやFlexなど左→右→左下...と「Z」字の順で並ぶものが多いですが、column-countというプロパティを使うと上→下→右上...というように逆「N」字の順で配置できます。ここでは<ul>の中の<li>を並べるのを例に各プロパティの説明をします。

column-count

親の<ul>に指定します。値には数字をセットします。「3」を指定した場合は各列の幅は均等で3列になります。

column-gap

列同士の間隔を指定します。px%で値を指定することができます。

break-inside

子要素<li>に指定します。avoidという値を指定することで要素の途中で折り返すのを防ぎます。このプロパティを指定しないと下記のように「04」が1列目と2列目に跨るように配置されてしまいます。

column-countでbreak-inside: avoid;を指定し忘れた場合の図

その14. リンクの下線アニメーション

See the Pen [CSS Tips] リンクの下線アニメーション by Takuro Sakai (@sakaccho) on CodePen.

通常のtext-decorationではこのような表現ができないので、疑似要素を使って再現します。

親要素<a>inline-block要素にします。block要素にしてしまうと横幅いっぱいに<a>が広がりテキストがない部分もクリッカブルエリアになってしまうので注意してください。:afterは幅100%・高さ1pxで線の形にします。position: absolute;で下部に配置し、transform: translate(-100%, 0);で左側の要素外に移動させます。

最後に、ホバーしたときにtransformを元の値に戻す指定をして完成です。

その15. ボタンの拡大アニメーション

See the Pen [CSS Tips] ボタンの拡大アニメーション by Takuro Sakai (@sakaccho) on CodePen.

ホバーすると中心から広がるエフェクトつきのボタンです。通常時に見えているのはa要素だけで、ホバー時に中心から広がってくる部分は:afterで作成します。

親となるablock要素の真円にして、position: relative;を指定しておきます。ここでは幅と高さが100px、まわりに6pxの黒いボーダーをつけました。

:afterは親と同じ大きさの真円で、absoluteで中央に配置します。topleft50%で始点を中心に移動させ、transformtranslate(-50%, -50%):after自身の幅と高さ50%分を戻すことで中央に配置しています。また、scale(0, 0)で大きさを0%、つまり見えない状態にしています。

a:hover:after {
  transform: translate(-50%, -50%) scale(1.1, 1.1);
}

最後に、ホバーのときにscale(1.1, 1.1)になるように設定することで、大きさ0%から110%に拡大するアニメーションを実装します。ここでtransform: scale(1.1, 1.1);のようにscale()の値だけ設定しないように注意してください。値を上書きしてしまうため、translate(-50%, -50%)が効かなくなってしまいます。上記のように初期状態を引き継ぐように指定しましょう。

その16. ボタンのスライドアニメーション

See the Pen [CSS Tips] ボタンのスライドアニメーション by Takuro Sakai (@sakaccho) on CodePen.

ホバーすると左から別の背景色がスライドして切り替わるボタンのアニメーションです。ボタンの背景に左側50%が金色(#a48c61)、右側50%が黒色(#000000)になるグラデーションを設定し、background-size: 200% auto;で背景の大きさを要素の幅の2倍に設定しています。また、background-position: 100% 0;で通常時は右側の黒色部分だけが見えるようにずらします。ホバー時には背景の位置を0 0に戻します。

この実装でポイントなのが、背景画像の大きさが要素より大きい場合、下の図のような振る舞いをするという点です。

通常、background-positionでXの正方向に値を指定した場合、背景画像は右に移動しますが、背景画像の大きさの方が大きい場合は「背景画像 X=100%」位置の点が、「要素 X=100%」位置に重なるように配置されるのです。従って、上記のボタンの初期状態ではbackground-position: 100% 0;というプラスの値を指定したにも関わらず、背景画像はマイナスの方向に移動したように見えるのです。

その17. 脈打つように広がる波紋アニメーション

See the Pen gOwBzoJ by Takuro Sakai (@sakaccho) on CodePen.

カルーセルやスライドショーなどのインジケーターの表現に用いると存在感を放って良い演出になります。サンプルではクリックするとその波紋が広がるようになります。

波紋にあたる部分は擬似要素:afterで再現します。この:afterabsoluteで配置し、親要素.pointに対して幅・高さいっぱいとなる真円にします。

アニメーションで波紋の広がりを再現します。「大きさが100%・背景色が金色の透過40%」という状態から「大きさが650%・背景色が透過0%」、つまり拡大しながら消えていくような「pulseMotion」という@keyframesを作成します。これを以下のように、.-activeが付与されたときに1.4秒間隔で繰り返すように適用します。

.point.-active:after {
  animation: pulseMotion 1.4s linear infinite;
}

その18. 自転する地球アニメーション

See the Pen [CSS Tips] Earth by Takuro Sakai (@sakaccho) on CodePen.

アニメーションを使用して世界地図を左から右に移動させ、あたかも自転しているかのように表現しています。まず親要素.earthで土台となる200pxの真円を作成します。そこにbox-shadowで内側に影をつけることで球体感を増しています。

世界地図は:beforeに背景として指定します。背景のサイズは高さがいっぱいになるように設定し、よりリアルになるよう:before自体をtransformで地軸の傾きと同じ23.4度傾けます。あとはanimationにキーフレーム「rotation」を16秒間隔で繰り返すように設定し、世界地図を左から右に移動させます。

キーフレーム「rotation」はbackground-positionが「0 0」の位置から「-200% 0」の位置に変わるという単純な動きになっています。

@keyframes rotation {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: -200% 0;
  }
}

その19. 羽ばたく鳥のアニメーション

See the Pen [CSS Tips] 羽ばたく鳥のアニメーション by Takuro Sakai (@sakaccho) on CodePen.

メインビジュアルに小さな鳥を何匹か飛ばす、ということで以前この実装を行いました。大きく表示すると角ばってしまってリアリティが薄れますが、上記の大きさくらいだと動きさえ工夫すればかなりリアルに再現できます。

鳥の再現は至ってシンプルです。まず正方形の要素内に、下辺と右辺にそれぞれ1pxの黒い疑似要素を作成し、正方形全体を45度傾けます(上図①)。次に翼を少し水平に倒したいので、:before:afterをそれぞれtransform: rotate();で外側に30度倒します(②)。最後にleftWingrightWingというキーフレームを適用し、30~110度(-30~-110度)間で傾きが変わるアニメーションを適用します(③)。よりリアルな鳥にするために翼を傾ける頻度は不規則に滑空する時間をとっています。

あとは、画面を横断するキーフレーム「moving」を親の.birdに適用すれば、左から右に飛んでいく鳥の完成です。

その20. 紙吹雪

See the Pen dyOpvZr by Takuro Sakai (@sakaccho) on CodePen.

紙吹雪は見た目や動きをCSSで、ランダム性をもたせるための処理をJSで実装しています。まず、CSSの部分ですが、一枚の紙につき三重の<span>を使用しています。それぞれの<span>は以下のように使い分けます。

  • 1階層目:紙のサイズ、振り始めの位置、落下アニメーション
  • 2階層目:紙の傾き
  • 3階層目:紙の色、紙の回転

表示する紙吹雪は2種類の動きを用意します。1つがY軸を中心として回転する「Y軸回転バージョン」、もう1つが時計回りに回り続ける「360度回転バージョン」です。なお、「Y軸回転バージョン」の際は2階層目にランダムな傾きを与えます。

Y軸回転バージョン
360度回転バージョン

また、1階層目に以下のように斜めに落下していく軌道をとるアニメーションを指定します。このような@keyframesをJSで12種類生成し、HTMLに動的に追加しています。

@keyframes moving-1 {
  0% {
    opacity: 0;
    transform: translate(0, 0);
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate(-60px, 270px);
  }
}

役割分担を踏まえ、それぞれの紙要素が以下のようになるようにJSで100枚分生成しています。

<!-- 1階層目 -->
<span style="
  top: -20px;                                  /* -20px で固定の値 */
  left: 17%;                                   /* 0~99% のランダムな値 */
  width: 5px;                                  /* 4~7px のランダムな値 */
  height: 6px;                                 /* 4~7px のランダムな値 */
  animation: moving-6 5900ms linear infinite;  /* moving-1 ~ moving-12 のいずれかを適用 */
  animation-delay: 2950ms;                     /* 一定の範囲内でランダムな値 */
">
  <!-- 2階層目 -->
  <span style="
    transform: rotate(34deg);                  /* 3階層目が rotateY の場合に傾きをランダムでつける */
  ">
    <!-- 3階層目 -->
    <span style="
      background-color: #E397AD;                 /* JS内で定義した12色からランダムなカラーコード */
      animation: rotateY 500ms linear infinite;  /* rotate360 か rotateY のどちらかを適用 */
      animation-delay: 2950ms;                   /* 一定の範囲内でランダムな値 */
    ">
    </span>
  </span>
</span>

JSの処理はページ読み込み時に一度だけ、落下軌道の@keyframesの作成と紙吹雪要素を生成しているだけで、あとはCSS任せの処理となっています。

さいごに

いかがでしたでしょうか。紹介したものはそのままウェブサイトに流用できるものばかりではありませんが、ぜひ実装のアイデア、エッセンスとして「こうやって動かせば良いのか」という閃きに貢献できれば幸いです。

ウェブに関するベイジの知見を、徹底的に学んでみませんか?

ベイジの知見を余すことなく提供する『戦略的ウェブ制作集中講座』の2023年版の参加者を絶賛募集中です。

戦略的ウェブ制作集中講座

講座の商材および申し込み用はこちら

取り扱うテーマは、BtoBサイト、採用サイト、オウンドメディア、プロジェクト管理、組織づくりの5つ。ベイジの最新の知見を、余すことなくご提供します。

全14回、1回1時間とすることで、1回あたりの拘束時間は短く、受けやすくしています。

アーカイブ動画も、講座で使ったスライドも、ベイジが業務で使ってるドキュメントの雛形も、すべて提供します。

参加者限定の専用Slackチャンネルを用意し、オフラインでの懇親会も開催します。講座自体はオンライン開催ですが、皆さまと直接コミュニケーションが取れる機会を、できるだけ設けようと思います。

以下のような方には、特に自信を持ってオススメできる講座に仕上がっています。是非ご検討ください。

  • これまでのウェブ制作の考え方を大きく変えたい
  • ウェブ制作のスタイルを根本的に見直したい
  • 圧倒的な情報量で数年分のレベルアップを一気にしたい
  • 提案力をつけて、市場での競争力を高めたい
  • ビジネスに影響を与えるウェブ制作をマスターしたい
  • ウェブ制作の「実践的な最先端」を見ておきたい
  • 自社のウェブ運用をもっと洗練させたい
  • 社員教育して強いチームにしたい

こんな記事も読まれています

提案書の書き方、徹底解説~提案書のストーリー・コピー・デザインの基本法則【スライド付】
枌谷力のプロフィール画像
枌谷力
821,590View
デザイナーじゃなくても知っておきたい色と配色の基本
枌谷力のプロフィール画像
枌谷力
745,107View
パワポでやりがちな9の無駄な努力
枌谷力のプロフィール画像
枌谷力
252,502View
上に戻る