個人サイト制作:サイトマップへ戻る

レスポンシブデザインに対応したグローバルナビゲーション

レスポンシブデザインに対応したグローバルナビゲーションとは、画面サイズやデバイスの種類に応じて柔軟に形を変えるナビゲーションメニューのことです。
大きなディスプレイでは横並びのメニューとして表示され、ユーザーが一目で全体構造を把握できるように設計されます。
一方でスマートフォンやタブレットのような小さな画面では、ハンバーガーメニューやドロワー形式に切り替わり、限られたスペースでも操作できるよう工夫しますよね。
こうした仕組みによって、同じサイトをどの環境から閲覧しても一貫した操作性が保たれ、ユーザーは迷うことなく目的のページへアクセスできます。
レスポンシブ対応のグローバルナビゲーションは、現代のWebにおいて必須の要素といえるでしょう。

…と、ここまでは教科書的な一般論なんですけど。
当サイトの場合、グローバルナビゲーションはそのままスマホでも小さめに表示されるようにしてあり、ハンバーガーメニューやドロワー形式のメニューは別途用意してあります。
1つのサイトに複数のカテゴリーがあるので、常にメインのサイトマップが目につくようにしてあるのです。

グローバルナビゲーションを作るためのhtml

普通のHTMLですから、特に難しいことはないです。


<nav class="den_nav">
  <ul>
    <li><a href="https://feinatelier.org/"><img src="/menu/mspass.webp" alt="このサイトのシンボルマーク" class="feinhome"></a></li>
    <li><a href="/" class="animated-link">ホーム</a></li>
    <li><a href="/another-eden/anaden_sitemap.html" class="animated-link">アナザーエデン</a></li>
    <li><a href="/fish/fish_sitemap.html" class="animated-link">アウトドアのエリア</a></li>
    <li><a href="/contents/site_create.html" class="animated-link">個人サイト制作</a></li>
    <li><a href="/contents/protect.html" class="animated-link">AI学習を防ぐ工夫</a></li>
    <li><a href="/contents/rss.html" class="animated-link">更新のお知らせ</a></li>
  </ul>
</nav>

唯一言えることがあるとすれば、あんまりグローバルナビゲーションに多くの項目を付けないようにしていますね。
当サイトであれば、カテゴリー分けされたサイトマップ+α程度。
その他はすべて他のメニューに委ねています。

グローバルナビゲーションを作るためのCSS

このCSSは「グローバルナビゲーション(上部メニュー)」の見た目と動きを作るためのものです。
主にリンクの下線アニメーション、半透明のナビ背景、ロゴのホバー効果、リストの横並びを実現しています。

基本の役割としては、次のような感じでしょうかね。

各ルールについて、ちょっと説明してみましょう。

リンクの見た目とアニメーション
.animated-link は文字色や太さ、色変化のトランジションを設定。transition: color 0.3sで色が滑らかに変わります。
.animated-link::after は絶対配置で要素の下に高さ2pxの線を作り、初期幅を0%にしておきます。ホバー時に幅を100%にすることで左から右へ伸びる下線アニメになります。
ナビ全体の背景と表示アニメ
.den_nav は半透明のグラデーション背景とバックドロップブラー(backdrop-filter)で背景をぼかす。角丸とパディングで見た目を整えています。
初期状態はopacity: 0translateY(-20px)で隠れており、.visibleを付けるとフェードインして下からスッと出る動きになります。
ロゴとリスト
.feinhome はロゴ画像のサイズとホバー時の拡大・影(drop-shadow)を設定。
.den_nav uldisplay: flexで横並びにし、flex-wrap: wrapで狭い画面では折り返します。リストの余白はliで調整。

疑似要素で装飾を追加するとHTMLを汚さずに表現できるんですよね。
transitiontransformで自然なアニメーションを作るようにしてます。
ただ、backdrop-filterで背景をぼかす時にはブラウザの対応状況だけ確認したほうが良いかも。
そろそろコードに移りますか。

グローバルナビゲーションを構成するheader.css


/* ★グローバルナビゲーションを構成する */
.animated-link {
 position: relative;
 color: #e3f2fd;
 font-weight: 500;
 text-decoration: none;
 transition: color 0.3s ease;
}

.animated-link:hover {
 color: #ffffff;
}

.animated-link::after {
 content: "";
 position: absolute;
 left: 0;
 bottom: -3px;
 width: 0%;
 height: 2px;
 background: linear-gradient(to right, #42a5f5, #80d8ff);
 transition: width 0.3s ease;
}

.animated-link:hover::after {
 width: 100%;
}

.den_nav {
 background: linear-gradient(to bottom, rgba(173, 216, 230, 0.5), rgba(173, 216, 230, 0));
 backdrop-filter: blur(12px);
 -webkit-backdrop-filter: blur(12px);
 padding: 12px 20px;
 border-radius: 20px;

 opacity: 0;
 transform: translateY(-20px);
 transition: opacity 0.8s ease, transform 0.8s ease;
}

.den_nav.visible {
 opacity: 1;
 transform: translateY(0);
}

.feinhome {
 width: 45px;
 transition: transform 0.3s ease, filter 0.3s ease;
}

.feinhome:hover {
 transform: scale(1.1);
 filter: drop-shadow(0 0 6px rgba(128, 216, 255, 0.6));
}

.den_nav ul {
 list-style-type: none;
 margin: 0;
 padding: 0;
 display: flex;
 flex-wrap: wrap;
}

.den_nav ul li {
 margin-right: 20px;
 margin-bottom: 10px;
}

.den_nav ul li a {
 color: #1A73E8;
}

.den_nav ul li a:hover {
 color: #0078D4;
}
グローバルナビゲーションのリンク装飾

.animated-link {
  position: relative;
  color: #e3f2fd;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.3s ease;
}
position
親要素としての位置基準を作ります。後で使う「::after」の線を、この要素を基準に配置できます。
color
文字色を薄い水色にします。優しく見える初期色です。
font-weight
文字の太さをやや太めにします。見出しリンクとして少し強調されます。
text-decoration
デフォルトの下線を消します。代わりに擬似要素で線を作ります。
transition
文字色が変わるときのアニメ時間と動き方を指定します。0.3秒でなめらかに変わります。

.animated-link:hover {
  color: #ffffff;
}
hover時のcolor
マウスを乗せると白に変わります。コントラストが上がり、アクティブ感が出ます。

.animated-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 0%;
  height: 2px;
  background: linear-gradient(to right, #42a5f5, #80d8ff);
  transition: width 0.3s ease;
}
content
空の内容で擬似要素を作ります。線の箱を用意するイメージです。
position
擬似要素をこのリンクの中で絶対配置します。親のrelativeが基準になります。
left
左端に揃えます。線の開始位置です。
bottom
テキストの少し下に配置します。-3pxで文字の下から少し離します。
width
初期幅を0%にします。最初は線が見えません。
height
線の太さを2pxにします。細めの下線です。
background
右方向に向かうグラデーションの色です。青からライトブルーへ変化します。
transition
幅が変わるときのアニメ設定です。0.3秒でスッと伸びます。

.animated-link:hover::after {
  width: 100%;
}
hover時のwidth
マウスを乗せると線が左から右へ100%まで伸びます。ホバーの気持ちよさを演出します。
グローバルナビ本体の見た目と表示アニメ

.den_nav {
  background: linear-gradient(to bottom, rgba(173, 216, 230, 0.5), rgba(173, 216, 230, 0));
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding: 12px 20px;
  border-radius: 20px;

  opacity: 0;
  transform: translateY(-20px);
  transition: opacity 0.8s ease, transform 0.8s ease;
}
background
上から下に薄い水色の透明グラデーション。ガラス風の柔らかい背景になります。
backdrop-filter
背景全体を12pxぼかします。半透明のガラス効果です。
-webkit-backdrop-filter
SafariなどWebKit用の互換指定です。同じぼかしを効かせます。
padding
内側の余白を上下12px、左右20pxにします。中身が詰まり過ぎないようにします。
border-radius
角を20px丸めます。やさしい印象のカード形状です。
opacity
初期は透明にします。後でクラス切り替えでフェードインします。
transform
初期位置を上に20pxずらします。出現時に下へスライドさせます。
transition
透明度と位置の変化を0.8秒でなめらかにします。フェード+スライドのアニメを統合します。

.den_nav.visible {
  opacity: 1;
  transform: translateY(0);
}
visible時のopacity
完全に表示します。0から1へフェードインします。
visible時のtransform
縦位置を元に戻します。上からふわっと降りてくる感じになります。
ホームアイコン(お魚マーク)のホバー演出

.feinhome {
  width: 45px;
  transition: transform 0.3s ease, filter 0.3s ease;
}
width
画像やアイコンの幅を45pxに固定します。ナビに収まりやすいサイズです。
transition
拡大と影の変化を0.3秒で同期させます。反応が自然になります。

.feinhome:hover {
  transform: scale(1.1);
  filter: drop-shadow(0 0 6px rgba(128, 216, 255, 0.6));
}
transform
マウス乗せで1.1倍に拡大します。クリックしたくなる視覚的誘導です。
filter
明るい水色の発光風ドロップシャドウを付けます。存在感を軽く強調します。
ナビ内のリストレイアウト

.den_nav ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
}
list-style-type
デフォルトの黒点などの箇条書き記号を消します。ナビに不要な装飾を外します。
margin
外側余白をゼロにします。親との空き調整をCSSで統一します。
padding
内側余白もゼロにします。行頭のずれをなくします。
display
フレックスボックスで横並びのレイアウトにします。ナビ項目を並べやすくします。
flex-wrap
横幅が狭いときは折り返します。スマホでのレイアウト崩れを防ぎます。

.den_nav ul li {
  margin-right: 20px;
  margin-bottom: 10px;
}
margin-right
項目同士の横の間隔を20px空けます。詰まりを防ぎます。
margin-bottom
折り返したときの縦の間隔を10px確保します。複数段でも読みやすくします。
ナビのリンク色とホバー

.den_nav ul li a {
  color: #1A73E8;
}
color
通常時のリンク色を鮮やかなブルーにします。ブランド感や可読性を両立します。

.den_nav ul li a:hover {
  color: #0078D4;
}
hover時のcolor
少し深いブルーに切り替えます。ホバーで状態変化を明確に伝えます。

次はブログ用のCSSを掲載しますが、これは単に色を変えただけで、他の機能的な部分は全て同じですよ。

ブログ用のグローバルナビゲーションを構成するheader.css


/* ★ブログ用のグローバルナビゲーションを構成する */
.animated-link_blog {
 position: relative;
 color: #1A73E8;
 font-weight: 500;
 text-decoration: none;
 transition: color 0.3s ease;
 font-size: 0.95em;
}

.animated-link_blog:hover {
 color: #0d47a1;
}

.animated-link_blog::after {
 content: "";
 position: absolute;
 left: 0;
 bottom: -3px;
 width: 0%;
 height: 2px;
 background: linear-gradient(to right, #42a5f5, #80d8ff);
 transition: width 0.3s ease;
}

.animated-link_blog:hover::after {
 width: 100%;
}

.den_nav_blog {
 background: linear-gradient(to bottom,
   rgba(255, 165, 0, 0.15),
   rgba(255, 165, 0, 0));
 backdrop-filter: blur(14px);
 -webkit-backdrop-filter: blur(14px);
 border-radius: 20px;
 padding: 12px 20px;

 opacity: 0;
 transform: translateY(-20px);
 transition: opacity 0.8s ease, transform 0.8s ease;
}

.den_nav_blog.visible {
 opacity: 1;
 transform: translateY(0);
}

.feinhome {
 width: 45px;
 transition: transform 0.3s ease, filter 0.3s ease;
}

.feinhome:hover {
 transform: scale(1.1);
 filter: drop-shadow(0 0 6px rgba(66, 133, 244, 0.5));
}

.den_nav_blog ul {
 list-style-type: none;
 margin: 0;
 padding: 0;
 display: flex;
 flex-wrap: wrap;
}

.den_nav_blog ul li {
 margin-right: 20px;
 margin-bottom: 10px;
}

.den_nav_blog ul li a {
 color: #1A73E8;
}

.den_nav_blog ul li a:hover {
 color: #0d47a1;
}

次はJavaScriptの解説ですが、グローバルナビゲーションのものは大したことやってないから、そんなに長くはならないです。

グローバルナビゲーションを作るためのJavaScript

このスクリプトが何をしているかというと、まずはナビが画面に見えたら visible クラスを付け、見えなくなったら外しています。
IntersectionObserver が「画面との交差」をイベントのように教えてくれるようになってる。
フェードイン・スライドインなどのCSS演出を、見えるタイミングで発火させているわけですね。
さっそくスクリプトを見ていきましょう。


// グローバルナビゲーションの動き
document.addEventListener("DOMContentLoaded", () => {
const nav = document.querySelector(".den_nav");

const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
nav.classList.add("visible");
} else {
nav.classList.remove("visible");
}
});
});

observer.observe(nav);
});
    
DOM の準備ができたら実行
イベント登録
document.addEventListener("DOMContentLoaded", () => {
ページのHTMLが読み込まれて、要素が使える状態になったタイミングで、中の処理を実行します。画像などの読み込み完了は待たず、HTMLだけ準備されたら動きます。
ターゲット要素を取得
要素取得
const nav = document.querySelector(".den_nav");
クラス名 den_nav の要素(グローバルナビ)をページから1つ探して取得します。見つかった要素を nav という変数に入れます。
交差監視(IntersectionObserver)を作成
オブザーバー作成
const observer = new IntersectionObserver(entries => {
画面(ビューポート)と対象要素が「交差しているか」を監視する仕組みを作ります。交差状況が変わるたびに、後ろの関数が呼ばれます。
コールバック引数
entries => {
監視結果の配列 entries が渡されます。配列の中には、監視中の各要素の状態(見えているかなど)が入っています。
監視結果を1つずつ処理
ループ
entries.forEach(entry => {
監視対象(ここでは nav)ごとの状態を1件ずつ取り出して処理します。
可視判定
if (entry.isIntersecting) {
対象要素が画面内に入っている(交差している=見えている)かを判定します。見えていれば true です。
表示用クラス付与
nav.classList.add("visible");
画面に見えているとき、ナビ要素に visible というクラスを付けます。CSS側でこのクラスにアニメーションや不透明度変更などを設定しておくと「見えたときの動き」が実現できます。
クラス除去
} else { nav.classList.remove("visible"); }
画面から外れた(見えていない)ときは、visible クラスを外します。これで「隠れているときの状態」に戻せます。
コールバック終了
});
1件の監視結果処理を終えます。
オブザーバー作成終了
});
IntersectionObserver の設定を終えます。
監視を開始
監視開始
observer.observe(nav);
先ほど取得したナビ要素 nav を監視対象として登録します。これで、ナビが画面に入る/出るたびに上の判定とクラス付けが動きます。
DOMContentLoaded の関数終了
終了括弧
});
「DOMが読み込まれたら実行する」関数の終わりです。ここまでの処理が、ページ読み込み直後にセットされます。

他に何かあるかなー…
一応補足としてお話しするなら、次のようなポイントがあるかも。

CSSが鍵
visible クラスに対して、例として opacity: 1; transform: translateY(0); transition: .3s; などのスタイルを用意すると、見えた瞬間にふわっと表示できます。初期状態(den_nav)側では opacity: 0; transform: translateY(-8px); のようにしておくと、切り替えがわかりやすいです。
安全対策
.den_nav が存在しない場合は observer.observe(nav); でエラーになります。初心者向けには、if (!nav) return; を要素取得直後に入れると安心です。
細かい設定
IntersectionObserver はしきい値やルート余白も設定できます(例: new IntersectionObserver(cb, { threshold: 0.5 }) で半分見えたら発火)。動きのタイミングを調整したいときに便利です。

次はブログ用のJavaScriptですが、これはden_nav_blogの部分が違うだけで、カラーの異なるCSSに合わせているだけです。


// ブログ用グローバルナビゲーションの動き
document.addEventListener("DOMContentLoaded", () => {
const nav = document.querySelector(".den_nav_blog");

const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
nav.classList.add("visible");
} else {
nav.classList.remove("visible");
}
});
});

observer.observe(nav);
});
    

このようにして、当サイトのグローバルナビゲーションはCSSとJavaScriptが連携して動いているわけです。
一口にグローバルナビゲーションといってもいろんなデザインパターンや動きがあると思うから、以前に使っていたコードも残しておきますね。


サイトマップ

全ページをリスト化したサイトマップも用意していますが、けっこうなページ数があります。
下記の「カテゴリー分けサイトマップ」のほうが使いやすいでしょう。

アナザーエデン関連ページ・サイトマップ
アナザーエデンの強敵戦やストーリーコンテンツのリスト、お勧めバッジなどを掲載したコーナーです。
期間限定のない普通のRPGですので、初心者でも安心して続けていけるゲームとなっています。
もっとも重要なグラスタについては、場所別に網羅した表があります。

個人サイトのホスティングとコンテンツ作成
個人でウェブサイトを作るなら時間をかけて。
HTML・CSS・JavaScriptの書き方はもちろん、無料かつ広告なしでホームページを作る方法を掲載したコーナーです。
Webデザインやレイアウトについても書いてあります。

魚釣りなどアウトドアのエリア
ゲームとパソコンだけじゃなく、アウトドアも趣味なんです。
このコーナーでは魚釣りの記録とか、魚料理のレシピ、はたまたサイクリングなどなど。
アウトドアに関連するコンテンツが詰め込まれています。