アニメーションするハンバーガーボタンつくる
今日日(きょうび、って漢字にするとめちゃ読みずらい)、ハンバーガーボタンは動いて当然だよね、って気風だし、毎回つくるの面倒なのでさくっとコピペできるボタン用意した。
See the Pen animated hamburger button by ruemui (@ruemui) on CodePen.
ポイント
- モジュールとして使いやすいようボタンだけ
- なるべく少ないコード
- カスタマイズしやすいよう色々まとめた
使い方
HTML
<div class="header__btn"><span>MENU</span></div>
.header__btn { $width: 50px; $strokeWidth: 4px; $distance: 15px; $duration: .4s; $color: #000; position: absolute; width: 50px; height: 50px; font-size: 0; &:hover {cursor: pointer;} span { border-bottom: $strokeWidth solid $color; width: $width; position: absolute; top: 50%; left: 50%; margin-left: -($width / 2); transition: all $duration ease; &:before, &:after { content: ''; display: inline-block; border-top: $strokeWidth solid $color; width: $width; position: absolute; left: 50%; margin-left: -($width / 2); transition: all $duration ease; } &:before { top: -($distance); } &:after { top: $distance; } } } // when the menu opens .header__btn--opened { span { border-bottom: none; &:before { transform: rotate(-45deg); top: 0; } &:after { transform: rotate(45deg); top: 0; } } } /* to display button at the center */ .header__btn { margin: auto; top: 0; bottom: 0; left: 0; right: 0; }
$width
: ボタンの幅$strokeWidth
: ハンバーガーの線幅$distance
: 線と線の間隔$duration
: アニメーションする時間$color
: メニューの色
span
が中央線、:before
が上の線、:after
が下の線になっていて、上下の線の回転角を変えて色々できる。たとえば、:before
、を45度:after
を135度にしたりしてもいい。
js
var $btn = $('.header__btn'); $btn.on('click', function(e) { e.preventDefault(); $(this).toggleClass('header__btn--opened'); });
e.preventDefault();
いらないけどトリガーのdiv
をa
に変えてもいいように一応入れておいた。
あと、cssだけでやるのも(ちょっと前だけど)流行っていたのでつくっといたよ。
See the Pen CSS only animated hamburger button by ruemui (@ruemui) on CodePen.
HTML
<div class="header__btn"> <input type="checkbox" id="menu"> <label for="menu">MENU</label> </div>
$width: 50px; $strokeWidth: 6px; $distance: 15px; $duration: .4s; $color: #000; label:hover {cursor: pointer;} input { display: none; } label { font-size: 0; width: $width; height: $width; position: absolute; top: 50%; left: 50%; margin-left: -($width / 2); transition: all $duration ease; &:before, &:after { content: ''; display: inline-block; border-top: $strokeWidth solid $color; width: $width; position: absolute; left: 50%; margin-left: -($width / 2); transition: box-shadow ($duration / 4), transform $duration ($duration / 2), top $duration; } &:before { top: -($distance); box-shadow: 0 $distance 0 $color; } &:after { top: $distance; } } // when the menu opens input:checked { & ~ label { &:before { transform: rotate(-45deg); top: 0; box-shadow: ($distance * 2) $distance 0 lighten($color, 100%); } &:after { transform: rotate(45deg); top: 0; } } }
この人 CSS3 Only Menu
のやり方を参考に。
label
をトリガーにすると本当にボーダーの上をクリックしなければいけなかったのでlabelに高さを持たせて、
三本の線はlabel:before
のbox-shadow
で。box-shadow
でつくる方が色々線のコントロールはしやすかった。
比較して
js使わないほうが条件こぼれとかなさそうだし、反応もすこしだけいい気がする。ただメニューで使うときにはinput:checked
を使ってメニューオープン時のスタイルを定義しなきゃいけないので、CSSの見通し悪くなりそう。