普通の縦メニューをレスポンシブデザインに対応させてみる

レスポンシブデザインに対応した縦メニューを作ってみました。できるだけ詳しく解説してみますので、これを参考にサイトに合わせて自由にカスタマイズしてもらえたらうれしいです。

vertical-menu-responsive1.png

まずは実際に見てください。ブラウザを伸縮させながら見ていただければと思います。レスポンシブウェブデザインの確認にはブックマークレットのViewport Resizerも便利です。

では解説していきます。

HTML

<div id="navigation">
  <div id="toggle"><a href="#">menu</a></div>
  <div id="menu">
    <h3>Tittle1</h3>
    <ul>
      <li><a href="#">menu1</a></li>
      <li><a href="#">menu2</a></li>
      <li><a href="#">menu3</a></li>
      <li><a href="#">menu4</a></li>
      <li><a href="#">menu5</a></li>
      <li><a href="#">menu6</a></li>
    </ul>
    <h3>Tittle2</h3>
    <ul>
      <li><a href="#">menu1</a></li>
      <li><a href="#">menu2</a></li>
      <li><a href="#">menu3</a></li>
      <li><a href="#">menu4</a></li>
    </ul>
    <h3>Tittle3</h3>
    <ul>
      <li><a href="#">menu1</a></li>
      <li><a href="#">menu2</a></li>
      <li><a href="#">menu3</a></li>
      <li><a href="#">menu4</a></li>
      <li><a href="#">menu5</a></li>
    </ul>
    <h3>Tittle4</h3>
    <ul>
      <li><a href="#">menu1</a></li>
      <li><a href="#">menu2</a></li>
      <li><a href="#">menu3</a></li>
      <li><a href="#">menu4</a></li>
      <li><a href="#">menu5</a></li>
    </ul>
  </div>
</div>

2行目にメニューをたたんだときに表示されるボタンがありますが、それ以外は普通の縦メニューです。カテゴリごとで分かれていてカテゴリ名はh3タグを使っています。

CSS

続いてCSSです。長いですがとりあえずメニューの部分を全て載せます。全体を見たい場合はサンプルのソースをのぞいてください。

#navigation{
  float: left;
  width: 30%;
  margin: 0;
  padding: 0;
}
#navigation h3{
  margin: 0;
  padding: 8px 5px 5px;
  background: #8d990f;
  color: #fff;
  font-size: 12px;
  text-align: center;
}
#menu h3:nth-of-type(1){ background: #8d990f; }
#menu h3:nth-of-type(2){ background: #99820f; }
#menu h3:nth-of-type(3){ background: #995f0f; }
#menu h3:nth-of-type(4){ background: #993d0f; }
#navigation ul{
  list-style-type: none;
  margin: 0;
  padding: 0;
  background: #fff;
  border-left: 5px solid #8d990f;
}
#menu ul:nth-of-type(1){ border-color: #8d990f; }
#menu ul:nth-of-type(2){ border-color: #99820f; }
#menu ul:nth-of-type(3){ border-color: #995f0f; }
#menu ul:nth-of-type(4){ border-color: #993d0f; }
#navigation ul li{
  width: 100%;
  margin: 0;
  padding: 0;
}
#navigation ul li a{
  display: block;
  margin: 0;
  padding: 8px 10px;
  color: #333;
  font-size: 12px;
  text-align: left;
  text-decoration: none;
}
#navigation li a:hover{ background: #eee; }
#toggle{ display: none; }
@media only screen and (max-width: 1023px) {
  #navigation{
    float: none;
    width: 100%;
    background: #ebe7d2;
  }
  #menu { display: none; position: relative; }
  #menu:after {
    position: absolute;
    content:"";
    bottom: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: #d6cea3;
  }
  #navigation h3{
    clear: both;
    position: relative;
    z-index: 9999;
  }
  #navigation ul{
    margin-bottom: -1px;
    border-left-width: 3px;
    border-right-width: 3px;
    border-right-style: solid;
    background: #ebe7d2;
  }
  #navigation ul:before,
  #navigation ul:after{
    content: "";
    display: table;
  }
  #navigation ul:after{ clear: both; }
  #navigation ul{ *zoom: 1; }
  #navigation ul li{
    float: left;
    width: 25%;
    box-sizing: border-box;
    border-right: 1px solid #d6cea3;
    border-bottom: 1px solid #d6cea3;
  }
  #navigation ul li:nth-of-type(4n){ border-right: 0; }
  #navigation ul li a{
    text-align: center;
    padding: 12px 0px;
  }
  #navigation ul li a:hover{ background: #f5f4ea; }
  #toggle{
    display: block;
    position: relative;
    width: 100%;
    background: #222;
  }
  #toggle a{
    display: block;
    position: relative;
    padding: 15px 0 10px;
    color: #fff;
    text-align: center;
    text-decoration: none;
  }
  #toggle:before{
    display: block;
    content: "";
    position: absolute;
    top: 50%;
    left: 10px;
    width: 20px;
    height: 20px;
    margin-top: -10px;
    background: #fff;
  }
  #toggle a:before, #toggle a:after{
    display: block;
    content: "";
    position: absolute;
    top: 50%;
    left: 10px;
    width: 20px;
    height: 4px;
    background: #222;
  }
  #toggle a:before{ margin-top: -6px; }
  #toggle a:after{ margin-top: 2px; }
}
@media only screen and (max-width: 767px) {
  #navigation ul li{ width: 50%; }
  #navigation ul li:nth-of-type(2n){ border-right: 0; }
}
@media only screen and (max-width: 479px) {
#navigation ul li{
    float: none;
    width: 100%;
  }
}

大きいディスプレイ用から書いています。最近の流れからいくとモバイルからでしょうけど、まだ慣れていないので。

それでは個別に解説していきます。

PC用ディスプレイ

普通の縦メニューですがそれだけだと面白くないのでh3の色をそろぞれ変えています。「nth-of-type」に対応していないブラウザのことも考えて一応「#navigation h3」にもbackgroundを指定しています。

この辺の色は最初に選んだ色から彩度のみを変えていくと自然な流れになります。

#navigation{
  float: left;
  width: 30%;
  margin: 0;
  padding: 0;
}
#navigation h3{
  margin: 0;
  padding: 8px 5px 5px;
  background: #8d990f;
  color: #fff;
  font-size: 12px;
  text-align: center;
}
#menu h3:nth-of-type(1){ background: #8d990f; }
#menu h3:nth-of-type(2){ background: #99820f; }
#menu h3:nth-of-type(3){ background: #995f0f; }
#menu h3:nth-of-type(4){ background: #993d0f; }

「#menu h3:nth-of-type(1)」は#menuのなかにある最初のh3要素ということになります。「nth-child」とごっちゃになるという方はこちらの記事をどうぞ。

たくさんカテゴリがあっていちいち全てに色を指定するのは面倒だという場合は、「#menu h3:nth-of-type(n)」のnの部分を変更すると便利です。「1」 を 「4n-3」に、「2」 を 「4n-2」に、「3」 を 「4n-3」に、「4」 を 「4n」にそれぞれ変更すると、「1,5,9・・・番目」、「2,6,10・・・番目」、「3,7,11・・・番目」、「4,8,12・・・番目」とスタイルが適用されます。

h3要素の下にあるメニューの左側にh3要素と同じ色のボーダーを付けています。

#navigation ul{
  list-style-type: none;
  margin: 0;
  padding: 0;
  background: #fff;
  border-left: 5px solid #8d990f;
}
#menu ul:nth-of-type(1){ border-color: #8d990f; }
#menu ul:nth-of-type(2){ border-color: #99820f; }
#menu ul:nth-of-type(3){ border-color: #995f0f; }
#menu ul:nth-of-type(4){ border-color: #993d0f; }

最後にリンクになっている部分です。

#navigation ul li{
  width: 100%;
  margin: 0;
  padding: 0;
}
#navigation ul li a{
  display: block;
  margin: 0;
  padding: 8px 10px;
  color: #333;
  font-size: 12px;
  text-align: left;
  text-decoration: none;
}
#navigation li a:hover{ background: #eee; }
#toggle{ display: none; }

こちらもなんてことはないですね。最後の「#toggle」は次以降でメニューがたためれたときに使いますので、ここでは表示しません。

1023px以下のディスプレイ
vertical-menu-responsive2-2.png

ここからはPCより小さいスマホやタブレットを想定したものになります。2カラムだったものが1カラムになります。1カラムにするのは768pxからでもよいかもしれません。

@media only screen and (max-width: 1023px) {
  #navigation{
    float: none;
    width: 100%;
    background: #ebe7d2;
  }
  #menu { display: none; position: relative; }
  #menu:after {
    position: absolute;
    content:"";
    bottom: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: #d6cea3;
  }

まず、全体を横幅100%にして、メニュー部分を隠します。隠したメニューは後で解説するボタンで開閉します。

メニューの一番下にボーダーを付けるために擬似要素を使っています。

vertical-menu-responsive2-4.png

リンクの周りのボーダーと同じ色のやつです。リンクが偶数の場合必要ないですが、奇数の場合これがないと一番下のボーダーが途中で途切れます。この画像の場合、「menu5」の横のスペースの下にボーダーが付きません。

  #navigation h3{
    clear: both;
    position: relative;
    z-index: 9999;
  }
  #navigation ul{
    margin-bottom: -1px;
    border-left-width: 3px;
    border-right-width: 3px;
    border-right-style: solid;
    background: #ebe7d2;
  }
  #navigation ul:before,
  #navigation ul:after{
    content: "";
    display: table;
  }
  #navigation ul:after{ clear: both; }
  #navigation ul{ *zoom: 1; }

左にあったボーダーを少し細くして、同じ太さのボーダーを右にもつけます。ulの中にあるliが回りこんで横並びになりますので、clearfix(下の6行)で回りこみを解除しています。

「menu6」の下にはボーダーがありますが、その隣のスペースの下にはボーダーはありません。かなり微妙で目を凝らしても気付かないかもしれませんが、使う色によっては目立ってしまうと思うのできっちり対応してみます。

「margin-bottom: -1px;」で一番下のボーダーの分をその下にくる要素であるh3にかぶせ、h3を優先的に表示させるために、「 position: relative;」と「 z-index: 9999;」を指定します。別に9999である必要はありません。

vertical-menu-responsive2-5.png
  #navigation ul li{
    float: left;
    width: 25%;
    box-sizing: border-box;
    border-right: 1px solid #d6cea3;
    border-bottom: 1px solid #d6cea3;
  }
  #navigation ul li:nth-of-type(4n){ border-right: 0; }
  #navigation ul li a{
    text-align: center;
    padding: 12px 0px;
  }
  #navigation ul li a:hover{ background: #f5f4ea; }

メニューの幅を25%にして横並びにします。また、それぞれ右と下にボーダーを付けて囲うようにします。また、右端のメニューの右側にはボーダーは要りませんので表示しません。

widthとborderを同時に使うので「box-sizing: border-box;」を追加します。box-sizingを使い慣れていない方はこちらの記事をどうぞ。

これらのメニューは隠れていますので、表示するためのボタンを設置します。

  #toggle{
    display: block;
    position: relative;
    width: 100%;
    background: #222;
  }
  #toggle a{
    display: block;
    position: relative;
    padding: 15px 0 10px;
    color: #fff;
    text-align: center;
    text-decoration: none;
  }
  #toggle:before{
    display: block;
    content: "";
    position: absolute;
    top: 50%;
    left: 10px;
    width: 20px;
    height: 20px;
    margin-top: -10px;
    background: #fff;
  }
  #toggle a:before, #toggle a:after{
    display: block;
    content: "";
    position: absolute;
    top: 50%;
    left: 10px;
    width: 20px;
    height: 4px;
    background: #222;
  }
  #toggle a:before{
    margin-top: -6px;
  }
  #toggle a:after{
    margin-top: 2px;
  }

このボタンは「レスポンシブWebデザインに対応したメニューの作り方【追記あり】|Webpark」という記事でも紹介しましたが、あらためて解説を載せます。

responsive-menu4.png

白い正方形の上に黒い長方形を2つ乗せて3本線を表現しています。

この3つの要素はすべて擬似要素で作られています。この辺の使い方は慣れるまで難しいかもしれませんが、使い慣れるとCSSの幅がぐっと広がります。

では、縦の位置の調整について、ボタンの部分をもっと拡大して解説します。

responsive-menu6.png

top: 50%;を指定することで、擬似要素の上の位置が画像の点線部分になります。

白い正方形にあたる「#toggle:before」の場合は高さ20pxの半分にあたる10pxを「margin-top: -10px」で上げることで上下中央に表示されます。

続いて、白い正方形を区切る2つの黒い長方形について、「#toggle a:before」は真ん中の太い点線部分から6px上げて(上の点線)、「#toggle a:after」は点線部から2px下げて(下の点線)表示しています。

767px以下のディスプレイ
vertical-menu-responsive2-3.png

今度は先ほど横幅25%にして横に4つ並べていたメニューを、横幅50%にして2つ並ぶようにします。

@media only screen and (max-width: 767px) {
  #navigation ul li{ width: 50%; }
  #navigation ul li:nth-of-type(2n){ border-right: 0; }
}
479px以下のディスプレイ
vertical-menu-responsive3.png

これで最後です。メニューが横幅100%になります。

@media only screen and (max-width: 479px) {
#navigation ul li{
    float: none;
    width: 100%;
  }
}
jQuery

1023px以下のディスプレイを対象にしたメニューを開閉する仕組みをjQueryで実装します。

$(function(){
  var menu = $("#menu");
  $("#toggle").click(function(){
    menu.toggle();
    return false;
  });
  $(window).resize(function(){
    var win = $(window).width();
    var p = 1024;
    if(win > p){
      $(menu).show();
    }
  });
});

前半部分は「#toggle」をクリックすればメニュー全体が開閉する仕組みです。

後半部分はディスプレイサイズが変更されたとき、1024px以上の場合にはメニューが表示される仕組みです。

1023px以下のディスプレイ表示した際のボタンでメニューを開閉して閉じた状態にしてから、1024px以上のディスプレイで見るとメニューが表示されません。そんな不都合をなくすためのものです。

この辺はメディアクエリで対応できそうな気もしますが、jQueryで開閉された場合以下のようにインラインでスタイルが書き込まれるため、メディアクエリで書いたものより優先されます。

ということで、jQuery部分の解説でした。

さいごに

ということで横メニューをレスポンシブデザインに対応させる方法を紹介しました。これをそのまま使うということはあまりないと思いますが、詳しく説明してみましたので、これを参考にご自分のサイトに合ったメニューを作っていただければと思います。

フィードやTwitterで最新情報をチェック
follow us in feedly
この記事に付いているタグの最新記事一覧
loading...
コメント









※コメントはご意見ご感想や間違いのご指摘等にしていただけますようお願いいたします。コメントを確認する時間がなく、技術的なご質問をいただいても答えできません。申し訳ございませんがご理解のほどお願いいたします。

Recent Entry
Popular Entry
  • このエントリーをはてなブックマークに追加