二本線からバツ印へ

═✕。

Appleの新ウェブサイト(2014年9月)では狭い画面の時にグローバル・ナビゲーションを出す二本線のアイコンが表示される。それをタッチするとナビゲーションが表示されると同時に回転しながらバツ印に変化する。同じようなアニメーションをCSSでやってみると意外に面倒くさかった。

Demo: Sandwich

二本線は以下のように擬似要素を2つ使って作った。コンテナーに対して幅を半分のサイズ、高さを6%とした。サイズと位置は全て%で統一したので、コンテナーの幅と高さを指定すれば以下のCSSは変えることなくスケールする。

.sandwich::before,
.sandwich::after {
  box-sizing: border-box;
  display: block;
  position: absolute;
  left: 25%;
  width: 50%;
  height: 6%;
  content: "";
  background-color: #333;
  transition: all 0.8s ease-in-out;
}

.sandwich::before {
  top: 30%;
}

.sandwich::after {
  top: 64%;
}

二本線にするためにtopプロパティーの位置だけ変える。デモなのでアニメーションは:hoverをトリガーにtransitionプロパティーで行わせた。ease-in-outを指定して、バツ印に変わる最後にちょっとブレーキが掛かるようにしておくとより近づく。

アニメーションは回転の中心と幅を調節しながら315度別方向に回す。

.sandwich:hover::before,
.sandwich:hover::after {
  top: 47%;
  left: 15%;
  width: 70%;
}

.sandwich:hover::before {
  transform: rotate(315deg);
}

.sandwich:hover::after {
  transform: rotate(-315deg);
}

70%の根拠は、元が50%なのでそれに√2を掛けたものleftプロパティーも70%に合わせて25%から15%に減らしておく。バツ印の1辺の高さは6%なので、中央に配置するには(100% - 6%) / 2 = 47%topプロパティーに指定すれば良い。

これでオンマウスで二本線からバツ印に変わる。Appleのもののように切替型にするなら:targetをトリガーにするのがコストが低い。その場合は両セレクターにtransitionプロパティーを指定することになる。URLにフラグメント識別子(location.hash)を追加したくないならJavaScriptでクラスを切り替えるようにして、それをトリガーにすることになる。


作ってからAppleのウェブサイトをもう一回確認したら、二本線から一本線にして、90度時計回りに回転させ、それから45度別方向に回転させているみたいだった。animationプロパティーを使ってならできそうだけど、同じプロパティー(ここではtransformプロパティー)を二回に分けてアニメーションさせられないtransitionプロパティーでは無理そう。

とにかくcalc()で平方根を計算できる定数的なの欲しい。という感想。工夫すればできたりしそう。