「HTML」と「CSS」のみで作る グローバルナビメニュー

【JavaScriptを使用しない】「HTML」と「CSS」のみ グローバルナビメニュー ドロップダウン・三階層まで

Webサイトの主要ページへのリンクをまとめたグローバルナビメニューは、ユーザービリティを考慮したわかりやすい設計が求められます。サイトのページ数が多い場合は、ナビメニューに掲載できる表示範囲も限りがあるため、工夫が必要になってきます。

今回は、基本的なグローバルナビメニューの作成と、JavaScriptを使用しない「HTML」と「CSS」だけで設定可能な、比較的簡単なドロップダウン表示を実装していきます。また、子階層・孫階層までの三階層表示までを作成します。

ドロップダウン表示(2階層まで)

まず、2階層までのドロップダウン表示のサンプルを確認して動きを見てみましょう。

今回は、マウスオンでドロップダウン表示になるように設定しています。(Menu2)

2階層までコードサンプル

See the Pen Global navi menu - dropdown by web-basic-archive (@web-basic-archive) on CodePen.

HTMLの確認

それでは、HTMLの構造を見てみましょう。グローバルナビの部分は、下記のようになります。

<nav id="gnav">
    <ul>
        <li><a href="">Menu1</a></li>
        <li>
            <a href="">Menu2</a>
            <ul class="gnav_child"> <!-- ドロップダウン表示する子階層のメニュー -->
                <li><a href="">Child01</a></li>
                <li><a href="">Child02</a></li>
                <li><a href="">Child03</a></li>
                <li><a href="">Child04</a></li>
                <li><a href="">Child05</a></li>
            </ul>
        </li>
        <li><a href="">Menu3</a></li>
        <li><a href="">Menu4</a></li>
        <li><a href="">Menu5</a></li>
    </ul>
</nav>

ドロップダウンで表示する子階層の部分は、親階層の<li>の中に配置する基本的な構造です。

こちらをCSSでスタイルと、ドロップダウンの動作を付けていきます。

CSSのスタイリング

グローバルナビの部分のスタイルは下記になります。

/*グローバルナビメニュー*/
#gnav ul {
    list-style: none;
    padding-left: 0;
}
#gnav ul li a {
    text-decoration: none;
    display: block;
    width: 100%;
    height: 100%;
    text-align: center;
    color: #820184;
}
#gnav ul li a:hover {
    opacity: 0.7;
}
#gnav > ul {
    display: flex;
}
#gnav > ul > li {
    width: 6rem;
    position: relative;
    padding: 10px 0;
}
#gnav > ul > li > a {
    padding: 5px 10px;
}

/*子階層*/
.gnav_child {
    visibility: hidden; /*最初は非表示*/
    width: 100%;
    position: absolute;
    left: 0;
    top: 95%;
    background: #fff;
    -webkit-box-shadow: 0px 3px 10px 2px rgba(25, 26, 26, 0.3);
    box-shadow: 0px 3px 10px 2px rgba(25, 26, 26, 0.3);
    border-radius: 5px;
    z-index: 0;
    transition: all .5s cubic-bezier(0.075, 0.82, 0.165, 1); /*アニメーションの時間とイージング設定*/
    transform: scaleY(0); /*ドロップダウンアニメーションのために高さを0にしておく*/
    transform-origin: center top; /*transformの基準点を設定 上部中央*/
    opacity: 0; /*フェイドインのアニメーションのために透明度0にする*/
}

/*子階層ドロップダウン*/
#gnav > ul > li:hover .gnav_child { /*親階層の<li>にマウスオンしたとき*/
    visibility: visible; /*表示する*/
    opacity: 1; /*フェイドイン 透明度を1に*/
    transform: scaleY(1); /*ドロップダウン 高さを1に*/
}

/*子階層の▲の装飾*/
.gnav_child::before {
    content: "";
    display: block;
    position: absolute;
    top: -9px;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 10px 10px 10px;
    border-color: transparent transparent #fff transparent;
    filter: drop-shadow(0 0px 5px rgba(25, 26, 26, 0.3));
    z-index: -1;
}
.gnav_child li {
    background: #fff;
}

/*子階層の背景の角丸設定*/
.gnav_child > li:first-child {
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
}
.gnav_child > li:last-child {
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
}

.gnav_child a {
    padding: 10px 5px; 
}

この中で特に重要な、子階層のCSSについて確認していきましょう。

31行目:最初は非表示にするので、visibility: hidden; にしておきます。display: none;でも非表示になりますが、後にアニメーションの設定をするために、visibilityを使用します。

33行目:position: absolute;で絶対配置にしておきます。この時少し注意なのが、topの位置です。この後の設定で親階層のli要素にマウスオンした状態で、この子階層メニューが表示されるようにするのですが、子階層の配置が親要素の領域上にあると、マウスオン状態が維持されやすいので、topの位置を95%にしています。

41行目:ここからドロップダウンアニメーションの設定をしていきます。まずは、動作時間、イージングの設定を行います。

42行目:ドロップダウンの動きは、transformのscaleYを使用します。heightで動きをつける方法もありますが、scaleYを使用したほうが比較的簡単に設定ができます。初期は「0」にしておき、後のマウスオンの設定で通常の「1」に戻します。

43行目:transformの基準点を設定しておきます。上部中央の位置からアニメーションをスタートさせるので、center topになります。

44行目:フェイドインの効果も合わせて付けたいので、opacityで調整します。こちらも初期は「0」にしておき、後のマウスオンの設定で通常の「1」に戻します。

48行目以降:ここからマウスオンの設定をします。親要素の<li>にマウスオンした状態で、表示と各アニメーションを行うので、「.gnav > ul > li:hover .gnav_child」となります。

マウスオンとマウスアウトの状態をJavaScriptで設定する場合は、それぞれの場合について記述しなればなりませんが、CSSの疑似クラス「:hover」を使用すると、比較的容易に設定ができます。

子階層(2階層)まで設定できたので、次は孫階層(3階層)まで表示させてみましょう。

ドロップダウン表示(3階層)

3階層表示コードサンプル

孫階層表示の動きをサンプルで確認してみましょう。

子階層・Menu2の中の最初の<li>の中に、孫階層(.gnav_gchild)を配置しました。

マウスオンすると、今度は横からスライドインで表示されます。

See the Pen Global navi menu - dropdown(Three layers) by web-basic-archive (@web-basic-archive) on CodePen.

HTMLの確認(3階層)

孫階層の表示方法の考え方は、子階層の表示と同じです。

<nav id="gnav">
    <ul>
        <li><a href="">Menu1</a></li>
        <li>
            <a href="">Menu2</a>
            <ul class="gnav_child"> <!-- ドロップダウン表示する子階層のメニュー -->
                <li>
                    <a href="">Child01</a>
                     <ul class="gnav_gchild"> <!-- スライドインする孫階層のメニュー -->
                         <li><a href="">G-child01</a></li>
                         <li><a href="">G-child02</a></li>
                         <li><a href="">G-child03</a></li>
                         <li><a href="">G-child04</a></li>
                         <li><a href="">G-child05</a></li>
                     </ul>
                </li>
                <li><a href="">Child02</a></li>
                <li><a href="">Child03</a></li>
                <li><a href="">Child04</a></li>
                <li><a href="">Child05</a></li>
            </ul>
        </li>
        <li><a href="">Menu3</a></li>
        <li><a href="">Menu4</a></li>
        <li><a href="">Menu5</a></li>
    </ul>
</nav>

HTMLの構造は、階層が深くなっていきますが、入れ子関係のみ注意しておけば問題ないと思います。

CSSのスタイリング(3階層)

次に、追加した孫階層の部分のCSSを確認しましょう。

/*孫階層*/
.gnav_gchild {
    visibility: hidden;
    position: absolute;
    left: 100%;
    top: 0;
    width: 100%;
    -webkit-box-shadow: 0px 3px 10px 2px rgba(25, 26, 26, 0.3);
    box-shadow: 0px 3px 10px 2px rgba(25, 26, 26, 0.3);
    background: #fff;
    border-radius: 5px;
    z-index: 0;
    transition: all .5s cubic-bezier(0.075, 0.82, 0.165, 1);
    transform: scaleX(0);
    transform-origin: left top;
    opacity: 0;
}

/*孫階層のスライドイン*/
.gnav_child li:hover .gnav_gchild {
    visibility: visible;
    opacity: 1;
    transform: scaleX(1);
}

/*孫階層の◀の装飾*/
.gnav_gchild::before {
    content: "";
    display: block;
    position: absolute;
    top: 12px;
    left: -10px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 10px 10px 10px 0;
    border-color: transparent #fff transparent transparent;
    filter: drop-shadow(0 0px 5px rgba(25, 26, 26, 0.3));
    z-index: -1;
}

/*孫階層の角丸設定*/
.gnav_gchild > li:first-child {
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
}
.gnav_gchild > li:last-child {
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
}

スタイルの設定は、子階層とほぼ同じですが、マウスオンすると今度は横からスライドインさせるので、設定が変わってきます。

5~6行目:子階層の右横に表示させたいので、絶対配置の位置を調整します。今回はleft: 100%, top: 0 にしています。

14行目:子階層のドロップダウン表示の際は高さ(縦幅)をアニメーションさせましたが、今度は横からのスライドインなので、横幅を scaleX で調整します。transformの基準点も合わせて調整してください。

ここで表示スペース上の注意点ですが、Menu5など一番右端の子階層の孫階層の表示は、そのまま右側に出してしまうレイアウトから、はみ出してしまうので、折り返して左側に出すなどの変更が必要になります。その場合は、絶対配置の位置、transformの基準点をサイトデザインに合わせて調整してください。

グローバルナビメニューの表示方法は、今回のようにシンプルなテキストのみデザインのほかに、画像を組み込んで目立たしたり、画面に大きく表示させるメガメニューと呼ばれる方法もありますので、次の機会にご紹介していきたいと思います。

参考にしたサイト

JavaScript不要!CSSだけで出来るドロップダウンメニューの実装方法

Follow me!