前回はハンバーガーメニューの骨子となるHTMLを作成しました。
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>投票ボタン付き 横棒グラフ</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200&icon_names=menu" />
</head>
<body>
<header>
<button id="menu-btn">
<span class="material-symbols-outlined">menu</span>
</button>
<nav>
<ul>
<li><a href="#">ホーム</a></li>
<li><a href="#">投票ページ</a></li>
<li><a href="#">コメント</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
</header>
<main>
<div>
投票をするところ
</div>
</main>
<footer>
<p>© 2025 投票アプリ</p>
</footer>
</body>
</html>
これをCSSで操作し、ハンバーガーメニューを作ることにします。
掲示板のCSSのでそこまで凝ったものにする必要はないので楽で助かります。
イメージとしてはnavタグの中にメニューがありますので、このnavの表示、非表示をJavaScriptで操作することにします。
表示の時にはメニューが見えて、非表示の時には消える感じです。
まずは全体の構成などを決めるためにbodyを設定しておきます。
ブログの最初の方でも書きましたけど、VSCodeを使いますのでSassで書いていきます。
一応書いておきますと、以下のような書き方の場合、
body {
font-size: 1rem;
color: red;
}
font-sizeをキー(プロパティ)、1remを値と呼びます。
ではまずbodyを書いていきます。
body
body {
font-size: 1rem;
font-family: sans-serif;
margin: 0;
padding: 0;
}
フォントの種類や色、余白を設定します。
背景色とかもここで決めてしまおうかと思いましたが、ヘッダーやメイン、フッターで色分けする可能性もあるのでボディで決めてしまうのはやめておきます。
もし色分けをしないなら、後ほど各セッションで設定するか、ボディに戻ってきて書き足すことにします。
次にヘッダーです。
header {
position: relative;
background-color: #fff;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
そんなにややこしいことはしませんが、とりあえず要素の配置だけ決めておきます。
まずposition: relative;ですが、これは何かを基準にして相対的な位置に自分を置くという意味ですが、相対的なものの対象がないため自分自身が基準になります。
これを付けておくことで、今後ヘッダーを基準として配置していくことができます。
背景はとりあえず白、paddingは1remにしておきましょう。
メニューを並べる方向は横で、flexはデフォルトは横方向なので特にいじる必要はありません。
<button>と<nav>は横に並ぶことになります。
次にハンバーガーメニューについて配置していきます。
nav {
position: absolute;
display: none;
top: 100%;
right: 0;
}
コメントアウトで基本的なことは書いてますが、私自身のために以下に注意書きを書いておきます。
改めて書きますが、イメージとしてはbuttonを押すたびに<nav>が消えたり現れたりする、というようにします。
先ほどヘッダーのところでposition: relative;と書きましたので、ポジションをabsoluteと書いたことによってnavの基準はヘッダーになります。
ヘッダーのすぐ下に配置するのでtopは100%にしておきます。
これはずらし具合を示します。
ヘッダー、メニューの二つの紙があると考えてください。
100%で二枚が連なるように配置されます。
0%ならnavの位置はヘッダーの上端からということになってしまい、完全に紙を重ねることになります。
対して右端はヘッダーと合わせることになりますので、ずらし具合は0になります。
次はulの中を書いていくことになります。
ul
ul{
list-style: none;
padding: 1rem;
}
以上。
リストの「・」とか余白を消して、文字の周りに適当に余白を作っておきます。
あとで確認してから気に入らないところを直していきます。
つぎはliですね。
li
li {
margin-bottom: 0.5rem;
a {
display: block;
padding: 0.5rem 1rem;
text-decoration: none;
color: #333;
&:hover {
background-color: #f0f0f0;
}
}
}
display: block;についてですが、<a>は最初はインラインの要素を持っていて、文字の分しか幅を持っていません。
なのでblockにすることで縦に並べ、かつ端から端までをリンクの範囲を広げます。
&:hoverについて
&というのは親セレクタを示すものなのですが、「書き方はSassやのになんで親セレクタを書く必要があんねん」という疑問が出てきますが、これはスペースの問題です。
もしこれを省略して以下のように書いてしまうと、
li {
:hover {
color: red;
}
}
出力は「liの中にある子要素」ということで
li :hover {
color: red;
}
このようになってしまいます。
liとhoverの間にスペースが入ってしまって疑似セレクタとして機能してくれないわけです。
なので&:hoverと直接くっつける必要があります。
つまり以下のようになります。
li {
&:hover {
color: red;
}
}
おわりに
さて、CSSについてはこんなものでしょうか。
ボタンについてはGoogleフォントから直接持ってきてますし、書く必要はないでしょう。
今回やったことをまとめておきます。
body {
font-size: 1rem;
font-family: sans-serif;
margin: 0;
padding: 0;
}
header {
position: relative;
background-color: #fff;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
nav {
position: absolute;
display: none;
top: 100%;
right: 0;
ul {
list-style: none;
padding: 0;
li {
margin-bottom: 0.5rem;
a {
display: block;
padding: 0.5rem 1rem;
text-decoration: none;
color: #333;
&:hover {
background-color: #f0f0f0;
}
}
}
}
}
次回はこれらを動かすためにJavaScriptを書いて、動作を見てみることにします。