先日の記事、「職業訓練(WEBサイト管理者コース)の卒業制作:HTML・CSS・JavaScript・jQueryによるサイト作り」の中、ヘッダーエリアの1つの工夫として、
・ロゴとナビゲーションメニューをヘッダーエリアの左側と右側にそれぞれ固定し、
・画面幅の縮小に合わせて折り返させるように設定している
と少し触れました。
この作業はHTMLとCSSだけで完成できたのですが、実は意外と苦労しました。
例えば、「position:fixed;」でロゴとナビゲーションメニューをヘッダーエリアの左側と右側にそれぞれ固定させたところ、下の要素がヘッダーエリアの背面に隠れてしまったり、「display: flex;」でナビゲーションメニューを次の行に折り返させようとしたところ、メニューごとの文字が2行目に折り返させて、見た目があまりよくなかったりして、解決するのに結構時間がかかりました。
いろいろ試してようやく解決したので、備忘録的にも、同じ悩みを抱えている方がいらっしゃるかもしれないというのもあって、記事にすることにしました。
完成した状態:ナビゲーションメニューの右側固定と画面サイズ適応
自分が求めた完成形は以下の図の通りです。
初期状態では、ロゴとナビゲーションメニューをヘッダーエリアの左側と右側にそれぞれ固定され、画面幅の縮小に合わせナビゲーションメニューがメニューごとに2行目に折り返して来ます。
さらに、図2が示したように、スクロールダウンしてもナビゲーションメニューはずっと一番上に固定表示されるままとなっています。
※スクロールダウンによってロゴが消えて、ナビゲーションメニューが画面幅いっぱいに表示させ、かつ遅れて降りてくるなどの設定はJavaScript(jQuery)も関わっているため、設定方法は長くなるので、次回の記事にする予定です。
完成形のソースコード:HTMLとCSSコート及び解説
HTMLとCSSソースコート
HTMLコードは以下の通りです。
<header>
<h1><a href="index.html"><img src="images/logo.png"alt="FUMOTO PPARA"></a></h1>
</header>
<nav>
<button><img src="images/button.png" width="20" height="17" alt="Button"><br class="menu">MENU</button>
<ul id="navi">
<li id="nav_home"><a href="index.html">HOME</a></li>
<li id="nav_activity"><a href="activity.html">施設案内</a>
<ul>
<li><a href="activity.html#campsite">キャンプサイト</a></li>
<li><a href="activity.html#cottage-kashiwa">コテージ柏</a></li>
<li><a href="activity.html#suizansou">翠山荘</a></li>
<li><a href="activity.html#kenashisansou">毛無山荘</a></li>
<li><a href="activity.html#mahoroba">まぼろば~麓の森の大きなお家~</a></li>
<li><a href="activity.html#kanayamakitchen">金山キッチン</a></li>
<li><a href="activity.html#kenashian">けなし庵</a></li>
</ul>
</li>
<li id="nav_fee"><a href="fee.html">料金</a>
<ul>
<li><a href="fee.html#fee_camp">キャンプ</a></li>
<li><a href="fee.html#fee_activity">宿泊施設</a></li>
<li><a href="fee.html#fee_rental">レンタル</a></li>
</ul>
</li>
<li id="nav_reserve"><a href="reserve.html">オンライン予約</a></li>
<li id="nav_goods"><a href="goods.html">グッズ販売</a></li>
<li id="nav_rule"><a href="rule.html">注意事項</a></li>
<li id="nav_access"><a href="access.html">アクセス</a></li>
<li id="nav_contact"><a href="contact.html">お問い合わせ</a></li>
</ul>
</nav>
navタグの中に、buttonタグがありますが、それはスマホ用ハンバーガーメニューに関する記述なので、ここでは無視して大丈夫です。
また、「施設案内」と「料金」の下にそれぞれ別のulタグとliタグがありますが、それはサブメニュー用なので、今回の記事においても特に触れません。
そして、CSSコードは以下の通りです。
body {
margin: 0;
padding: 0;
font-family: 'Sawarabi Gothic', Arial, 'sans-serif';
background-color: #A8D8B9;
color: #5f5039;
font-size: 87.5%;
line-height: 1.5;
width: 100vw;
}
#breadcrumb, #contents, footer{
margin: 0 auto 0 auto;
width: 1000px;
}
header{
position:fixed;
width:100vw;
height: 100px;
top:0;
background:#4C9E67;
z-index: 999;
}
header h1{
margin: 0 0 26px 25px;
padding-top: 28px;
text-align: left;
}
nav ul a{
color: black;
}
#index #nav_home a,
#activity #nav_activity a,
#fee #nav_fee a,
#reserve #nav_reserve a,
#goods #nav_goods a,
#rule #nav_rule a,
#access #nav_access a,
#contact #nav_contact a,
nav ul a:hover {
color:#FFF;
}
nav{
position:fixed;
top:30px;
right:25px;
transition: top .3s;
font-size: 1.2em;
width: 60vw;
background:#4C9E67;
z-index: 999;
}
nav ul {
margin: 0 0 20px 0;
padding: 0;
list-style-type: none;
line-height: 150%;
}
nav ul li{
float: left;
}
nav ul li a{
display:block;
border-right:1px solid #526563;
text-decoration:none;
padding-left: 10px;
padding-right: 10px;
}
nav ul li:last-child > a{
border-right:none;
}
nav >ul >li >ul >li> a:last-child {
border-right:none;
}
ロゴ位置に関する記述説明:「position:fixed」、「text-align: left」と「z-index」
第17行までは全体に関する設定で、第18行から見ていきましょう。
まず、第18行からの「header 」セレクタはロゴの位置固定「position:fixed」や背景色「background:#4C9E67」に関して記述しています。
なお、他のコンテンツが同じく「position:fixed」を使って位置を固定させたとしても、ロゴが常に最前面に来るように、「z-index」プロパティの値を極端の999で指定しています。
そして、「header h1」はロゴ位置に関する記述です。
「text-align: left」でロゴをヘッダーエリアの左に寄せるよう指定しております。
ナビゲーションメニューの位置に関する記述説明
第33行から35行までの「nav ul a」スタイル宣言はナビゲーションメニューの文字色(リンク)に関する指定で、第37行から47行は該当するページにいるときや、ホバーしたときのナビゲーションメニューの文字色に関する記述です。
第49行からの「nav」スタイル宣言は、上のロゴ位置に関する記述と似ていて、「position:fixed」及び「z-index: 999」の説明は省きますが、「top:30px」と「right:25px」でナビゲーションメニューという箱を右寄せにさせるよう指定しています。
さらに、「width: 60vw」でナビゲーションメニュー箱の幅を画面幅の60%と指定しています。なお、必ず「60vw」でなければだめということではなく、状況次第で自由に設定することが可能です。
そして、第67行からの「nav ul li」に関する「float: left」宣言はナビゲーションメニューの箱の中にある要素(メニュー達)を箱に対して左寄せさせて、画面幅を超えた場合は自動的に次の行に折り返すよう記述しています。
また、第71行からの記述、「text-decoration:none」はナビゲーションメニューの文字列の下線(リンクである標識)をなくしたり、「border-right」は右側に棒線「|」をつけた上、「nav ul li:last-child > a」>「border-right:none」で最後のメニューである「問い合わせ」の右側の傍線を非表示させる記述です。
「nav >ul >li >ul >li> a:last-child」はサブメニューに関するセレクタで、これを外すと、「施設案内」や「料金」の中のサブメニューはすべて右側に傍線がつくようになります。
以上がロゴやナビゲーションメニューの固定表示や、ナビゲーションメニューの画面サイズ適応に関する記述及びその説明でした。 下では完成まで遭遇したいろんなトラブルや試行錯誤をご紹介します。もしかして似たトラブルに遭遇するかもしれないので、良ければ是非ご覧ください。
完成までの試行錯誤
一番最初に悩んだのが、いかにナビゲーションメニューを右に寄せながら、中のメニューは左から右に並べて、かつ画面幅に合わせて次のように折り返させるかということです。
恥ずかしながら、最初は「右寄せのナビゲーションメニューの箱を作り、要素を左寄せ」させる方法は浮かんでいなくて、いろんな試行錯誤をしました。
例えば、「nav」全体を右に寄せずに、中の子要素であるメニュー達を「float: right」で一旦右からfloatさせて、HTMLファイルのメニューを逆順に並べさせたりするようなとんでもない複雑なやり方までしてしまいました(笑)。
もちろん、「display: flex」も試しました。
「display: flex」→ナビゲーションメニューごとに改行されてしまう
例えば、floatの代わりに、「nav ul」の中に「display: flex」を入れた場合、以下の図3のように、ナビゲーションメニューごとに改行されてしまいます。
「nav ul li a」の中に、「display:block」を入れてもあまり変わらなかったし、自分の力では「display: flex」でうまくできませんでした。
もしかして「display: flex」を使ってもうまくいく方法があるかもしれないのですが、ご存知の方は是非ご教示いただければ幸いです。
fixedにしたら下の要素が潜り込んでしまう解決策:下の要素のpadding-top設定
そして、もう1つトラブルがありました。
それが、ロゴとナビゲーションメニューを「position:fixed」にして、常に画面の一番上に表示させたところで、下のコンテンツはヘッダーエリアの背面に潜り込んでしまう現象(図4の上部分)です。
今では原因ははっきりわかりますが、当時では訓練校の先生に聞くまでは「position:fixed」にすると、要素が上に浮いてしまい、後に来る要素が浮いた分に対してずれ込んでくることを認識していませんでした。
そこで、ヘッダーとナビゲーションメニューの下に来るコンテンツに対して、padding-top設定(自分の場合は100px)をすれば、図4の下のようにうまく回避することができました。
やはり基礎をしっかりしないとだめだなと改めて認識させられました(笑)。
まとめ
以上、ロゴとナビゲーションメニューをヘッダーエリアの左側と右側にそれぞれ固定させ、画面幅の縮小に合わせナビゲーションメニューを折り返させるようHTMLとCSSのコーディング方法及び間違った際のトラブル例をご紹介しました。
次回はJavaScript(jQuery)を使って、動きをつけた手順などを書こうと思っていますので、どうぞお楽しみに〜