CSS3でタブ・スライダーを作る

2020年12月18日

前回作ったCSS Sliderとは全くコンセプトを別にしたタブ・スライダーを学ぶことになった。このページがそうなのだ。その方法論と手が届かなかったCSS3の奥義をまとめて、理解することに努めることとなった。各タブには、その骨子を備忘録として保存する。では、ここからスタート。

初期値とするinputタグの属性に「"checked"属性」を指定することで、ブラウザーを開いた時に、ラジオボタンが選択された状態で表示される。inputとlabelを関連付けてデザインの変更を設定する。

このページのポイントの一つ目はchecked属性の構文「:checked」である。二つ目は隣接セレクタというもので、セレクタを結合子「+」で連結して指定するもの。

『.tab-switchのラジオボタンがチェックされていて隣接するのが.tab-labelのときはcolor: #fe001a;に変更する。』というJavaScriptで書くようなコマンドだが、これはCSS3で以下のように書けば良いのだから特筆すべきことである。

  .tab-switch:checked+.tab-label {
    color: #fe001a;
  }

『ラジオボタンがチェックされて、labelが隣接していたら背景の色を #fe001a に変える』という書き方は次のように書く。

input[type="radio"]:checked + label {background: #fe001a;}

※ラジオボタンは一組の中で一つの値を選択するように設計されている。checked属性の動作に馴染むためのサンプルを最後にどうぞ。

<label>好き:
<input type="radio" name="sampleRadio" checked>
</label>
<label>嫌い:
<input type="radio" name="sampleRadio">
</label>

CSS プロパティが変化する際のアニメーション速度をコントロールするCSS トランジション

遷移 (transition) によって、要素の2つの状態間の変化(transitionプロパティとは変化するまでの時間を設定するプロパティ)を定義することができる。それぞれの状態は :hover や :active のような疑似クラスで定義するか、 JavaScript を使用して動的に設定する。

この transition プロパティと一緒に transform (トランスフォーム)という変形(移動・回転・伸縮・傾斜)に関するプロパティが一緒に使われる。このページでは以下のように使われている。

transform: translateX(100%);
transition: cubic-bezier(0.4, 0, 0.2, 1) .2s;
transition: transform .3s 80ms, opacity .3s 80ms;

複数のアニメーションを指定するプロパティの例は以下になる。transition では五つ、transform では二つを設定してみた。

.square-shape {
    border-style: solid;
    border-width: 1px;
    display: block;
    width: 50px;
    height: 50px;
    background-color: #ffd000;
    opacity: 1;
    transition: width 2s, height 2s, background-color 2s, opacity 5s, transform 2s;
}

.square-shape:hover {
    background-color: #fe001a;
    width: 60px;
    height: 60px;
    transform: translateX(30px) rotate(90deg);
    opacity: 0;
}

<div class="square-shape"></div>

CSS の transition プロパティは、 transition-property、 transition-duration、 transition-timing-function、 transition-delay の一括指定プロパティである。

遅延アニメーションの書き方について。アニメーションは開始タイミングを遅らせることが出来る。従来マウスを乗せた時(hover)やクリック(click)がトリガーとなってアニメーションをスタートさせていたが、そのトリガーより何秒後にアニメーションをスタートするか決めることが出来る。例えば次は全てを対象にアニメーションで変化させる時間を「2秒」、アニメーションが開始するタイミングを「1000分の80秒」遅らせる。

transition: all 2s;
transition-delay: 80ms;

これを一括で指定するとこうなる。

transition: all 2s 80ms;

擬似要素(::after)を使って下線を引く

タブをタップ(もしくはクリック)するとアクティブになっている下線が移動して表示される、この下線部分を擬似要素を使って書く。

前提として::beforeと::afterの違いだが、左右では左が、上下では上が::beforeになる。故に右と下が::afterになる。display: block の場合は要素同士は縦に並ぶ。横線なので、widthが線の長さ、heightが太さになる。そこでコードを書くと以下になる。次に、チェックが入った.tab-switchの隣接セレクタの.tab-label::afterが対象になると、下線の非表示を表示に変えるという具合だ。尚、擬似要素を表示させたい時は必ず「content」が必要。

  .tab-label::after { 
    background: #fe001a;
    bottom: 0;
    content: '';
    display: block;
    height: 3px;
    left: 0;
    opacity: 0;
    pointer-events: none;
    position: absolute;
    transform: translateX(100%);
    transition: cubic-bezier(0.4, 0, 0.2, 1) .2s 80ms;
    width: 100%;
    z-index: 1;
  }
  .tab-switch:checked+.tab-label::after { 
    opacity: 1;
    transform: translateX(0);
  }

ついでに::before ::after を使ってタイトルをデザインしてみる。

h2.sham {
   position: relative;
   padding: 0 .5em .5em 2em;
   border-bottom: 1px solid #B61C2C;
}
h2.sham::before,
h2.sham::after {
   position: absolute;
   content: '';
}
h2.sham::before {
   top: .2em;
   left: .2em;
   z-index: 2;
   width: 18px;
   height: 18px;
   background: rgba(203, 162, 164, .5);
}
h2.sham::after {
   top: .7em;
   left: .7em;
   width: 13px;
   height: 13px;
   background: rgba(182, 28, 44, .5);
}
<h2 class="sham">擬似要素は便利だ</h2>

擬似要素は便利だ

整数値でフレックスアイテムの表示順序を指定(初期値は0)

このページではorderプロパティが重要な役割を果たしている。フレックスアイテムは、デフォルトではソースに記述されている順序で表示される。 orderプロパティを使用するとこの表示順序を変更できる。具体的には以下のように使う。

/* css */
ul.flex_menu {
  display: -webkit-flex;
  display: flex;
  width: 100%;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

ul.flex_menu a {
  display: block;
  margin: 2px;
  padding: 10px;
  font-size: 10px;
  background-color: #66cc99;
  color: #ffffff;
  text-align: center;
  text-decoration: none;
}
<!-- html -->
<ul class="flex_menu">
  <li style="order:2;"><a href="#">menu1</a></li>
  <li style="order:3;"><a href="#">menu2</a></li>
  <li style="order:4;"><a href="#">menu3</a></li>
  <li style="order:1;"><a href="#">menu4</a></li>
</ul>

このタブ切り替えは、ラジオボタンを利用してCSSだけで切り替えを実装出来るものだ。筆者はタブ切り替えを行った際のスクロールしながら切り替わる演出を探していきついたのだが、この機会に新たなCSS3の奥深さを知ることとなった。

参考元:CSSだけでスライドするタブ切り替えを考えてみた