【Bootstrap5 テンプレート】サイドメニュー(縦メニュー)の作成:非表示機能付き
2022.02.09 /
本記事ではBootstrap5を使用したサイドメニュー(縦メニューバー)の作成方法について解説していきます。
仕事で利用するようなWebアプリケーションでは縦型のサイドメニューを利用することが多いです。
しかし画面上部にある横メニューの作成方法はよく見かけますが、縦型のサイドメニューの作成方法はなかなかWeb上では見かけません。
そこでテンプレートの作成を通してサイドメニューの作成について解説していきます。
またサイドメニューはボタンの押下で表示・非表示する機能をJavaScriptで追加します。
作成するテンプレート
本記事で作成するBootstrap5によるWebアプリケーション用テンプレートは次図のようになります。
三本線のボタンを押すことでサイドメニューが非表示になります。
それでは次項よりこのテンプレートの作成方法を一つずつ解説していきます。
ページの高さを画面いっぱい(100%)にする
ここで作成するページは高さが画面いっぱい(100%)にして、スクロールがbody要素上で行われないようにします。
そのためhtml要素とbody要素にSizingユーティリティの高さ設定のクラスであるh-100クラスを追加します。
<html class="h-100">
<body class="h-100">
<!— ヘッダー -->
<!— サイドメニュー -->
<!— メインコンテンツ -->
</body>
</html>
h-100クラスを追加することにより以下のcssが適用されます。
hight: 100%!important
高さではなく横幅を指定する場合はw-100などを利用します。
header要素の設定
header要素
テンプレート上のサイトタイトルやLoginや新規登録のリンクを入れ込むheader部を作成します。
hearder要素を以下のようにbody要素の間に記入します。
<html class="h-100">
<body class="h-100">
<header class="w-100 d-flex justify-content-between align-items-center bg-light px-3">
<!— ヘッダーの内容 -->
</header>
<!— サイドメニュー -->
<!— メインコンテンツ -->
</body>
</html>
header要素には以下のクラスを指定しています。
- w-100
- d-flex
- justify-content-between
- align-items-center
- bg-light
- px-3
d-flexクラスはflexbox(フレックスボックス)を有効にします。d-flexクラスを指定された要素はflexコンテナとなり、その子要素はflexアイテムとなります。
display: flex !important;
子要素のflexアイテムを垂直方向に中央揃えするためにalign-items-center、flexアイテムを両端に配置するためにjustify-content-betweenを追加しています。
高さを固定するために高さを50pxに設定し、影を付けるためcssファイルに以下を追加します。
header{
height: 50px;
box-shadow: 0px 0px 5px 0px hsla(0, 0%, 7%, 0.3);
}
ヘッダー内部
header要素の内部に以下コードを記述します。
<ul class="navbar-nav d-flex flex-row">
<li class="nav-item mx-3 text-muted active"><a href="#" class="nav-link text-secondary">New</a></li>
<li class="nav-item mx-3 text-muted"><a href="#" class="nav-link text-secondary">Login</a></li>
</ul>
サイドメニューとメインコンテンツを囲む要素の設定
サイドメニューとメインコンテンツをdiv要素で囲み、クラスに以下3つのクラスを指定します。
- d-flex
- flex-row
- w-100
flex-rowクラスをflexコンテナに指定することで、子要素であるflexアイテムを左から右に配置します。
flex-direction: row !important;
またサイドメニューとメインコンテンツの高さは、ヘッダーの高さを引いた高さに設定します。calc()関数を利用して以下スタイルを適用させます。
height: calc(100% - 50px)
ページ全体のコードは以下のようになります。
<html class="h-100">
<body class="h-100">
<header class="w-100 d-flex justify-content-between align-items-center bg-light px-3">
<!— ヘッダーの内容 -->
</header>
<div class="d-flex flex-row w-100" style="height: calc(100% - 50px)">
<!— サイドメニュー -->
<!— メインコンテンツ -->
</div>
</body>
</html>
サイドメニューの設定
サイドメニュー:nav要素
サイドバーをメニューとして使用しますので、ここではnav要素を使用します。nav要素は次のように記入します。
<!— サイドメニュー -->
<nav class ="bg-dark">
<!— メニュー内容 -->
</nav>
nav要素に追加したbg-darkクラスは背景色を黒色に設定します。
サイドメニューの横幅はここでは230pxで固定します。cssファイルに以下を追加してください。
nav {
width: 230px;
}
メニューの設定
サイドメニューの各メニューは以下のように記入します。
<nav class="bg-dark">
<ul class="nav flex-column m-0 p-3">
<li class="nav-item mb-2"><a href="#" class="nav-link">Python</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link">Django</a></li>
</ul>
</nav>
メニューの色と背景色をcssで変更します。
.nav-link {
color: white;
background-color: rgba(255, 255, 255, 0.493);
}
メインコンテンツの設定
メインコンテンツの部分はmain要素で囲み、w-100クラスとbg-lightクラスを指定します。
<!— メインコンテンツ -->
<main class="w-100 bg-light" >
<!— タイトルバー -->
<!— コンテンツ -->
</main>
main要素の内部にタイトルバーとコンテンツを入れ込みます。
タイトルバー
タイトルバーは以下のように記述します。
<!— タイトルバー -->
<div class="bg-light border shadow-sm d-flex flex-row align-items-center">
<div class="navbar-brand toggle-menu">
<button class="btn btn-light btn-sm" id="toggle"><i class="fas fa-bars fa-lg"></i></button>
</div>
<div class="fs-4 fw-bold">Dashboard</div>
</div>
コンテンツ
メインのコンテンツ部分は以下のように記述します。
<!— コンテンツ -->
<div class="p-3">
<div class="d-flex flex-row">
<div class="card mx-1" style="max-width: 15rem;">
<img src="https://office54.net/static/image/252/outlook-receive.png" alt="img" class="card-img-top">
<div class="card-body">
<h4 class="card-title">カードの見出し</h4>
<p class="card-text">カードの内容</p>
<a href="#" class="btn btn-primary stretched-link">ボタン</a>
</div>
</div>
<div class="card mx-1" style="max-width: 15rem;">
<img src="https://office54.net/static/image/224/excel_windows.png" alt="img" class="card-img-top">
<div class="card-body">
<h4 class="card-title">カードの見出し</h4>
<p class="card-text">カードの内容</p>
<a href="#" class="btn btn-primary stretched-link">ボタン</a>
</div>
</div>
</div>
</div>
ここではコンテンツにカード(card)を入れ込んでいます。
サイドメニューを表示・非表示にするJS
ボタンをクリック時にサイドメニューを表示・非表示にするため以下JavaScriptコードを追加します。
<script type="text/javascript">
window.onload = () => {
// toggleボタン
let sidemenuToggle = document.getElementById('toggle')
// メインコンテンツを囲むmain要素
let page = document.getElementsByTagName('main')[0];
// 表示状態 trueで表示中 falseで非表示
let sidemenuStatus = true;
// ボタンクリック時のイベント
sidemenuToggle.addEventListener('click', () => {
// 表示状態を判定
if(sidemenuStatus){
page.style.cssText = 'margin-left: -230px'
sidemenuStatus = false;
}else{
page.style.cssText = 'margin-left: 0px'
sidemenuStatus = true;
}
})
}
</script>
このJavaScriptの動きとしては、ボタンが押下されたらmain要素を左に移動させてサイドメニューを非表示にするというものです。
もう一度ボタンを押すと、main要素を元の位置に戻します。
またCSSアニメーションで表示・非表示に動きをつけます。
main {
transition: 0.3s all ease;
}
これでサイドメニューを表示・非表示できるWebアプリケーション用テンプレートが完成します。
テンプレートの全コード
本記事で解説したテンプレートの全コードを以下に記します。
<html class="h-100">
<head>
<title>OFFICE54</title>
<style media="screen">
header{
height: 50px;
box-shadow: 0px 0px 5px 0px hsla(0, 0%, 7%, 0.3);
}
nav {
width: 230px;
}
.nav-link {
color: white;
background-color: rgba(255, 255, 255, 0.493);
}
main {
transition: 0.3s all ease;
}
</style>
</head>
<body class="h-100">
<header class="w-100 d-flex justify-content-between align-items-center bg-light px-3">
<!— ヘッダーの内容 -->
<h1 class="mx-2 fs-4 text-primary fw-bold">OFFICE54</h1>
<ul class="navbar-nav d-flex flex-row">
<li class="nav-item mx-3 text-muted active"><a href="#" class="nav-link text-secondary">New</a></li>
<li class="nav-item mx-3 text-muted"><a href="#" class="nav-link text-secondary">Login</a></li>
</ul>
</header>
<div class="d-flex flex-row w-100" style="height: calc(100% - 50px)">
<!— サイドメニュー -->
<nav class="bg-dark">
<ul class="nav flex-column m-0 p-3">
<li class="nav-item mb-2"><a href="#" class="nav-link">Python</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link">Django</a></li>
</ul>
</nav>
<!— メインコンテンツ -->
<main class="w-100 bg-light">
<!— タイトルバー -->
<div class="border shadow-sm d-flex flex-row align-items-center bg-light">
<div class="navbar-brand toggle-menu">
<button class="btn btn-light btn-sm" id="toggle"><i class="fas fa-bars fa-lg"></i></button>
</div>
<div class="fs-4 fw-bold">Dashboard</div>
</div>
<!— コンテンツ -->
<div class="p-3">
<div class="d-flex flex-row">
<div class="card mx-1" style="max-width: 15rem;">
<img src="https://office54.net/static/image/252/outlook-receive.png" alt="img" class="card-img-top">
<div class="card-body">
<h4 class="card-title">カードの見出し</h4>
<p class="card-text">カードの内容</p>
<a href="#" class="btn btn-primary stretched-link">ボタン</a>
</div>
</div>
<div class="card mx-1" style="max-width: 15rem;">
<img src="https://office54.net/static/image/224/excel_windows.png" alt="img" class="card-img-top">
<div class="card-body">
<h4 class="card-title">カードの見出し</h4>
<p class="card-text">カードの内容</p>
<a href="#" class="btn btn-primary stretched-link">ボタン</a>
</div>
</div>
</div>
</div>
</main>
</div>
</body>
<script type="text/javascript">
window.onload = () => {
// toggleボタン
let sidemenuToggle = document.getElementById('toggle')
// メインコンテンツを囲むmain要素
let page = document.getElementsByTagName('main')[0];
// 表示状態 trueで表示中 falseで非表示
let sidemenuStatus = true;
// ボタンクリック時のイベント
sidemenuToggle.addEventListener('click', () => {
// 表示状態を判定
if(sidemenuStatus){
page.style.cssText = 'margin-left: -230px'
sidemenuStatus = false;
}else{
page.style.cssText = 'margin-left: 0px'
sidemenuStatus = true;
}
})
}
</script>
</html>