下線アニメーション付きタブ切り替えを作る方法
タブを切り替えたときに、選択中のタブを示す下線がスムーズに移動するタブ切り替えを作る方法を紹介します。このサンプルでは、「概要」「特徴」「使い方」「サポート」の4つのタブを用意し、クリックしたタブに合わせて青い下線(インジケーター)が横方向へアニメーションしながら移動します。選択したタブの文字色も青色へ変わり、その下に表示されるコンテンツも対応する内容へ切り替わります。
HTMLで4つのタブ、下線となるインジケーター、それぞれに対応するコンテンツを作成し、CSSのtransitionを使って下線の位置と横幅を滑らかに変化させます。JavaScriptでは選択したタブの位置と横幅を取得し、その値に合わせてインジケーターのleftとwidthを変更します。そのため、タブごとに文字数や横幅が異なる場合でも、選択したタブの位置に合わせて下線を移動できます。
マウスやタッチによるクリックだけでなく、キーボードの左右矢印キー、Homeキー、Endキーによるタブ操作にも対応しています。また、画面幅が狭くタブが表示領域に収まらない場合はタブ部分を横スクロールでき、スクロール後やウインドウサイズを変更した場合にも選択中のタブに合わせて下線の位置を調整します。Webサイトの商品情報やサービス案内、設定画面など、現在選択している項目を下線の動きで分かりやすく見せたい場合に利用できます。
免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
タブを切り替えると、選択中のタブに合わせて下線がスムーズに移動します。
選択中のタブに合わせて、タブの下にある青い下線がスムーズに移動します。
タブの位置と横幅を取得し、下線の位置と長さを選択したタブに合わせて変更します。
タブはクリックのほか、左右の矢印キー、Homeキー、Endキーでも切り替えられます。
画面幅が狭い場合はタブ部分を横スクロールでき、スクロール後も選択中のタブに下線が合うように調整します。
概要・特徴・使い方・サポートの各タブをクリックすると、青い下線が選択したタブの位置へスムーズに移動し、対応する内容へ切り替わります。
コードをコピーして使おう!
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>下線アニメーション付きタブ切り替え</title>
<!-- CSSファイル -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- 下線アニメーション付きタブ切り替え全体 -->
<div class="animated-tab-underline_wrap">
<!-- タブ部分 -->
<div class="animated-tab-underline_tabarea">
<!-- タブ一覧 -->
<div
class="animated-tab-underline_tabs"
role="tablist"
aria-label="表示内容">
<!-- 概要タブ -->
<button
class="animated-tab-underline_tab is-active"
id="animated-tab-underline-overview"
type="button"
role="tab"
aria-controls="animated-tab-underline-panel-overview"
aria-selected="true"
tabindex="0"
data-tab="overview">
概要
</button>
<!-- 特徴タブ -->
<button
class="animated-tab-underline_tab"
id="animated-tab-underline-feature"
type="button"
role="tab"
aria-controls="animated-tab-underline-panel-feature"
aria-selected="false"
tabindex="-1"
data-tab="feature">
特徴
</button>
<!-- 使い方タブ -->
<button
class="animated-tab-underline_tab"
id="animated-tab-underline-usage"
type="button"
role="tab"
aria-controls="animated-tab-underline-panel-usage"
aria-selected="false"
tabindex="-1"
data-tab="usage">
使い方
</button>
<!-- サポートタブ -->
<button
class="animated-tab-underline_tab"
id="animated-tab-underline-support"
type="button"
role="tab"
aria-controls="animated-tab-underline-panel-support"
aria-selected="false"
tabindex="-1"
data-tab="support">
サポート
</button>
<!-- 選択中のタブ位置へ移動する下線 -->
<span
class="animated-tab-underline_indicator"
aria-hidden="true">
</span>
</div>
</div>
<!-- 概要コンテンツ -->
<div
class="animated-tab-underline_panel is-active"
id="animated-tab-underline-panel-overview"
role="tabpanel"
aria-labelledby="animated-tab-underline-overview"
data-panel="overview">
<!-- コンテンツタイトル -->
<div class="animated-tab-underline_panel-title">
概要
</div>
<!-- コンテンツ本文 -->
<p class="animated-tab-underline_panel-text">
選択中のタブに合わせて、タブの下にある青い下線がスムーズに移動します。
</p>
</div>
<!-- 特徴コンテンツ -->
<div
class="animated-tab-underline_panel"
id="animated-tab-underline-panel-feature"
role="tabpanel"
aria-labelledby="animated-tab-underline-feature"
data-panel="feature">
<!-- コンテンツタイトル -->
<div class="animated-tab-underline_panel-title">
特徴
</div>
<!-- コンテンツ本文 -->
<p class="animated-tab-underline_panel-text">
タブの位置と横幅を取得し、下線の位置と長さを選択したタブに合わせて変更します。
</p>
</div>
<!-- 使い方コンテンツ -->
<div
class="animated-tab-underline_panel"
id="animated-tab-underline-panel-usage"
role="tabpanel"
aria-labelledby="animated-tab-underline-usage"
data-panel="usage">
<!-- コンテンツタイトル -->
<div class="animated-tab-underline_panel-title">
使い方
</div>
<!-- コンテンツ本文 -->
<p class="animated-tab-underline_panel-text">
タブはクリックのほか、左右の矢印キー、Homeキー、Endキーでも切り替えられます。
</p>
</div>
<!-- サポートコンテンツ -->
<div
class="animated-tab-underline_panel"
id="animated-tab-underline-panel-support"
role="tabpanel"
aria-labelledby="animated-tab-underline-support"
data-panel="support">
<!-- コンテンツタイトル -->
<div class="animated-tab-underline_panel-title">
サポート
</div>
<!-- コンテンツ本文 -->
<p class="animated-tab-underline_panel-text">
画面幅が狭い場合はタブ部分を横スクロールでき、スクロール後も選択中のタブに下線が合うように調整します。
</p>
</div>
</div>
<!-- JavaScriptファイル -->
<script src="script.js"></script>
</body>
</html>
サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLでは「概要」「特徴」「使い方」「サポート」の4つのタブ、選択中のタブを示す下線(インジケーター)、それぞれのタブに対応するコンテンツを作成します。CSSではタブやコンテンツのデザインに加えて、下線の色・太さ・移動アニメーションを設定し、JavaScriptで選択したタブに合わせて下線の位置と横幅を変更します。
タブはクリックして切り替えられるほか、キーボードの左右矢印キー、Homeキー、Endキーでも操作できます。JavaScriptでは選択中のタブの位置と横幅を取得し、その値を下線のleftとwidthへ反映します。タブ部分を横スクロールした場合やウインドウサイズが変更された場合にも位置を再計算するため、選択中のタブに合わせて下線を表示できます。
外部ライブラリや外部サービス、APIなどは使用していません。APIキーやURLなど利用者自身で用意する情報もないため、index.html、style.css、script.jsの3ファイルを同じsampleフォルダへ配置すれば、そのままブラウザで動作を確認できます。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
index.htmlは、タブ切り替えのHTML構造を記述するファイルです。「概要」「特徴」「使い方」「サポート」の4つのタブ、それぞれに対応するコンテンツ、選択中のタブ位置へ表示する.animated-tab-underline_indicatorを記述しています。タブ名やコンテンツのタイトル・本文を変更する場合は、このファイルを編集します。タブ側のdata-tabとコンテンツ側のdata-panelによって、切り替えるタブとコンテンツを対応させています。
style.cssは、タブ切り替え全体のデザインと下線アニメーションを設定するファイルです。全体の横幅や余白、枠線、背景色、タブの文字サイズ、コンテンツの高さなどを設定しています。下線にはposition:absoluteを使用し、JavaScriptから変更されるleftとwidthをtransitionで滑らかに変化させます。また、画面幅640px以下の表示調整もこのファイルで行います。
script.jsは、タブの切り替えと下線の位置調整を行うファイルです。クリックされたタブのdata-tabを取得し、同じ値を持つdata-panelのコンテンツを表示します。選択中のタブではis-active、aria-selected、tabindexを更新します。また、getBoundingClientRect()でタブの位置と横幅を取得し、下線の位置と長さを合わせます。左右矢印キー、Homeキー、Endキーによるタブ操作、タブ部分の横スクロール時とウインドウサイズ変更時の下線位置の再計算もscript.jsで行っています。
設置方法・使い方
sampleフォルダを作成し、その中へindex.html、style.css、script.jsの3ファイルを同じ階層で配置します。index.htmlでは<link rel="stylesheet" href="style.css">からstyle.cssを読み込み、ページ下部の<script src="script.js"></script>からscript.jsを読み込む構成です。追加のライブラリや外部ファイルを読み込む必要はありません。
ファイルを配置したらsample/index.htmlをブラウザで開きます。最初は「概要」が選択され、そのタブの下へ青い下線が表示されます。「特徴」「使い方」「サポート」など別のタブをクリックすると、選択したタブの文字色が変わり、下線がそのタブの位置へスムーズに移動して、下のコンテンツも対応する内容へ切り替わります。
キーボードで操作する場合はタブへフォーカスし、右矢印キーで次のタブ、左矢印キーで前のタブへ移動できます。最後のタブから右矢印キーを押すと最初のタブへ、最初のタブから左矢印キーを押すと最後のタブへ移動します。Homeキーでは最初のタブ、Endキーでは最後のタブへ移動します。
カスタマイズできる内容
index.htmlでは、「概要」「特徴」「使い方」「サポート」というタブ名と、それぞれのコンテンツタイトル・本文を変更できます。タブとコンテンツの対応関係を変更する場合は、タブのdata-tabと対応するコンテンツのdata-panelを同じ値にします。idとaria-controls、aria-labelledbyも対応する組み合わせになっているため、タブ構成を変更する場合はそれぞれの対応関係を維持します。
style.cssでは、全体の最大横幅、余白、枠線、角丸、背景色、タブの文字色、選択中の文字色、下線の色・太さ・丸み・移動時間、コンテンツの高さや余白などを変更できます。特に.animated-tab-underline_indicatorのbackgroundを変更すると下線の色、heightを変更すると下線の太さ、transitionを変更すると下線が移動する速度を調整できます。
数値調整
style.css
padding:40px 20px;
ページ全体の余白です。40pxが上下、20pxが左右の余白を表します。値を大きくすると画面端との間隔が広がります。
max-width:700px;
タブ切り替え全体の最大横幅です。値を大きくすると全体を広く表示でき、小さくすると狭くなります。
margin:40px auto;
タブ切り替え全体の上下余白です。40pxを大きくすると上下の間隔が広がります。autoによって左右中央へ配置します。
padding:32px;
タブ切り替え全体の内側余白です。値を大きくすると外枠とタブ・コンテンツとの間隔が広がります。
border-radius:18px;
タブ切り替え全体の角丸です。値を大きくすると丸みが強くなります。
min-width:120px;
各タブの最小横幅です。値を大きくすると各タブが横に広くなり、全体が表示領域を超えた場合はタブ部分を横スクロールできます。
min-height:52px;
各タブの最小高さです。値を大きくするとタブが高くなります。
padding:14px 18px;
各タブの内側余白です。14pxが上下、18pxが左右を表します。値を大きくするとタブ内の余白が広がります。
font-size:16px;
タブの文字サイズです。値を大きくするとタブ名の文字が大きくなります。
transition:color .3s ease;
タブの文字色が変化する時間です。.3sは0.3秒を表し、値を大きくするとゆっくり、小さくすると速く変化します。
outline:3px solid ...
キーボード操作でタブへフォーカスしたときに表示する枠線の太さです。3pxを大きくするとフォーカス枠が太くなります。
outline-offset:-3px;
フォーカス枠の位置です。マイナス値によって枠線をタブの内側へ移動しています。
border-radius:8px 8px 0 0;
フォーカス枠上部の角丸です。8pxを大きくすると上側の丸みが強くなります。
bottom:-1px;
下線の上下位置です。タブ一覧の境界線へ下線を重ねるため、下方向へ1px移動しています。
height:3px;
選択中タブの下線の太さです。値を大きくすると下線が太くなり、小さくすると細くなります。
border-radius:999px;
下線の両端を丸くする値です。十分に大きな値を設定することで、下線の左右を丸い形にしています。
transition:left .3s ease, width .3s ease;
下線の位置と横幅が変化する時間です。.3sは0.3秒を表します。値を大きくすると下線がゆっくり移動し、小さくすると速く移動します。
min-height:190px;
コンテンツ部分の最小高さです。値を大きくするとコンテンツの表示領域が高くなります。
padding:24px;
コンテンツ部分の内側余白です。値を大きくすると文章と枠線の間隔が広がります。
font-size:18px;
コンテンツ内タイトルの文字サイズです。値を大きくするとタイトルが大きくなります。
レスポンシブ対応
このサンプルはstyle.cssでレスポンシブ対応しています。タブ切り替え全体へwidth:100%とmax-width:700pxを設定しているため、最大700pxを基準にしながら表示できる横幅に合わせて全体が縮小します。タブ部分にはoverflow-x:auto、タブ一覧にはwidth:max-contentとmin-width:100%を設定しているため、タブの横幅が表示領域を超えた場合はタブ部分だけを横スクロールできます。
画面幅640px以下では@media (max-width:640px)によってサイズを調整します。全体の内側余白を24px 18px、タブの最小横幅を110px、最小高さを48px、内側余白を12px 16px、文字サイズを14pxへ変更します。コンテンツ部分も最小高さ170px、内側余白20px 16px、タイトル17pxへ縮小します。さらにscript.jsでは横スクロール時とウインドウサイズ変更時に選択中タブの位置を再取得して下線を調整するため、スマートフォン・タブレット・PCで選択中のタブと下線の位置を合わせた状態で利用できます。
コメント