トップページ > 便利な小技 > プルダウンメニュー

CSSレイアウト[便利な小技]

プルダウンメニュー

プルダウンメニューは、CSSだけでなく、簡単なJavaScriptも組み合わせて作る。

CSSの「visibility」プロパティと、そのON, OFF用のJavaScriptを使用する。
プルダウンさせるメニューをあらかじめCSSで「visibility: hidden」にしておき、親メニューにロールオーバーするとJavaScriptによってプルダウンメニューが「visible」、ロールアウトすると「hidden」に戻るようにする。要は、CSSを操作するJavaScriptを書くわけ。

プルダウンメニューの作り方[1]まずメニューセットを作る

図説 まず全体を囲むボックス(ここではsample)の中に、
親メニューと、それをロールオーバーすると出てくるサブメニューを1セットとしてボックスで囲む(ここではmainmenu)。
サブメニューの固まり(ここでは#sample .mainmenu ul)にはvisibility: hidden」を指定する。
この親とサブメニューのセットを「float: left;」で並べる。

下記はCSSの抜粋。
#sample { width: 420px; }
#sample .mainmenu { width:100px; float:left; }
#sample .mainmenu ul { margin: 0px; padding: 0px; visibility:hidden; }
#sample .mainmenu li a{ 略(リンク通常時のborderや背景色などデザイン指定をする)}
#sample .mainmenu li a:hover{ 略(ロールオーバー時のデザイン指定をする)}

この段階でブラウザチェックすると、親メニューが1列に並んでいるだけで、サブメニューは表示されない。

プルダウンメニューの作り方[2]JavaScriptを書く

次に、隠れているサブメニューを、親メニューにロールオーバーしたら「visible」にするJavaScriptを作る。その考え方は次の通り。

図説 このサンプルでは、親メニューはh4要素、サブメニューはul要素。
親メニューにロールオーバーしたら、その子であるulが表示されるようにする。そこで、ulにはそれぞれを区別するための名前を付ける必要がある。

例えば、いちばん左の「サービス案内」にロールオーバーすると、その子である「pull1(ul要素)」が表示され、親からロールアウトすると「pull1」は非表示になるようにする。

これだけだと「pull1」の上にカーソルがある時、親からロールアウトしているので、この「pull1」が非表示になってしまい何も選べない。だから、「pull1」自身にも、「ロールオーバーしている時は「pull1」を表示し、ロールアウトで「pull1」を非表示」の指令(親のと全く同じ)を与える。

ということで、
「pull1」に対してなら「"pull1"を表示」と「"pull1"を非表示」という2つのJavaScriptを作る。

下記はこのページのJavaScriptの抜粋。

function pDown1() { document.getElementById('pull1').style.visibility='visible'; }
    ↑ファンクション「pDown1」は、pull1のスタイルvisibilityをvisibleにする
function pHide1() { document.getElementById('pull1').style.visibility='hidden'; }
    ↑ファンクション「pHide1」は、pull1のスタイルvisibilityをhiddenにする

    引き続き↓「pDown2」「pHide2」として「pull2」の表示・非表示を指定する。
function pDown2() { document.getElementById('pull2').style.visibility='visible'; }
function pHide2() { document.getElementById('pull2').style.visibility='hidden'; }
(引き続き、ID'pull3'用、ID'pull4'用を作っていく。)

HTMLをスッキリさせるために外部JavaScript書類を作り、HTMLの<head>部にリンクさせる。リンクのタグは以下の通り。
<head>
<script type="text/javascript" src="../js/pulldown.js"></script>
</head>

プルダウンメニューの作り方[3]HTML上で「ul」にidを与える

HTML上で「ul」に、pull1、pull2の名前を付ける(JavaScript上で使ったもの。くれぐれもタイプミスに注意)。これはidでを与える。
そして、親であるメニューボタンと子である「ul」に、「onMouseOver」と「onMouseOut」のファンクションを指定する。これで完成。

HTMLは下記の通り。
<div id="sample">
<div class="mainmenu">
<h4 id="menu1"><a href="#" onMouseOver=pDown1(); onMouseOut=pHide1();>サービス案内</a></h4>
<ul id="pull1"; onMouseOver=pDown1(); onMouseOut=pHide1();>
<li><a href="#">フラワーアレンジ</a></li>
<li><a href="#">店舗検索</a></li>
<li><a href="#">キャンペーン情報</a></li>
<li><a href="#">フラワースクール</a></li>
</ul>
</div><!-- END mainmenu-->
<div class="mainmenu">
<h4 id="menu2"><a href="#" onMouseOver=pDown2(); onMouseOut=pHide2();>プレスリリース</a></h4>
<ul id="pull2"; onMouseOver=pDown2(); onMouseOut=pHide2();>
<li><a href="#">2008年</a></li>
<li><a href="#">2007年</a></li>
<li><a href="#">2006年</a></li>
</ul>
</div><!-- END mainmenu-->
<div class="mainmenu">
<h4 id="menu3"><a href="#" onMouseOver=pDown3(); onMouseOut=pHide3();>企業案内</a></h4>
<ul id="pull3"; onMouseOver=pDown3(); onMouseOut=pHide3();>
<li><a href="#">企業概要</a></li>
<li><a href="#">企業理念</a></li>
<li><a href="#">関連企業</a></li>
<li><a href="#"><span style="letter-spacing:2em;">沿革</span></a></li>
<li><a href="#">店舗紹介</a></li>
</ul>
</div><!-- END mainmenu-->
<div class="mainmenu">
<h4 id="menu4"><a href="#" onMouseOver=pDown4(); onMouseOut=pHide4();>企業案内</a></h4>
<ul id="pull4"; onMouseOver=pDown4(); onMouseOut=pHide4();>
<li><a href="#">新卒採用</a></li>
<li><a href="#">中途採用</a></li>
<li><a href="#">短期スタッフ</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</div><!-- END mainmenu-->
<div class="c-both"></div>
</div><!-- END sample-->
実際に使う時は「position:absolute」で配置する

このページ上にあるサンプルは、本文の中に組み込んでいる都合で、メニューボタン下に空きがある(プルダウンするメニューのスペース分の空き)。
実際の使用時にはこのサンプル全体を囲むボックスに「position: absolute」を指定する。そうすれば下の空きが無くなる。
「position:absolute」は絶対位置指定。この指定をすれば、他の要素と切り離され、他に影響をいっさい与えなくなる。 「position:absolute」についてはこちらを参照に。

「visibility:hidden」と「display:none」の違い

「visibility:hidden」←その要素を隠す(見えない状態にする。領域は確保する)
「display:none」←その要素を無くす(領域も無い)

このプルダウンメニューを作るのに、CSSの「visibility:hidden」と「display:none」のどちらが最適かというと、結局どちらも同じ。

ただ、「display:none」にすると、平常時(ロールアウト時)メニューの下にスペースは空かない(「position:absolute」の指定をしていなくても)。
ただし、ロールオーバーでサブメニューを表示した時、下の要素がどっと繰り下がることになり、みっともない。表示されたサブメニューが後続のボックス要素に影響を与えるから。
なので、やはり「position:absolute」を指定する必要がある。

サブメニューが表示された時、下の要素がグッと下がる効果を、あえて利用しても面白そう、という場合は「display:none」で「position:absolute なし」に。
ちなみに「display:none」の対照値は「display:block」を使うと良い。