概要
前回、CSSでヘッダーメニューを上部に固定する方法を投稿しましたが、メニュー構造を多階層にしたい時もあるでしょう。
ということで、前回のコードを応用して多階層メニューの上部固定を行います。
この記事だけを見ても分かるように、前回と重複する説明ももう一度記載しておきます。
キーワード
position: sticky; display: flex;
サンプル
See the Pen ヘッダーメニューを上部に固定(多階層メニュー) by Tamamotch (@tamamotch) on CodePen.
解説
前処理
* {
margin: 0;
padding: 0;
}
デフォルトCSSの関係であちこちに隙間ができてしまうので上書きする。
指定した覚えのない謎の隙間がある場合はデフォルトCSSを疑うべし。
header
header {
position: sticky;
top: 0;
z-index: 100;
}
position: sticky;
header要素をスティッキーアイテムにする。
自動的に親要素であるbody要素がスティッキーコンテナになる。
これにより、header要素が貼り付く。
なお、スティッキーコンテナ内に兄弟要素がないときちんと貼り付かない仕様とのことなので、兄弟要素mainも用意する。
試しにmain要素を丸っと削除すると、スクロールと共にheader要素が流れていってしまうのが分かる。
top: 0;
貼り付く場所を最上部に固定する。
z-index: 100;
スクロールした時に全要素の上に重なるよう、適当な大きさを指定しておく。
親メニュー、子メニュー共通
.ul-menu,
.ul-submenu {
list-style-type: none;
text-align: center;
}
list-style-type: none;
リストのマーカーを削除する。
text-align: center;
テキストを左右中央寄せにする。
親メニュー
.ul-menu {
display: flex;
}
display: flex;
ul要素をflexコンテナにし、子要素liをflexアイテムにする。
これにより、子要素liが横並びになる。
.li-menu {
flex: 1;
position: relative;
}
flex: 1;
flexアイテムであるli要素の横幅を均等にする。
試しにこれを削除すると、li要素の横幅がそれぞれのテキスト幅になるのが分かる。
position: relative;
子メニューの位置決定のために設定しておく。
子メニュー
.ul-submenu {
position: absolute;
width: 100%;
visibility: hidden;
}
position: absolute;
親ボックスを基準に位置を決める。
そのためには、親ボックス(.li-menuクラス)にposition: relative;
を設定しておく必要がある。
これにより、親メニューの真下に子メニューが配置される。
width: 100%;
親ボックスと同じ横幅にする。
visibility: hidden;
非表示にする。
親メニュー > 子メニュー
.li-menu:hover > .ul-submenu {
visibility: visible;
}
visibility: visible;
li-menuクラス(li要素)にカーソルを合わせると、直下のul-submenuクラス(ul要素)を表示する。
クリック範囲
a {
display: block;
text-decoration: none;
padding: 10px 0 10px 0;
}
display: block;
表示形式をblockにする。
これにより、a要素のクリック範囲が親要素liのサイズと同じになる。
text-decoration: none;
見栄えのために、テキストの装飾(リンクの下線)を行わない。
padding: 10px 0 10px 0;
見栄えのために、上下に10px太らせる。
.a-1 { background-color: pink; }
.a-2 { background-color: moccasin; }
.a-3 { background-color: lightblue; }
.a-2_1 { background-color: orange; }
.a-2_2 { background-color: gold; }
.a-2_3 { background-color: yellow; }
background-color: xxx;
デモ時に分かりやすいように各範囲に色を付けておく。
main
main {
height: 500px;
}
height: 500px;
ある程度スクロールできるよう、高さを持たせておく。