マグネットのように背景色が移動するタブボタンの作り方
タブのボタンをカレント表示させる際に、背景色がマグネットのようにスライドして追従するアニメーションをつけてみました。
Chrome 125からサポートされたCSS Anchor Positioningを使用すればCSSだけで実装できそうですが、今回は幅広いブラウザでの対応が必要だったのでJavaScriptを使用しました。
実装例
早速ですが下記が実装例です。
タブボタンをクリックするとグレーの背景色が磁石のように遅れて追従します。今回はタブボタンは1行ですが、複数行となった場合にも対応しています。
コードのアウトプット
基本的なタブの実装は置いておいて、磁石のように追従する部分のコードを中心にアウトプットします。
選択済みのタブの情報を取得する処理
背景色を動かすために、下記のupdateTabBackground
という関数を追加しています。
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()
を使用してビューポートに対するタブボタンの位置と、ビューポートに対するラッパー要素の位置を計算して定数に格納しています。
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に代入することで、位置を設定しています。
// 背景のサイズと位置を設定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
プロパティを設定しています。
.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;
を追加します。
.c-tab { position: relative;}
今回は親要素となるc-tab
に対して追加しましたが、この辺りはHTMLの構造によって変わってくるので適宜調整が必要です。
以上「マグネットのように背景色が移動するタブボタンの作り方」でした。今回は背景色をアニメーションさせましたが、下線(アンダーライン)だけでも同じように動かせそうです。