ブログ

マグネットのように背景色が移動するタブボタンの作り方

タブのボタンをカレント表示させる際に、背景色がマグネットのようにスライドして追従するアニメーションをつけてみました。

Chrome 125からサポートされたCSS Anchor Positioningを使用すればCSSだけで実装できそうですが、今回は幅広いブラウザでの対応が必要だったのでJavaScriptを使用しました。

実装例

早速ですが下記が実装例です。

背景色がマグネットのようにスライドするタブ

タブボタンをクリックするとグレーの背景色が磁石のように遅れて追従します。今回はタブボタンは1行ですが、複数行となった場合にも対応しています。

コードのアウトプット

基本的なタブの実装は置いておいて、磁石のように追従する部分のコードを中心にアウトプットします。

選択済みのタブの情報を取得する処理

背景色を動かすために、下記のupdateTabBackgroundという関数を追加しています。

script.js
const tabWrapper = document.querySelector('[data-tab="wrapper"]');
// 背景を動かす処理
function updateTabBackground() {
const activeButton = tabWrapper.querySelector('[aria-selected="true"]');
if (activeButton) {
const buttonRect = activeButton.getBoundingClientRect();
const listRect = tabList.getBoundingClientRect();
// 背景の位置を計算
const x = buttonRect.left - listRect.left;
const y = buttonRect.top - listRect.top;
// 背景のサイズと位置を設定
tabBg.style.width = `${buttonRect.width}px`;
tabBg.style.height = `${buttonRect.height}px`;
tabBg.style.transform = `translate(${x}px, ${y}px)`;
}
}

この関数の中では大きく分けて2つの処理を行っています。

  • 背景の位置を計算する処理
  • 背景のサイズと位置を設定する処理

背景の位置を計算

getBoundingClientRect()を使用してビューポートに対するタブボタンの位置と、ビューポートに対するラッパー要素の位置を計算して定数に格納しています。

script.js
const buttonRect = activeButton.getBoundingClientRect();
const listRect = tabList.getBoundingClientRect();
// 背景の位置を計算
const x = buttonRect.left - listRect.left;
const y = buttonRect.top - listRect.top;

背景のサイズと位置を設定

背景の要素tabBgに対して、getBoundingClientRect()で取得した幅と高さを設定しています。また上記で取得したビューポートに対する位置情報をtranslateのxとyに代入することで、位置を設定しています。

script.js
// 背景のサイズと位置を設定
tabBg.style.width = `${buttonRect.width}px`;
tabBg.style.height = `${buttonRect.height}px`;
tabBg.style.transform = `translate(${x}px, ${y}px)`;

背景色を動かすためのupdateTabBackground関数を、初期表示時、ウィンドウリサイズ時、タブボタンクリック時に実行することで、動的に背景色のtranslateの値が変化するようになります。

CSSアニメーションを設定

最後にCSSアニメーションを設定します。背景の要素が変化時にアニメーションするように、transitionプロパティを設定しています。

style.css
.c-tab__bg {
display: block;
position: absolute;
top: 0;
left: 0;
background-color: #f0f0f0;
z-index: -1;
pointer-events: none;
/* CSSアニメーションを設置 */
transition: background-color 0.3s ease;
}

また親要素を基準にc-tab__bgを移動させる必要があるため、ラッパーとなる要素にposition: relative;を追加します。

style.css
.c-tab {
position: relative;
}

今回は親要素となるc-tabに対して追加しましたが、この辺りはHTMLの構造によって変わってくるので適宜調整が必要です。

以上「マグネットのように背景色が移動するタブボタンの作り方」でした。今回は背景色をアニメーションさせましたが、下線(アンダーライン)だけでも同じように動かせそうです。