CSSでドロップダウンメニューを上に開く方法をお伝えしたいですが、その前にドロップダウンを上に開くって変ですね。
白い黒板みたいな感じです。黒いホワイトボードの方が近いかな?
そんなことはさておき、ドロップダウンメニューを上に開きたいという需要はかなり少ないかもしれません。
でも、そういった場合もあるかもしれないのでやってみました。
CSSでドロップダウンメニューを上に開く方法
まず、メニュー部分のHTMLです。
<nav id="footerrnav">
<ul class="gmenu">
<li>
<a href="https://swell.dev-lib.work">メニューA</a>
<ul>
<li><a href="https://swell.dev-lib.work">メニューA-1</a></li>
<li><a href="https://swell.dev-lib.work">メニューA-2</a></li>
<li><a href="https://swell.dev-lib.work">メニューA-3</a></li>
<li><a href="https://swell.dev-lib.work">メニューA-4</a></li>
</ul>
</li>
<li>
<a href="https://swell.dev-lib.work">メニューB</a>
<ul>
<li><a href="https://swell.dev-lib.work">メニューB-1</a></li>
<li><a href="https://swell.dev-lib.work">メニューB-2</a></li>
<li><a href="https://swell.dev-lib.work">メニューB-3</a></li>
<li><a href="https://swell.dev-lib.work">メニューB-4</a></li>
</ul>
</li>
<li>
<a href="https://swell.dev-lib.work">メニューC</a>
<ul>
<li><a href="https://swell.dev-lib.work">メニューC-1</a></li>
<li><a href="https://swell.dev-lib.work">メニューC-2</a></li>
<li><a href="https://swell.dev-lib.work">メニューC-3</a></li>
<li><a href="https://swell.dev-lib.work">メニューC-4</a></li>
</ul>
</li>
<li>
<a href="https://swell.dev-lib.work">メニューD</a>
<ul>
<li><a href="https://swell.dev-lib.work">メニューD-1</a></li>
<li><a href="https://swell.dev-lib.work">メニューD-2</a></li>
<li><a href="https://swell.dev-lib.work">メニューD-3</a></li>
<li><a href="https://swell.dev-lib.work">メニューD-4</a></li>
</ul>
</li>
<li>
<a href="https://swell.dev-lib.work">メニューE</a>
<ul>
<li><a href="https://swell.dev-lib.work">メニューE-1</a></li>
<li><a href="https://swell.dev-lib.work">メニューE-2</a></li>
<li><a href="https://swell.dev-lib.work">メニューE-3</a></li>
<li><a href="https://swell.dev-lib.work">メニューE-4</a></li>
</ul>
</li>
</ul>
</nav>
そして、修正前のCSSです。
/* メニュー */
ul.gmenu {
margin: 0;
padding: 0;
background-color: #000000;
}
ul.gmenu > li {
display: inline-block;
padding: 5px;
font-weight: bold;
}
ul.gmenu > li a {
color: #ffffff;
}
/* サブメニュー */
ul.gmenu ul {
display: none;
}
ul.gmenu > li:hover ul {
display: block;
height: auto;
position: absolute;
background-color: #000000;
padding: 5px;
margin-left: -5px;
}
ul.gmenu ul > li {
display: block;
padding: 5px;
}
ul.gmenu li:hover {
background-color: #666666;
}
今回問題になっているのは画面の一番したの部分です。
下の画像の赤枠の部分です。

修正前の画面はこちらになります。
[btn class=”simple”]修正前のサンプル画面[/btn]
現在のメニューの状態や、HTMLやCSSの作り方については以前に作成した記事を参照ください。
このメニューにマウスカーソルをあてると下に子メニューがプルダウンで開いてしまい、画面がガタガタいいます。
これに対し、追加したCSSです。
/* フッターメニュー 上に開く */
#footerrnav ul.gmenu > li {
position: relative;
}
#footerrnav ul.gmenu > li:hover ul {
bottom: 34px;
white-space: nowrap;
}
これで上にむかってメニューが開き、画面の下に隠れたりガタガタいいません。
[btn class=”simple”]修正後のサンプル画面[/btn]
CSSの内容は次に解説します。
CSSの解説
通常上に開くということが無いためか、ちょっと強引に作った部分があります。
しかしちゃんと上に開いているので良しとしましょう!(←自分で言う)
ヘッダーのメニューと区別する
メニュー用のCSSは1つで、ヘッダーとフッターのメニュー両方に反映されるようにID指定はせずクラスで対応しています。
そのせいで下のメニューの子メニューもドロップダウンになり画面の下限を超えてメニューが開くようになってしまいました。
そこで、今回の修正はフッターのメニューにだけ適用するためにCSSのセレクタに #footerrnav をつけています。
これによりヘッダーメニューには適用されずフッターメニューにだけ適用されるようになります。
上に開くようにボトムを設定する
ドロップダウンメニューを作成する記事でも紹介しましたが、修正前CSSの25行目で position: absolute; を指定することにより、表示場所を指定しています。
position: absolute; は通常 top や left などを指定して表示位置を固定させるのですが、何も指定しないと本来表示されるはずの位置で固定表示されます。
今回のメニューで言うと親メニューの項目のすぐ下になります。
そして、修正前CSSの19行目で初期状態では非表示にし、23行目で親メニューの項目にマウスカーソルがあたったときに表示するようにしています。
何も指定しないと下に表示されるので、上に表示されるために position: absolute; に対し bottom プロパティで子メニューの底辺の位置を指定することにします。
ここで問題なのが値に何を指定すればよいのかということです。
0 を指定すると親メニューの底辺と同じ高さから上に表示されるようになるため、親メニュー上辺とを指定しなければいけません。
つまりメニューの高さと同じ値です。
メニューの高さを調べる方法は長くなるので割愛します。
今回の場合はメニューの高さは34ピクセルだったので bottom: 34px; と指定しました。(追加したCSSの6行目です。)
しかしこれだとメニューとか関係なしに、表示された画面の一番下から34px上に表示されるようになってしまいます。
その対応は次です。
表示位置を親メニューの項目に合わせる
追加したCSSの3行目で、position: relative; を指定しています。
セレクタは #footerrnav ul.gmenu > li なので、フッターの親メニューの各項目に対する設定になります。
フッターの親メニューの各項目に対し、表示位置の基準を設定することで、上で設定した bottom が画面の一番下では無くメニューの底辺からになります。
position は、表示位置を指定するためのプロパティです。
relative は、表示位置の基準になるための値です。通常はこれ単体で使うことはなく、relative を指定した子要素で absolute を指定し、relative を指定した要素を基準として absolute を指定した要素の表示位置を決定します。
今回は追加したCSSの6行目で bottom を使い表示位置を指定しています。
追加したCSSの中には absolute を設定する記述はありませんが、実は修正前のCSSの25行目で子メニューの absolute を指定しています。
ここは難しい内容かもしれませんが、慣れれば簡単です!
諦めずに実践を繰り返し、なんとなくで良いので理解しておくべきCSSの知識です。
ここまで対応すればほぼ完成ですが、まだ問題があります。それは次で説明します。
折り返さないようにする
ここまでの対応だけでは、下の画像の赤枠のようにメニューが改行されて不細工な表示をされてしまいます。
これは、position: relative; が原因です。
relative を指定すると、それを横にはみ出せなくなるようです。
横にはみ出さないようにする対応では非常に有効ですが、改行してしまうと不細工な子メニューになってしまうのでそれを改善します。

改善方法は、追加したCSSの7行目 white–space: nowrap; です。
ちょっと長くなってしまったのであまり詳しくは書けませんが、改行をしないようにするための設定方法です。
名前などあまり改行して表示されたく無い文字があると思います。
その場合にこれを使うと改行されず、強引に1行で表示してくれます。
(表示エリアが少ない場合ははみ出てしまいますが・・・)
この設定をすると下の画像のようになります。

まとめ
上に開くために底辺の位置を指定し、それより上に表示されるようにする。
底辺の基準位置を指定するために親メニューの項目に対し、表示位置の基準となる設定をする。
表示位置の基準を指定すると横幅も基準項目と同じ幅になって変に改行されてしまうため、改行されないように設定する。
bottom の値を指定するところや、改行させない設定をするところなど多少強引な方法かもしれませんが、これで上に開くメニューが出来ました。
今回は、position プロパティの良い勉強になったかと思います。
次はコンテンツエリアを少し細くしてサイドバーを表示してみようと思います。










コメント