タブメニューの作り方

CSSだけでタブメニューの作成方法について【アニメーションあり】

CSSを利用してタブメニューの作成方法を紹介していきます。中級編・応用編では、アニメーションを利用していきます。

タブメニューの作り方

タブメニューを作るためには、3つのテクニックを覚える必要があります。

1. labelタグとinputタグの連携

labelタグとinputタグを連携させるためには、labelタグの「for」を利用します。labelタグの「for」は、inputタグの「id」と紐づきます。

<label for="input-1">入力項目1</label>
<input id="input-1">

2. ラジオボタン選択時のセレクタ

ラジオボタン(input[type=”radio”])の選択時のセレクタは「:checked」で指定することができます。

input[type="radio"]:checked { outline: 5px solid red; }

3. 隣接セレクタ

同じ階層で隣接するセレクタは「+」で指定することができます。スタイルの適用は後半のセレクタに行われます。

<div id="div-1"></div>
<div>ここを指定</div>
#div-1 + div { color: red; }

初級編:タブメニュー

3つのテクニックを使って作成されたタブメニューが以下になります。「display: flex;」を利用することで複数のタブを横並びにしています。

「display: flex;」について

初級編:タブにマウスオーバーを追加

タブがマウスオーバーされた時にタブの背景色を変更します。マウスオーバーには、セレクタに「:hover」を利用します。

中級編:選択時にアニメーションを実行

選択時にコンテンツをふわっと表示されるようにします。

アニメーションには「transition」を利用します。二点間を移動させることができます。「opacity(透明度)」を移動させて表現しています。

コンテンツの非表示には「opacity(透明度)」を利用しています。「display: none;」を利用するとアニメーションにならないので気をつけてください。

中級編:マウスオーバーにもアニメーションを実行

初級編ではタブの背景色の変更しましたが、マウスオーバー時にふわっと背景色を変更するようにします。

ふわっとする部分は、要素を追加して対応することも可能ですが、疑似要素の「::before」を利用しています。疑似要素で対応しているため、HTMLの変更がなく対応できます。

応用編:選択されたタブに移動するアニメーション

選択されたタブへ移動するアニメーションを表現します。

カスタムプロパティを利用して移動するタブを表現しています。カスタムプロパティの値を上書きしているところが重要になります。

SASS(SCSS)を利用する方へ

SASS(SCSS)を利用する場合、selectクラスに関する箇所をシンプルにできます。

まずは「–i」を上書きする部分で「@for」を利用します。最大値はタブの個数になりますので、タブの個数の変数を用意することでselectクラス内の計算式にも利用できます。

.select {
    z-index: -1;
    position: absolute;
    left: calc(var(--tab-menu-width) / 3 * var(--i));
    flex: 1;
    width: calc(var(--tab-menu-width) / 3);
    border-bottom: 1px solid var(--tag-item-checked-color);
    background-color: var(--tag-item-checked-color);
    border-color: var(--tag-item-checked-color);
    transition: left 0.2s;
}

.tab-menu > input.index-0:checked ~ .select {
    --i: 0;
}

.tab-menu > input.index-1:checked ~ .select {
    --i: 1;
}

.tab-menu > input.index-2:checked ~ .select {
    --i: 2;
}
$tab-length:3;

.select {
    z-index: -1;
    position: absolute;
    left: calc(var(--tab-menu-width) / $tab-length * var(--i));
    flex: 1;
    width: calc(var(--tab-menu-width) / $tab-length);
    border-bottom: 1px solid var(--tag-item-checked-color);
    background-color: var(--tag-item-checked-color);
    border-color: var(--tag-item-checked-color);
    transition: left 0.2s;
}

@for $i from 1 through $tab-length {
    .tab-menu > input.index-#{$i - 1}:checked ~ .select {
        --i: #{$i - 1};
    }
}