<nav class="nav">
<div class="nav-container">
<ul class="nav-menu">
<li>
<a href="index.html" class="nav-link">ホーム</a>
</li>
<li class="nav-item-dropdown">
<a href="gallery.html" class="nav-link active">ギャラリー</a>
<ul class="dropdown-menu">
<li>
<a href="gallery-nature.html" class="dropdown-link active"
>自然</a
>
</li>
<li>
<a href="gallery-architecture.html" class="dropdown-link"
>建築</a
>
</li>
<li>
<a href="gallery-portrait.html" class="dropdown-link"
>ポートレート</a
>
</li>
<li>
<a href="gallery-abstract.html" class="dropdown-link">抽象</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
.nav-item-dropdown {
position: relative;
}
.dropdown-menu {
position: absolute;
left: 50%;
transform: translateX(-50%);
background-color: var(--color-white);
list-style: none;
padding: 10px 0;
min-width: 180px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
border-radius: 8px;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s ease;
}
.nav-item-dropdown:hover .dropdown-menu {
opacity: 1;
visibility: visible;
}
.dropdown-link {
display: block;
padding: 10px 20px;
color: var(--color-text);
text-decoration: none;
transition: background-color 0.3s ease, color 0.3s ease;
}
.dropdown-link:hover,
.dropdown-link.active {
background-color: var(--color-light-gray);
color: var(--color-accent);
}
const currentPage = window.location.pathname.split('/').pop() || 'index.html';
document.querySelectorAll('.nav-link').forEach((link) => {
link.classList.toggle('active', link.getAttribute('href') === currentPage);
});
CSS解説
1. .dropdown-menuの初期設定(「隠す」設定)`
| プロパティ | 説明 |
|---|---|
position: absolute; |
親要素(.nav-item-dropdown)を基準にして好きな位置に正確に配置できるようにします。 |
left: 50%; / transform: translateX(-50%);
|
メニューの中央を親要素の中央に合わせる、「中央揃え」のための設定です。 |
opacity: 0; |
透明度をゼロ(完全に透明)にして、メニューを画面から見えなくします。 |
visibility: hidden; |
マウス操作などができないように、メニュー自体を非表示にします。 |
transition: ... |
アニメーション(変化)の設定です。opacityやtransformの変化を0.3秒かけてなめらかに行います。 |
2..nav-item-dropdown:hover .dropdown-menuの設定(「表示する」設定)
| プロパティ | 説明 |
|---|---|
opacity: 1; |
透明度を1(完全に不透明)に戻し、メニューを見えるようにします。 |
visibility: visible; |
メニューを操作可能な状態にします。 |
opacityとvisibility
スムーズなフェードイン・フェードアウトを実現するには、以下の役割分担が必要です。
-
opacityの役割: スムーズな見た目の変化
| 設定 | 役割 | 備考 |
|---|---|---|
opacity: 0; |
要素を完全に透明にする。 |
transition を設定することで、透明度が 0 から 1 へ滑らかに変化し、フェードインアニメーションが生まれます。 |
opacity: 0 の問題点 |
要素が透明で見えなくても、クリックなどの操作はできてしまう(イベントが無効にならない)。 | マウスカーソルが透明なメニューの上を通過すると、意図しない挙動が起こる可能性があります。 |
-
visibilityの役割: 要素の操作を無効化
| 設定 | 役割 | 備考 |
|---|---|---|
visibility: hidden; |
要素を完全に非表示にし、その要素に対するクリックやマウスオーバーなどの操作(イベント)を無効化する。 |
opacity: 0 のときに、意図しないクリックを防ぐために使用します。 |
3. .dropdown-linkの設定
| 設定 | 役割 |
|---|---|
display: block; |
リンクの領域を行全体に広げて、クリックしやすくします。 |
padding: 10px 20px; |
リンクの上下左右に余白を作り、見た目を整えます。 |
4. .dropdown-link:hover, .dropdown-link.active の設定
ドロップダウン内のリンクにマウスが乗ったとき(:hover)、または現在アクティブなリンク(.active)のデザインを指定しています。
JavaScript
ユーザーが現在どのページを見ているか(「ホーム」「ギャラリー」など)を判断し、対応するメニュー項目にactiveクラスを付けて目印(ハイライト)を付ける役割を果たします。
処理のステップ解説
コードを3つのステップに分けて見ていきましょう。
1. 現在のページ名を取得する
const currentPage = window.location.pathname.split('/').pop() || 'index.html';
これは、今ブラウザで開いているファイルの名前(例: about.html や contact.html など)を知るための処理です。
-
window.location.pathname:ウェブサイトのアドレスのうち、ファイルパスの部分を取得します。(例:/portfolio/contact.html) -
.split('/'):パスをスラッシュ(/)で区切って、配列にします。(例:['', 'portfolio', 'contact.html']) -
.pop():配列の一番最後の要素(ファイル名)を取り出します。(例:'contact.html') -
|| 'index.html':もしファイル名が空っぽだった場合(トップページなど)、デフォルトで'index.html'とみなします。
結果: currentPage には、index.html や about.html のようなページファイル名が入ります。
2. すべてのナビゲーションリンクをチェックする
document.querySelectorAll('.nav-link').forEach((link) => {
// 処理
});
-
document.querySelectorAll('.nav-link'): HTMLの中で、class="nav-link"が付いているすべての要素(つまり、ナビゲーションメニューの各リンク)を探して集めます。 -
.forEach((link) => { ... }): 見つかったリンク一つ一つに対して、{}の中の同じ処理を繰り返し実行します。
3. 一致するかどうかを判定し、ハイライトする
link.classList.toggle('active', link.getAttribute('href') === currentPage);
これがハイライト処理の核となる部分です。
-
link.getAttribute('href'): リンクがどこへ飛ぶか(遷移先ファイル名)を取得します。 -
=== currentPage: リンクの遷移先(href)が、手順1で取得した現在のページ名(currentPage)と完全に一致するかどうかをチェックします。結果はtrue(一致した)かfalse(一致しなかった)のどちらかになります。 -
link.classList.toggle('active', ...):-
link.classListは、そのリンクに付いているクラス(目印)を操作するためのものです。 -
toggle('active', 条件)は非常に便利な機能です。-
条件が
trueの場合(つまり、今見ているページとリンク先が一致した!):リンクにactiveというクラス(目印)を追加します。 -
条件が
falseの場合(一致しなかった):リンクからactiveクラスを削除します。
-
条件が
-