CSS3だけで作るレスポンシブデザイン対応ナビゲーションバーの作り方

こんにちは、鴨田です。

最近はRetina対応のMac Book Proが出たり、特にスマートフォンに限らず、解像度の高いディスプレイが多くなってきました。そうなると、画像でいろいろな素材を作るということに関して限界が出てきます。

なので、最近はCSSだけでナビゲーションバーのデザインやコーディングを行うことが多いとは思いますが、知ってる人も知らない人もちょっとしたナビゲーションバーを作ってみましょう。

作るのは、横幅は特に設定しないレスポンシブデザインにも対応できるリキッドな6つの項目を持ったナビゲーションバーとします。ただし、スマートフォンを意識して、外側に320pxのラッパーを配置しておきます。

注意事項として、FirefoxとWebkit系ブラウザ(Google Chrome、Safariなど)でしかベンダープレフィックスをつけていないので、それ以外のブラウザで見ると、崩れます。

HTML


<div class="wrapper">
  <nav class="tab">
    <ul>
      <li><a href="#1">タブ1</a></li>
      <li><a href="#2">タブ2</a></li>
      <li><a href="#3">タブ3</a></li>
      <li><a href="#4">タブ4</a></li>
      <li><a href="#5">タブ5</a></li>
      <li><a href="#6">タブ6</a></li>
    </ul>
  </nav>
</div>

CSS


div.wrapper {
  width: 320px;
  background: #999;
}
nav.tab {
  width: 100%;
  padding: 10px;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
.wrapper ul {
  width: 100%;
  list-style: none;
  display:-moz-box;
  display:-webkit-box;
}
.wrapper ul li {
  -moz-box-flex:1.0;
  -webkit-box-flex:1.0;
  text-align: center;
  padding: 5px 0;
  background: #fff;
}
.wrapper ul li a {
  font-size: 14px;
  color: #333;
  text-decoration: none;
}
.wrapper ul li a:hover {
  text-decoration: underline;
}

デモ

外側のdiv要素には分かりやすいように背景色を敷いています。

nav要素の幅を100%としていますが、デザイン上、左右には余白が欲しいので、paddingを10px取っています。
ただし、普通にpaddingを指定すると、100%+20pxで外側のdiv要素をはみ出してしまいますので、
box-sizingプロパティを使って、はみ出さないようにします。

li要素を均等に割り付けたいので、box-flexプロパティを使って、親のul要素にもdisplayにboxを指定します。

後は、li要素の中のa要素に少し味付けをしてますが、基本的なコーディングはこれで出来たと思います。

続いて、もう少しちゃんとした装飾をしてみます。

CSS


div.wrapper {
  width: 320px;
}
nav.tab {
  width: 100%;
  padding: 10px;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
.wrapper ul {
  width: 100%;
  list-style: none;
  display:-moz-box;
  display:-webkit-box;
  box-shadow: 0 0 5px #666;
  border-radius: 5px;
}
.wrapper ul li {
  -moz-box-flex:1.0;
  -webkit-box-flex:1.0;
  text-align: center;
  background: -moz-linear-gradient(top, #999 50%, #666 50%);
  background: -webkit-gradient(linear,left top,left bottom, color-stop(0.5, #999),color-stop(0.5, #666));
  border-top: 1px solid #fff;
  border-bottom: 1px solid #fff;
  border-right: 1px solid #ccc;
}
.wrapper ul li:hover {
  background: -moz-linear-gradient(top, #666 50%, #333 50%);
  background: -webkit-gradient(linear,left top,left bottom, color-stop(0.5, #666),color-stop(0.5, #333));
}
.wrapper ul li:first-child {
  border-radius: 5px 0 0 5px / 5px 0 0 5px;
  border-left: 1px solid #fff;
}
.wrapper ul li:last-child {
  border-radius: 0 5px 5px 0 / 0 5px 5px 0;
  border-right: 1px solid #fff;
}
.wrapper ul li a {
  width: 100%;
  height: 100%;
  padding: 5px 0;
  display: block;
  font-size: 14px;
  color: #fff;
  text-decoration: none;
  text-shadow: 0 -1px 1px #333;
}
.wrapper ul li a:hover {
  text-shadow: 0 0 3px #fff;
}
</style>

デモ

せっかくなので、角丸、背景グラデーション、シャドウなどてんこ盛りにしてみました。

角丸にしたときに、いくつか注意事項があります。

li要素に背景色を指定している場合、
ul要素にborder-radiusプロパティを全ての角に指定しただけだと、うまく角丸にはならないはずです。
その時は、li要素の最初と最後の要素にも、角丸を指定する必要があります。

CSS


div.wrapper {
  width: 320px;
}
nav.tab {
  width: 100%;
  padding: 10px;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
.wrapper ul {
  width: 100%;
  list-style: none;
  display:-moz-box;
  display:-webkit-box;
  box-shadow: 0 0 5px #666;
  border-radius: 5px;
  border: 1px solid #fff;
}
.wrapper ul li {
  -moz-box-flex:1.0;
  -webkit-box-flex:1.0;
  text-align: center;
  background: -moz-linear-gradient(top, #999 50%, #666 50%);
  background: -webkit-gradient(linear,left top,left bottom, color-stop(0.5, #999),color-stop(0.5, #666));
  border-right: 1px solid #ccc;
}
.wrapper ul li:hover {
  background: -moz-linear-gradient(top, #666 50%, #333 50%);
  background: -webkit-gradient(linear,left top,left bottom, color-stop(0.5, #666),color-stop(0.5, #333));
}
.wrapper ul li:last-child {
  border-right: none;
}
.wrapper ul li a {
  width: 100%;
  height: 100%;
  padding: 5px 0;
  display: block;
  font-size: 14px;
  color: #fff;
  text-decoration: none;
  text-shadow: 0 -1px 1px #333;
}
.wrapper ul li a:hover {
  text-shadow: 0 0 3px #fff;
}

デモ

 ↑ 角が飛び出ています(> <) そしてなぜ、ul要素にまとめてborderを指定するのではなく、li要素に入れているのかと言えば、
li要素の大きさがちゃんと割り切れないような数値になると、
場合によって、一番最後のli要素のborderが太くなってしまったり、
角丸自体があまりキレイに表現されない場合があるためです。

CSS


div.wrapper {
  width: 320px;
}
nav.tab {
  width: 100%;
  padding: 10px;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
.wrapper ul {
  width: 100%;
  list-style: none;
  display:-moz-box;
  display:-webkit-box;
  box-shadow: 0 0 5px #666;
  border-radius: 5px;
  border: 1px solid #fff;
}
.wrapper ul li {
  -moz-box-flex:1.0;
  -webkit-box-flex:1.0;
  text-align: center;
  background: -moz-linear-gradient(top, #999 50%, #666 50%);
  background: -webkit-gradient(linear,left top,left bottom, color-stop(0.5, #999),color-stop(0.5, #666));
  border-right: 1px solid #ccc;
}
.wrapper ul li:hover {
  background: -moz-linear-gradient(top, #666 50%, #333 50%);
  background: -webkit-gradient(linear,left top,left bottom, color-stop(0.5, #666),color-stop(0.5, #333));
}
.wrapper ul li:first-child {
  border-radius: 5px 0 0 5px / 5px 0 0 5px;
}
.wrapper ul li:last-child {
  border-radius: 0 5px 5px 0 / 0 5px 5px 0;
  border-right: none;
}
.wrapper ul li a {
  width: 100%;
  height: 100%;
  padding: 5px 0;
  display: block;
  font-size: 14px;
  color: #fff;
  text-decoration: none;
  text-shadow: 0 -1px 1px #333;
}
.wrapper4 ul li a:hover {
  text-shadow: 0 0 3px #fff;
}

デモ

 ↑ 角丸の太さが一定ではありません(> <) 最後に、このブログの幅いっぱいにしてみると、こうなります。
これでレスポンシブデザインじゃなかったら、お笑いですからね。
外側のdiv要素の幅を100%にするか、幅を指定しないでください。

いかがでしたでしょうか。

最近はいろんなプラグインも出ていたりするので、全部自力で書く必要もないと思いますが、
一つのテクニックとして、覚えておいて損はないと思いますので、
使う機会があった際には、テンプレート的に使っていただければと思います。