CSSのhover(マウスオーバー)でサブメニューを表示/非表示させる4つの方法

 2016.10.11  2017.09.20

「メニューの上にカーソルを乗せるとサブメニューが表示される」というよくある動き。 CSSのみ・CSSとjQueryを組み合わせる・jQueryのみなどなど、色々な方法があると思いますが、みなさんはどのように実装していますか?

対応ブラウザやレスポンシブの有無などによっても変わってくると思いますが、先日、自分がよく使う方法とは違ったCSSのみでの実装方法を目にしたので、今更過ぎますが以下にまとめてみました。

サンプル

以下のような動きを想定したHTMLとCSSを作成します。

hoverサンプル

共通HTML

<header class="sample01">
	<ul>
		<li><a href="#">Menu01 <span>▼</span></a>
			<ul>
				<li><a href="#">Sub-menu01</a></li>
				<li><a href="#">Sub-menu02</a></li>
				<li><a href="#">Sub-menu03</a></li>
			</ul>
		</li>
		<li><a href="#">Menu02</a></li>
		<li><a href="#">Menu03</a></li>
	</ul>
	</header>

共通CSS

/* Menu */

header{
	margin-bottom: 13em;
	position: relative;
	width: 100%;
	background-color: #444;
}
ul > li{
	display: inline-block;
}
ul > li > a{
	padding: 15px 30px;
	display: block;
	font-size: 0.8em;
	text-transform: uppercase;
	letter-spacing: .2em;
}
ul > li > span{
	margin-left: 1.2em;
}
ul > li:hover > a{
	background-color: #efefef;
	color: #444;
}

/* Submenu */

ul li ul{
	position: absolute;
	top: 55px;
	left: 0;
}
ul li ul li{
	display: block;
}
ul li ul li a{
	background-color: #efefef;
	color: #444;
}
ul li ul li a:hover{
	background-color: #ddd;
}

<header>のクラス名には下記のサンプル番号(samplexx)が入ります。

displayを使う方法 (sample01)

.sample01 ul li ul{
	display: none;
}
.sample01 ul li:hover ul{
	display: block;
}

「display」でサブメニュー全体(ul)を非表示にしておき、マウスオーバーで表示させる方法です。

heightを使う方法 (sample02)

.sample02 ul li ul li{
	height: 0;
	overflow: hidden;
}
.sample02 ul li:hover ul li{
	height: auto; /*サブメニューの高さ*/
	overflow: visible;
}

サブメニューの高さを0に指定して非表示にし、マウスオーバーで従来の高さに戻す方法です。

positionを使う方法 (sample03)

.sample03 ul li ul{
	position: absolute;
	top: -1000px;
}
.sample03 ul li:hover ul{
	top: 55px;
}

サブメニューを「position」でウィンドウの外に追い出して非表示にし、マウスオーバーで従来の位置に戻します。上記の例では非表示にするためにtopを-1000pxと指定していますが、メニューがページの上部にあれば少ない数値でも構いません。この辺はざっくりと指定してます。マウスオーバー時は、サブメニューを「position: relative;」と指定したheaderの左上を起点とするグローバルメニューの56px分下に表示させるという仕組みです。※高さ55pxというのもざっくり指定してしまったので、ブラウザによってはズレているかもしれません…。

trasformを使う方法

.sample03 ul li ul{
	position: absolute;
	top: -1000px;
}
.sample03 ul li:hover ul{
	transform: translateY(1055px);
	-ms-transform: translateY(1055px);/*IE9対策*/
}

sample03を元に書いていますが、ウィンドウの外へ追い出したサブメニューをCSS3の「transform」を利用してY軸(縦方向)に移動させて表示する方法です。1056pxというのは、グローバルメニューを上部に追い出した距離(1000px)とグローバルメニューの高さを足したもので、上から下へ移動するイメージです。「transform」はIE8は未対応、IE9はベンダープレフィックス(-ms-transform)で指定すれば表示されると思います。transitionなどで動きをつけてもよいですね。

各ブラウザの検証はあまりしていないのですが(汗)、考え方の参考になれば幸いです。

Pocket