
CSSのみでグローバルナビゲーションメニューバーを実装する方法
コピペでもいいのですが、できれば実物を見ながら仕組みを理解していただければ嬉しいです。
・CSSは最初にスマホ版のレイアウトから設定している
・メディアクエリ(min-width: 680px)でPC端末向けのスタイルを設定している
・メニュー展開はleft: calc()により画面外から正面へ戻る動きをeasingさせているだけ
・ベンダープレフィックスによるダブり設定が多いが要所はシンプル
・PCやタブレットはgrid-areaで位置の制御をしている
CSSのみでグローバルナビゲーションメニューバーを作る
前回は、javascriptを使ったレスポンシブルのナビゲーションメニューを実装する方法をご紹介しました。
javascriptを使ったナビゲーションメニューの作り方はこちら
今回はjavascriptを使わずにhtmlとCSSのみで作るグローバルナビゲーションメニューバーをご紹介します。
上部に固定されるメニューバー
今回はページをスクロールしても上部に引っ付いてくる固定ナビゲーションメニューです。
ソース自体をそのままコピペする事できるので、自由に利用してみて下さい。
ナビゲーションメニューバー完成イメージ(iframe)
設置事例
文章をテストで並べていますが、スクロールしても枠上部に固定されます。
スマホ版でもPC版と同様に固定されます。
スマホ版ではハンバーガーメニューがあり、クリックすると上から下にではなく左から右へメニューが展開します。
単独事例サンプルはこちら
htmlソース
<header> <div class="container"> <div class="logo">LOGO</div> <input class="hamburger-button" type="checkbox" id="hamburger-button" /> <label for="hamburger-button"> <div></div> </label> <div class="menu"> <nav> <ul> <li><a href="#">Home</a></li> <li><a href="#">コンセプト</a></li> <li><a href="#">サービス内容</a></li> <li><a href="#">会社概要</a></li> </ul> </nav> <div class="buttons"> <a href="#" class="button primary">お問い合わせ</a> <a href="#" class="button">会員ログイン</a> </div> </div> </div> </header>
使い方
単独事例サンプルのソースを開くと、上部で読み込んでいる「main.css」に全てのスタイルが記述されています。
上にあるHTMLソースと、サンプルページで読み込んでいるCSS(リセットCSSとmain.css)を全てコピペすればすぐに使えるようになります。
このmain.cssの記述の解説をしていきますので、main.cssを開きながら確認して下さいね。
main.cssはこちら
スマホ版メニューCSSの構築
まず先にスマホ版レイアウトを作成
今回CSSのポイントは、先に「スマホ版のメニューレイアウト」を構成している事です。
その後に(min-width: 680px)や(min-width: 1080px)など、スマホ版以外となるPC構成を作って上書きしています。
PC構成を先に作っている訳ではない事に注意しましょう。
ベンダープレフィックスを設定している
main.cssでは、-msなどの接頭辞で始まるベンダープレフィックス設定も並行して記述してあります。
そのためやたらと長くなっており複雑な様に見えますが、設定自体は重複した状態です。
接頭辞の部分は省いて考えてもらえば、それ程複雑なものではありません。
以下より詳しく解説していきます(設定は24行目から)。
24行目:メニューバー固定にstickyを利用
top: 0; position: sticky;
絶対配置でposition:sticky;を設定する事で上部に固定をしています。
34行目:メニュー内の要素(container)にflexboxを使う
.logoやinputのボタンを横並びにするため、flexboxを設定しています。
display: flex;
77行目:ハンバーガーメニューについて
input.hamburger-button ~ label > div, input.hamburger-button ~ label > div::before, input.hamburger-button ~ label > div::after
labelタグ内にdivタグがありますが、このdivタグで3本線を表現しています。
div:beforeで1本目
divで2本目
div:afterで3本目
この時、線はbackgroundの背景色で表現します。
ボタンクリック時の×マークを表現
ハンバーガーメニュー(inputのcheckbox部分)がクリックされると、divの2本目が透明になり、1本目と3本目がそれぞれ斜め45度に傾く事で「×」マークを実現しています。
もう一度クリックされると元の3本線に戻る訳ですね。
その間の滑らかな動きをease-in-outで実現しています。
メニューの展開ギミック
120行目:メニュー展開時の動き
メニューが表示される時、左から右へ展開してくる動きを実現しています。
position: absolute; z-index: -1; top: 3.5rem; left: calc(-100vw - 3rem);
これはメニュー全体(.menu)を絶対配置でleft方向に100%分移動し、そこからさらに3rem分leftへ移動している事を指します。
要は完全に左側の画面外へ隠れてしまいたい訳ですね。
上記ではあえてさらに3rem分左へ移動していますが、0remでも完全に見えなくなるのであれば問題は無いと思います。
138行目:メニューがクリックされた時
メニューが画面上に展開された部分をここで指定しています。メニューが縦に並んでその下にボタンが2つ横並びしている状態ですね。
左の画面外に隠れていたものを、ボタンクリックと同時に画面の真正面に表示させる訳です。
この「位置の差」を埋める動きが、左から右へのメニュー画面のスライド運動になる訳です。
その上の段にあるtransition: 0.22s ease-in-out;で滑らかに移動させています。
右から左へ展開させる(逆の動き)場合
先ほどの120行目を下記の様に変更してみましょう。
left: calc(100vw - 0rem);
先ほどは画面左端へ隠れていましたが、上の様に変えると今度は右端へ隠れます。
プラスとマイナスの数値による移動方向
絶対配置leftの0vwは画面左端にくっついた状態であり、この状態からプラスの数値なら右へ、マイナス数値なら左へ移動します。
「-100vw」とすると、左方向(マイナス方向)に要素分だけ隠れます。
「100vw」とすると、右方向(プラス方向)に要素分だけ隠れます。
メニューの動き自体を命令していない
既におわかりだと思いますが、「左から右へ」或いは「右から左へ」と動くギミック命令がある訳ではありません。
そもそもjavascriptは使わないルールですし。
「画面外(左か右)の位置」から「真正面の位置」までの差を、transition: 0.22s ease-in-out;で埋めているだけです。
左に隠れていれば正面に移動するために右方向へ滑らかに戻り、右に隠れていれば正面に移動するために左方向へ滑らかに戻っているだけです。
left: calc(100vw - 0rem); /* 右端から左へスライドする */ left: calc(-100vw - 0rem); /* 左端から右へスライドする */
161行目:メニューを縦並びにする
表示されたメニュー項目は100%幅にする事で縦並びにしています。
さらにその下の方でボタンにポイントしたときの色の変化も滑らかにしています。
PC・タブレットの設定
206行目:これまでのメニュー構成をスマホに限定
メディアクエリ(min-width: 680px)として別の新ルールを入れる事で、それまでのメニューレイアウトをスマホ版に限定しています。
min-width: 680pxは「680px幅を超えた場合」という意味です。
逆にmax-width: 680pxは「680幅以内の場合」という意味です。
今回はmin-width: 680pxなので、画面幅が680pxを超えた場合の設定が入ります。
つまりPCやタブレットで見た場合は、このmin-width: 680px内の設定が優先される事になります。
ですのでこれまで設定してきたハンバーガーメニューの構成やクリックイベントは、スマホ版になるまで発生しません。
223行目:メニューを横並びに変更
メニュー項目部分
header .container .menu { z-index: unset; top: 0; l eft: 0; … display: grid; … }
left: calc()で隠れていたメニューをPC向けにもとの配置(top: 0 left: 0)に戻します。
header .container .menu nav { … grid-area: 2/1/3/3; } header .container .menu nav ul { … flex-direction: row; … justify-content: center; } header .container .menu nav ul > li { … flex: 1; }
メニューの位置(nav)はgrid-areaを使って指定し、各項目はflexを使って横並びに設定しています。
ボタン部分
header .container .menu div.buttons { … grid-area: 1/2/2/3; …
.buttonsの項目についても、grid-areaを使ってメニューの横に整列させています。
291行目:1040pxタブレット端末向け
ここから先はmin-width: 1040pxという形で、さらにiPadなどのタブレット枠向けの設定を追加しています。
先ほどと同様、ここまで設定してきたスタイルはタブレット端末枠では適用されず、新しいルールが設定される事になります。
タブレット端末向けサンプル
header .container .menu nav { … grid-area: 1/2/2/3; } header .container .menu div.buttons { … grid-area: 1/3/2/4; }
問い合わせや会員ログインのボタンはgrid-areaでタブレット向けに個別指定する事で、横並びメニューの上部に移動させています。
本記事上部で紹介しているiframe実例はまさに、このタブレット枠内の設定が反映されています。
ベンダープレフィックスについて
CSSには通常の設定以外に、-msと-webkitで始まる設定が多く出てきます。これがベンダープレフィックスです。
ベンダープレフィックス(接頭辞)とは、ブラウザの開発元(ベンダー)が独自の拡張機能や草案段階の仕様を実装する場合に、それが拡張機能である事を示すために付ける識別子の事を指します。
将来的に仕様が変更されるリスクに備え、独自拡張や先行実装のプロパティ名や値の先頭に付けることが推奨されています。
ベンダープレフィックスでは、前後に「-」を付けた識別子でブラウザの種類を特定します。
主要ブラウザのベンダープレフィックス
-moz- …… Firefox
-webkit- …… Google Chrome、Safari
-o- …… Opera
-ms- …… Internet Explorer
-webkit-box-align: start; /* Chrome向け */ -ms-flex-align: start; /* IE向け */ align-items: flex-start; /* 本来の設定 */ -webkit-box-pack: end; /* Chrome向け */ -ms-flex-pack: end; /* IE向け */ justify-content: flex-end; /* 本来の設定 */
ベンダープレフィックス併用は運営者の判断で
本CSSでも従来設定に加え、追加でIEやGoogleChrome向けのベンダープレフィックス設定をしています。
そのため設定もやたらと長くなっています。
ブラウザIEは今ほとんど使わない事ですし、入れるか入れないかは判断に任せます。
実装時の注意
紹介しているテストページはグローバルナビゲーションメニューバーと文章のみのシンプルな構成となっています。
実際には他に様々なコンテンツをデザインする情報が入ってくる事でしょう。
その場合各要素のスタイルがバッティングしないように気を付けて下さい。
既存のHTMLページに組み込む場合
特に最初にある程度構成されたページにこのようなナビゲーションメニューを後から組み込む場合は注意が必要です。
それまでに適用されているCSSの命令と今回のcss-header.cssのスタイルがぶつかると、表示が崩れる場合があります。
お互いが干渉しないようにクラス名を変えるなどの工夫が必要です。
リセットCSSを最初に読込む
紹介しているテストページはcss-style.cssを読む前にreset.min.cssをcdnで読み込んでいます。
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"> <link rel="stylesheet" href="main.css">
これによりCSSリセットを掛けた上でナビゲーションメニューバーのスタイルを適用しているのです。
ですので既存ページなど既に別CSSによるリセットが掛かっている場合などは特にバッティングしやすくなります。
そのままコピペして使っても良いのですが、仕組みを理解してクラス名や命令をオリジナルで用意していく方が賢明です。
そんなに複雑なナビゲーションではないので、バッティング箇所を修正するよりも時間を節約できると思います。
まとめ
以上CSSのみでグローバルナビゲーションメニューバーを実装する方法を紹介しました。
メニューバーを作る際のポイントを紹介しておきます。
実装のポイント
・CSSは最初にスマホ版のレイアウトから設定している
・メディアクエリ(min-width: 680px)でPC端末向けのスタイルを設定している
・メニュー展開はleft: calc()により画面外から正面へ戻る動きをeasingさせているだけ
・ベンダープレフィックスによるダブり設定が多いが要所はシンプル
・PCやタブレットはgrid-areaで位置の制御をしている
そんなに複雑なナビゲーションメニューではないので、バッティング箇所を修正するよりも時間を節約できると思います。