CSSでドロップダウンメニュー

|

ドロップダウンメニューのようなダイナミックな動作はJavaScriptが得意としますが、CSSだけでも実装可能です。

JavaScriptを使用せず、CSSのみでドロップダウンメニューを作成するポイントは以下の3つ。

  1. postionプロパティ、displayプロパティを駆使する
  2. ダイナミック擬似クラスhoverを使用する
  3. 子セレクタを使用する

問題はIE6では、hoverはa要素しか適用範囲でないこと、さらに子セレクタも適用されないということです。

ie7-jsという、IE6でもa要素以外にも:hoverが使えたり子セレクタが使用できるスクリプトがあるので、それを利用することで代用が利きます。

今回はie7-jsを使用せず、どこまでできるかやってみたいと思います。

子孫セレクタを応用すると、IE6でも子セレクタと同様の動作するので、そちらのテクニックを使用します。以下のページを参考にしてください。

IE6でも子セレクタを使う - CSSデザインノート

hoverはダイナミックな動きですので、やはりJavaScriptを使用しなければなりません。簡単なのは、IEの独自拡張であるexpression() 関数を使用します。これはCSS内でJavaScriptコードを読み込めるものです。ただし、CSSの仕様にないものですので、ソースコードはinvalidになってしまいます。

完成サンプルは以下のとおりです。

サンプル

※ページの中にサンプルを記述しているため、ブラウザによっては正常に動作しない場合があります。ご了承ください。サンプルはWindows XPのIE6、Firefox3.5、Safari4.0.3、Opera9.64 、Chrome2.0で動作確認済みです。

基本のHTMLソースは以下のとおりです。メインメニューと3つのサブメニューを用意しました。

(X)HTMLコード

<div id="menu">
   <ul>
      <li><a href="#">menu1</a>
         <ul>
            <li><a href="#">submenu1</a></li>
            <li><a href="#">submenu2</a></li>
            <li><a href="#">submenu3</a>
               <ul>
                  <li><a href="#">submenu3-1</a></li>
                  <li><a href="#">submenu3-2</a></li>
                  <li><a href="#">submenu3-3</a>
                     <ul>
                        <li><a href="#">submenu3-3-1</a></li>
                        <li><a href="#">submenu3-3-2</a></li>
                        <li><a href="#">submenu3-3-3</a></li>
                     </ul>
                  </li>
               </ul>
            </li>
         </ul>
      </li>
     <li><a href="#">menu2</a>
         <ul>
            <li><a href="#">submenu4</a></li>
            <li><a href="#">submenu5</a></li>
         </ul>
      </li>
      <li><a href="#">menu3</a>
         <ul>
            <li><a href="#">submenu6</a></li>
            <li><a href="#">submenu7</a></li>
            <li><a href="#">submenu8</a></li>
            <li><a href="#">submenu9</a></li>
         </ul>
      </li>
   </ul>
</div>

最低限必要なCSSソースコードです。

CSSコード

/* メインメニュー */
#menu ul {
   display:block;
   list-style-type: none;
   margin:0;
   padding:0;
}

/* サブメニュー1段目 */
#menu ul ul{
   display:none;
   position:absolute;
   top:100%;
   left:0;
}

/* サブメニュー2段目以降 */
#menu ul ul ul {
   top:0;
   left:100%;
}

/* リスト */
#menu li {
   float:left;
}

#menu li li {
   clear:both;
}

#menu li:hover {
   position:relative;
}

#menu li:hover > ul {
   display: block
}

/* IE6用 */
* html #menu li {
   behavior: expression(
      this.onmouseover=new Function("this.className='column1'"),
      this.onmouseout=new Function("this.className=''"),
      this.style.behavior = 'none'
   );
}

* html #menu li li {
   behavior: expression(
      this.onmouseover=new Function("this.className='column2'"),
      this.onmouseout=new Function("this.className=''"),
      this.style.behavior = 'none'
   );
}

* html #menu li li li {
   behavior: expression(
      this.onmouseover=new Function("this.className='column3'"),
      this.onmouseout=new Function("this.className=''"),
      this.style.behavior = 'none'
   );
}

#menu .column1 {position:relative;}
#menu .column1 ul {display:block;}
#menu .column1 * ul {display:none;}

#menu .column2 {position:relative;}
#menu .column2 ul {display:block;}
#menu .column2 * ul {display:none;}

#menu .column3 {position:relative;}
#menu .column3 ul {display:block;}
#menu .column3 * ul {display:none;}

後半部分がIE6用のソースコードになります。

hoverの代わりにJavaScriptのonmouseoverイベントハンドラを使用しています。サブカテゴリの数だけliの入れ子の指定が必要です。

本来なら、「* html li」の指定だけでドロップダウンできるはずなのですが、その入れ子の「* html li li」、さらにその入れ子の「* html li li li」と指定が必要となります。

例えばメインのメニューのli要素にマウスが載ったときに.column1のスタイルが実行されるのですが、onmouseoverの適用範囲が表示されたサブメニューまで及びます。

サブメニューのサブメニューを表示したくても、onmouseoverのままなので、新しくonmouseoverイベントハンドラを呼び出す必要があります。そのため、サブメニューの数分expression()関数が必要になってしまいます。

もっとよい書き方があるのかもしれませんが、あまりJavaScriptに詳しくないので、これが私にとっての最善の書き方になります。

これだけでは味気ないのでデザインしていきます。ここでは簡単に背景と余白を体裁します。

CSSコード

/* デザイン */
#menu li {
   line-height:1.6em;
   text-align: center;
   background:#ddd;
}

#menu li li {
   text-align: left;
}

#menu li a{
   display: block;
   width:100px;
   text-decoration:none;
   color:#333;
   padding:0 10px;
}

#menu li:hover {
   background:#7BBA10;
   color:#333;
}

#menu .column1, #menu .column2, #menu .column3 {
   color:#333;
   background:#7BBA10;
}

この例のようにwidthとpaddingを同時に指定する場合は、HTMLファイルが「完全標準モード」になるようにDOCTYPE宣言を指定する必要があります。

例えば、XHTMLファイルなら、

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

などです。

ドロップダウンメニューはJavaScriptで実装したほうがよりリッチに

以上、CSSのみでドロップダウンメニューを作成しましたが、やはりJavaScriptのほうがよりスムーズで美しいドロップダウンメニューができるので、そちらがお勧めではあります。

参考までに素敵なJavaScriptで実装する素敵なドロップダウンメニューはこちら。

参考サイト

このページに関連する記事

CSSの小技に関する記事(53)

参考サイト

お勧めCSS教本

Powered by Movable Type 4.21-ja

最近のブログ記事