5. レスポンシブ表示と CSS の責任範囲
デスクトップ表示では,サイトリンクとツールバーを横一列に配置し,ハンバーガーボタンを display: none で非表示にします。ビューポート幅が 768px 以下になるとハンバーガーボタンを表示し,サイトリンクとツールバーを全画面パネルへ移します。このブレークポイントは,VitePress で構築した Significant Bit のナビゲーションと共通です。
レイアウトトークン
サイトナビゲーションは,二つのカスタムプロパティを使用します。Docsify のベンダー CSS が定義する --navbar-height(4em)は,公式 Navbar の .app-nav を生成しないため使用しません。
:root {
--rt-site-nav-height: 64px;
--rt-layout-max-width: 90rem;
}--rt-site-nav-height
サイトナビゲーションの高さ,bodyのpadding-top,固定サイドバーとサイドバートグルのtopおよびheight,共有ボタンのtopに使用します。--rt-layout-max-width.eg-site-nav-innerの最大幅を定めます。デスクトップ表示では,内側に左右2remのパディングを設けます。ビューポート幅が 90rem を超える場合はサイドバー側にもガターを追加し,サイトナビゲーションのロゴ左端と本文のレイアウトを揃えます。
重ね順
通常時のサイトナビゲーションは z-index: 40 であり,共有ボタン(20)と未使用の公式 .app-nav(20)より上に配置します。メニュー展開時は,ヘッダー全体を Docsify のサイドバーと同じ z-index: 60 に引き上げ,高さを 100dvh にします。これにより,操作対象を記事目次からサイト横断メニューへ切り替えます。
ハンバーガーメニュー
ハンバーガーボタンはデスクトップ表示では非表示とし,768px 以下では display: flex !important によって表示します。!important は,Docsify の button スタイルより優先するために指定しています。クリック時の状態変更は setSiteNavOpen() が担います。
function setSiteNavOpen(header, open) {
var toggle = header.querySelector(".eg-site-nav-toggle");
header.classList.toggle("is-open", !!open);
if (toggle) {
toggle.setAttribute("aria-expanded", open ? "true" : "false");
}
document.body.classList.toggle("eg-site-nav-lock", !!open);
if (open) {
header.classList.remove("scrolled-down");
header.classList.add("scrolled-up");
}
}body.eg-site-nav-lock には overflow: hidden を設定し,メニュー展開中に背面の記事がスクロールすることを防ぎます。ハンバーガーの三本線は,CSS の変形によって閉じる操作を示す X へ変化します。メニューを開いた状態でビューポート幅が 768px を超えた場合は,resize イベントによってメニューを閉じます。Escape キーやパネル外のクリックによる閉じる処理は実装していません。パネル内のリンクはサイト間を移動する通常 URL であるため,リンクを選択すると Real Terms の単一ページアプリケーションから離れます。
768px 以下の .eg-site-nav-end は,64px のヘッダー直下に絶対配置する全幅パネルです。サイトリンクとツールバーは最大幅を 288px とし,水平方向の中央へ配置します。外観切替はラベル付きの行として表示し,その下に言語切替を配置します。デスクトップ表示でツールバーの左側に置く区切り線(.page-toolbar::before)は非表示にします。
Docsify のレイアウトオフセット
サイトナビゲーションを body の先頭へ固定配置するだけでは,本文とサイドバーがその背後に入ります。次の指定によって,サイトナビゲーションの高さに相当する領域を確保します。
body {
padding-top: var(--rt-site-nav-height);
}
body.sticky .sidebar {
top: var(--rt-site-nav-height);
height: calc(100% - var(--rt-site-nav-height));
}
body.sticky .sidebar-toggle {
top: var(--rt-site-nav-height);
height: calc(100% - var(--rt-site-nav-height));
}固定サイドバーとサイドバートグルは,top を 64px 下げ,高さから同じ値を差し引きます。これにより,サイトナビゲーションとの重なりを防ぎます。印刷時は,サイトナビゲーション,ツールバー,共有ボタン,フッターを非表示にし,body の padding-top を 0 に戻します。
責任範囲のまとめ
Docsify の責任範囲は次のとおりです。
- ハッシュルーティングと
auto2top loadSidebarによる_sidebar.md- サイドバー内の公式 search プラグイン
- 記事本文のレンダリング
独自実装の責任範囲は次のとおりです。
- サイト横断の固定ナビゲーション(
header.eg-site-nav) - サイトナビゲーション内の外観切替と言語切替
- スクロール時の表示制御とルート遷移後の再表示
- 768px 以下のハンバーガーメニューと
z-indexの調整
公式 Navbar(loadNavbar と _navbar.md)は使用しません。この機能はドキュメント内の補助的なナビゲーションには適していますが,サイト横断ナビゲーションとして必要な高さ,重ね順,レスポンシブ表示とは一致しません。Real Terms では,VitePress 側と共通するナビゲーションを Docsify のレンダリング領域外へ配置することで,両者の責任範囲を分離しています。