CSSのみで「TOPへ戻るボタン」を簡単に作る方法: スクロール途中で表示し、上に戻るアニメーションを実装!

#Scroll-driven Animations


元に戻りたい! (↼初見の方は無視してください)

Webデザインにおいて、ユーザーエクスペリエンスを向上させるためには、スムーズで便利なナビゲーションが不可欠です。その中でも、スクロール途中でも簡単にページトップに戻れるボタンを設置することは、サイトの定番となりつつあり、また非常に重要です。

この記事では、JavaScriptを使わずにCSSだけを駆使して、この便利なボタンを実装し、更に上に戻る際のアニメーションも取り入れる方法を解説します。

初心者の方にも分かりやすく、丁寧な説明を心掛けますので、良かったら読んでみて下さい。





以前、JavaScriptを使った「TOPへ戻るボタン」の実装方法をご紹介しました。

rubirubi.hateblo.jp

今回はJavaScriptを使わずに、同様の効果を実現する方法をご紹介します。

Scroll-driven Animations(スクロールドライブン・アニメーションズ)というAPIを利用するのですが、まだ新しいプロパティなのでブラウザやプラットフォームによっては機能しなかったり、不安定な部分はあるかも知れません。

ですが、スクリプトを使わずCSSのみで、アニメーションや、スクロール途中での表示などを実装できるメリットは大きいのと、コードはシンプルなので設置も簡単に出来ると思いますので、ぜひ参考にしてみて下さいね。


Scroll-driven Animationsとは

Scroll-driven Animations は、スクロール量に合わせてアニメーションが進められる API です。Chrome115 *1 で実装され、CSSと JavaScriptでアニメーションとスクロールを関連づけることができます。

scroll-driven-animations.style

この API では、JavaScriptのscrollイベントを使わずに、CSSだけでスクロールに合わせたアニメーションを作ることができます。たとえば、ある要素の透明度とスケールをスクロールに応じて 0 から 1 までアニメーションさせる場合、以下のコードになります。

.animation {
  view-timeline-name: --subjectReveal;
  animation-timeline: --subjectReveal;

  animation-name: appear;
  animation-fill-mode: both;
  animation-duration: 1ms; /* Firefox requires this to apply the animation */
}

@keyframes appear {
  from {
    opacity: 0;
    transform: scale(0);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

developer.mozilla.org


Scroll-driven Animationsを使用すると、スクロール コンテナ *2 のスクロール位置に基づいてアニメーションの再生を制御することができます。上下にスクロールすると、アニメーションが前方または後方にスクラブされます。 Scroll-driven Animations は、スクラブアニメーションやスティッキー(粘着性がある)な表現を、簡単に実装することができます。


クリックでスクラブアニメーションの説明を開く

スクラブアニメーション

スクロール量や位置に応じてアニメーションを変化させる動きのことです。スクロール連動のアニメーションを作成できるGSAP(ジーサップ。アニメーションを実装するために特化したJavaScriptライブラリ)のプラグインであるScrollTriggerを使用して実装します。

スクラブアニメーションは、たとえば、ピン留めされた画像がスクロールするごとに徐々に現れるような場合に使用されます。 スクラブアニメーションを導入するメリットは次のとおりです。

・ コンテンツの視線誘導に役立つ。
・ ウェブサイトの没入感の向上に役立つ。

スクラブアニメーションの値を大きくすると余韻が伸びるので、アニメーションの雰囲気も調整できます。



~Java Scriptを使わずに、CSSのみで「TOPへ戻るボタン」を実装し、
スクロール途中からボタンを表示して、スクロール アニメーションも表現する方法~


ボタンの実装

HTMLコードの基本構造

初めに、ページ内にTOPへ戻るボタンを配置するための基本的なHTML構造を作りましょう。

<a class="move-page-top" href="#">
  <div class="top-button">
    <span class="yajirushi"></span>
  </div>
</a>

a hrefでトップへのリンクを貼り、div配下でボタンのスタイルを指定しています。

クリックでさらに細かい説明を開く

<a href="#"> は、HTML内で使われるアンカータグ(リンク)で、#(ハッシュ)は通常、ページ内リンクの目的で使われます。しかし、#だけでは実際のリンク先が指定されていないため、このリンクはページ内のトップに戻るという訳です。

したがって、このようなリンクを設置すると、そのページ上のどの部分にいてもクリックするとページのトップに戻る挙動になります。これは、トップへのシンプルなページ内リンクとしてよく使われます。

ただし、ウェブアクセシビリティを考慮すると、この方法はスムーズでない場合があります。通常はJavaScriptを使用してアニメーションを追加するなど、ユーザーが快適にトップに戻れるようにすることも考慮します。

Output

CSSスタイル適用前の、上のコードが下記のリンクです。クリックすると、このページのトップに移動します。

※旅先で「元に戻りたい! 」をクリックすれば、またここに戻ります。

トップに行きたい! 

つまり、基本的には目次機能と同様で、ページ内リンクをトップに貼っているだけのことですので、上記のコードで既に「TOPへ戻るボタン」としての機能は実装済み、ということです。

残りの作業はボタンの位置や見た目の装飾、スクロール途中から表示するように設定したり、トップへ戻るときの動作を滑らかにするなど、インタラクティブな要素を追加することになります。


CSSコード

スタイルの実装

次にCSSです。先ず、ボタンの基本的なスタイルをCSSで設定しましょう。ここではまだ表示やアニメーションは設定せず、基本的な装飾(ボタンの外観を作る)を行います。

矢印系のアイコンや、イメージ画像を利用する方法もありますが、ここではCSSの基本プロパティを使って、色を付けたり、線を引いて矢印と円のボタンを成形したいと思います。

クリックでコードを開閉

.top-button {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background-color: #fecb6e;
}
.yajirushi::before,
.yajirushi::after {
  content: '';
  width: 25px;
  height: 6px;
  background-color: snow;
  position: absolute;
  border-radius: 3px;
}
.yajirushi::before {
  transform: translate(25px, 25px) rotate(45deg);
}
.yajirushi::after {
  transform: translate(10px, 25px) rotate(-45deg);
}

Output

このCSSコードは、トップへ戻るボタン(.top-button)とそのボタンに含まれる矢印(.yajirushi)をデザインするためのスタイルを定義しています。


クリックで詳細な解説を開閉

  1. .top-buttonクラスの役割:

    • width: 60px;およびheight: 60px;は、ボタンの大枠の、幅と高さを指定しています。
    • border-radius: 50%;は、円形の形状を作るためにボタンの角を丸めています。
    • background-color: #fecb6e;は、ボタンの背景色(オレンジ)を指定しています。
  2. .yajirushi::beforeおよび.yajirushi::after(疑似要素)のスタイル:

    • content: '';は、疑似要素の内容を空にしています。(ここでcontentを指定しないと、疑似要素として認識されません。''内にテキストを入力すれば文字を表示することも出来ますが、矢印を形成するラインを引くための疑似要素なので、ここではカラにしています。)
    • width: 25px;およびheight: 6px;は、矢印となるライン要素の幅と高さを指定しています。
    • background-color: snow;は、矢印の線の色名(雪色)を指定しています。
    • position: absolute;は、これら矢印の疑似要素が親の.top-buttonクラスから絶対位置に配置することを指定しています。
    • border-radius: 3px;は、矢印ラインの角を丸めています。
  3. .yajirushi::beforeのスタイル:

    • transform: translate(25px, 25px) rotate(45deg);は、疑似要素で作った矢印用の片方の線を45度傾け、矢印の左半分を形成しています。translateで円内の縦横の位置を指定しています。
  4. .yajirushi::afterのスタイル:

    • transform: translate(10px, 25px) rotate(-45deg);は、同じく疑似要素で作った矢印用の片方の線を-45度傾け、矢印の右半分を形成しています。また同様に、translateで円内の縦横の位置を指定しています。


以上、ここではCSSの疑似要素で線を作り、矢印を形成してボタンをデザインしました。




~Java Scriptを使わずに、CSSのみで「TOPへ戻るボタン」を実装し、
スクロール途中からボタンを表示して、スクロール アニメーションも表現する方法~


アニメーションの実装

スクロール途中でのボタン表示と、トップへの滑らかなスクロール

アニメーション部分をCSSコードに追加します。

クリックでコードを開閉

html {
  scroll-behavior: smooth;
}
body {
  height: auto;
}
@keyframes progress {
  0% {
    bottom: -120px;
  }
  40% {
    bottom: -120px;
  }
  45% {
    bottom: 0px;
  }
  50% {
    bottom: 20px;
  }
  100% {
    bottom: 20px;
  }
}
.move-page-top {
  position: fixed;
  right: 20px;
  bottom: -120px;
  animation: progress linear;
  animation-timeline: scroll();
  transition: bottom 1s ease;
  z-index: 2;
}

このコードは、Scroll-driven Animationsによるアニメーションを使用し、スクロール位置によるボタンの表示非表示、スムーズなスクロール・アクションを実装しています。

クリックで詳細な解説を開閉

  1. htmlセレクタのスタイル:

    • scroll-behavior: smooth;は、ページ内のリンクをクリックした際のスクロールを滑らかにするCSSプロパティです。ボタンをクリックしたとき一瞬でトップに行かず、画面をスクロールさせて上に戻るアニメーション部分です。
      このような動きの実装により、クリックした瞬間にパッ、と画面がトップに切り替わるより、その経緯を敢えてスムースなスクロールで見せることで、ページ内での現在位置をユーザーに認識させるなど、アクセシビリティやUXの向上が期待されます。
  2. bodyセレクタのスタイル:

    • height: auto;は、ボディ要素の高さを自動に設定します。通常、ページ全体の高さをコンテンツに合わせるために使用されます。
  3. @keyframes progressのアニメーション:

    • ページがスクロールされるときにトップへ戻るボタンのアニメーションを制御します。
    • 0%から100%の範囲で、bottomプロパティの値を変化させ、トップへ戻るボタンの表示位置を変更します。
      ここがこのコードの肝、と言える部分です。パーセンテージは、画面のスクロール位置を指定しています。つまり、ページトップから下に移動し、ページ全体の縦位置0~40%まではbottom: -120px;で矢印を画面外の下に隠し、45%の位置で0px、50%(ページ真ん中)で20pxとボタンの下部(bottom)の位置を徐々に上げていくことで、スクロール位置に連動したボタンの表示非表示を表現しています。
      ボタンの表示位置を早めたり遅らせたりするには、ここの数値を変化させれば良いわけです。
  4. .move-page-topのスタイル:

    • position: fixed;は、要素を固定位置に配置します。この場合、右下に固定されたトップへ戻るボタンです。
    • right: 20px;およびbottom: -120px;は、ボタンの初期位置を指定します。
    • animation: progress linear;は、先ほど定義した@keyframes progressのアニメーションを適用します。
    • animation-timeline: scroll();は、スクロールに合わせてアニメーションが進行するようにします。
    • transition: bottom 1s ease;は、bottomプロパティの変化を1秒かけて滑らかに変更するトランジションを設定します。
    • z-indexは、重なり合った HTML要素の前面・背面を指定する CSSプロパティです。通常では後に記述されたものが画面では手前に配置されますが、z-indexを使用することによって自由に優先順位を設定できます。値が大きい要素が上(手前)に表示されます。
      z-indexの初期値は autoであり、親要素と同じ階層に表示されます。ただし、positionプロパティでstatic以外の値が指定されていないと、数値は適用されませんので注意が必要です。
      z-indexの値は0を基準として、-2,147,483,647から 2,147,483,647まで(こんなに必要?)の値を指定できます。コードでは 2を指定していますが、もし他の要素と重なったときに裏側に回ってしまってボタンが押せなかったりするときは、この値を上げて対処すれば修正されることがあります。

Java Scriptを使わず、CSSのみでアニメーション機能を備えたTOPへ戻るボタンを実装する方法の解説は、ここまでとなります。

ブログ・サイトへの導入は、CSSコードはスタイルとアニメーション部分を合わせて<style></style>で囲み、HTMLコードと一緒にしてフッタなどに貼り付けてご利用下さい。


おわりに

Scroll-driven Animationsを活用し、機能的な「TOPへ戻るボタン」を、HTMLとCSSだけで作成することが出来ました。

これを自身のウェブサイトに導入することで、ユーザーが快適なブラウジングエクスペリエンスを得ることが期待できます。実際にコーディングしてみて、是非効果を確認してみてください!

Today's BGM

Nothings Gonna Change - 電気グルーヴ (1999)
「Nothing's Gonna Change」(ナッシングス・ゴナ・チェンジ)は、1999年にリリースされた電気グルーヴの11枚目のシングルです。 制作は石野卓球で、逆説的な歌詞が特徴的です。周囲の変化に対して「何も変わらない」と語りかけ、その独自のメッセージが心に残ります。 1998年に原型が制作され、完成までには長い時間を要したとされるこの楽曲。その製作背景や歌詞の意味には、当時の電気グルーヴの状況やメンバーの変動が影響していたようです。 シングル盤ジャケットのモデル名は沖樹莉亜。アートワークも見どころの一つです。 また、この楽曲はスペースシャワーTVの10周年記念イメージソングとしても使用され、その影響で欧州でもリリースされました。田中秀幸によるコンピュータグラフィックスのMVが、斬新な演出で話題となりました。電気グルーヴ独特の世界観と音楽性を感じる「Nothing's Gonna Change」の世界に是非、浸ってみてください。🎶✨


*1:Google Chrome115は、2023年 7月 12日にリリースされたウェブブラウザ「Google Chrome」の最新安定版です。バージョン番号は 115.0.5790.99 です。 Chrome 115 の新機能には次のようなものがあります:

  • スクロールに応じてコンテンツにアニメーション効果を適用できる
  • サードパーティCookie排除に向けた施策の一環として「Topics」と呼ばれるAPIの導入
  • サポート終了に関するメッセージをコンソールに追加

*2:スクロールコンテナは、特定のコントロール内でコンテンツをスクロール可能にするコントロールです。通常、この効果を得るためには、コンテナに対して overflow: scroll または overflow: auto を適用します。これにより、コンテンツがコンテナをはみ出す場合にスクロールバーが表示され、ユーザーはコンテンツを縦方向および横方向にスクロールできます。

スクロールコンテナの利用にはいくつかの魅力的な特性があります。例えば、フォームよりも大きなピクチャや画像を表示する場合、スクロールコンテナは画面に収めながらもユーザーに全体を見せる手段を提供します。同時に、縦方向と横方向の両方向にわたるスクロールが可能なので、ユーザーはコンテンツ全体を自在に閲覧できます。

また、スクロールコンテナを利用することで、レイヤーパネル内に多くのコンテンツを配置した場合でも、必要に応じてスクロールやページングが容易になります。これにより、コンテナ内のレイヤーを整理し、ユーザーにとって直感的で使いやすいインターフェースを構築することが可能です。

HTMLでスクロールバーを表示させるには、overflowプロパティを使用します。このプロパティは、横方向のスクロールを制御する overflow-x と、縦方向のスクロールを制御する overflow-y の2つがあります。これらのプロパティを活用することで、コンテナ内のコンテンツがはみ出す際に、適切な方向にスクロールバーが表示されるようになります。