HTML&CSS

【CSS】position: fixed; でメニューを固定したら親要素からはみ出てしまう!?

「position: fixed;」を使って、メニューをページトップに固定したら、メニューの横幅が親要素からはみ出てしまう…。

30DASYトライアル2ndのDAY9「ヘッダーとメインビジュアルのコーディング」に挑戦中にこの事象に出くわし、試行錯誤の末に無理やりどうにか解消できたのでデイトラ活動履歴として残しておきます。

↑こんな感じなので、読み終わったあとスッキリしないかもですが、この記事にたどりついたということは同じ事象が発生してモヤっているかと思うので、よかったら読んでいってください♪

デイトラDAY9の課題をおさらい

まずは、この記事を書くに至ったデイトラDAY9の課題をおさらいしておきます。

講座で提供されたXDのデザインカンプはこんな感じ↓

そして、コーディングの条件に 「CSSはSassで書く」「ヘッダーは上部に固定」 というものがありました。

これをもとに書いたコードがこちら↓
※必要なところだけ抽出してます。

See the Pen
position: fixed;_1
by あやたろう@独女リゾートエンジニアの卵 (@aya2kiku)
on CodePen.

「Result」ボタンをクリックすると画面表示イメージを確認することができます。

下にあるボタンで「0.25x」にしてもらうとわかりやすいですが、メニュー(.nav-wrapper)が親要素(.wrapper)の横幅をぶちぬいてしまっています…。

親要素

.wrapper {
   width: 1136px;
}

子孫要素

.nav-wrapper {
   width: 100%;
}

.nav-wrapper wrapper  の中に収まってくれると思っていたので、はみ出る理由がわかりませんでした。

position: fixed; の起点は親要素じゃない

調べていくと、どうやら「position: fixed;」の基準は、親要素ではなくディスプレイの幅のようです。

.nav-wrapper { width: 100%;}   は「ディスプレイの幅いっぱい」という指定をしているということになりますね…。

ん?でも、左側は親要素の内側に入ってるよね?

そうなんです。

これがまた混乱ポイントで「position: fixed;」は、

  • 親要素に横幅を指定する
  • 「position: fixed;」をつける子要素には left を指定しない(または「left: auto;」を指定する)

↑このふたつの条件がそろうと、親要素を基準にして親要素の左側にぴったりくっつくようになるのだとか。

上述のコーディングでは、意図せずこれらを全て満たしていたので、

  • .nav-wrapper { width: 100%;}   は「ディスプレイの幅いっぱい」という指定
  • でも、左側だけは親要素を基準に

ということになり、見本のようなトンチンカンな仕上がりになったようです…。

偶然の産物…??

position:fixed ; を親要素の内側にするには

では、メニューをページトップに固定しつつ、親要素の内側に収めるにはどうすればいいのか…??

ググりました。

めっちゃググりました。

でも、帯に短し襷に長し、あちらを立てればこちらが立たず…的なものしか見つからず…。

結果、ググって解決することを諦めました 笑

今のコードって「親要素の左端を起点」にはできているわけなので、 .nav-wrapper の横幅を100%指定ではなく、親要素と同じ幅にすればOKなんですよね。

See the Pen
position: fixed;_2
by あやたろう@独女リゾートエンジニアの卵 (@aya2kiku)
on CodePen.

※0.25xに切り替えるとわかりやすいです ^^

でも、これだと親要素の幅を変えた時に子要素の幅も変えなきゃいけなくなります。 

ぶっちゃけ、それがめんどくさいので100%指定でどうにかできないか…という模索をしていたと言っても過言ではない…。

ということで、ここで要件が出揃いました。

  • .nav-wrapper  は親要素の内側に収めたい
  • 親要素のサイズを変更したら子要素も自動的に変更されるようにしたい

ググって解決できないなら、視点を変えて「この要件を満たす方法はないか」と考えてみました。

それなら、勉強したばっかりのSass変数を使ってみたら?

そうです。

今回は、デイトラの課題もあってCSS部分をSassで書いています。

なので $width  という変数に横幅の数値を代入して、親子ともに横幅を  width: $width;  と指定してみました。

See the Pen
position: fixed;_ 3
by あやたろう@独女リゾートエンジニアの卵 (@aya2kiku)
on CodePen.

 

※0.25xに切り替えるとわかりやすいです ^^

…できたー!!

む、無理やり感がすごいニャー!!

確かに w

でも、これで、親要素の幅が変わっても、変数に代入する数値を変えるだけでOK!

一応、今回の要件は満たせたことになるので良しとします。

おわりに

これまで模写コーディングしてきたのが、親要素が横幅100%のページばっかりだったので、「position: fixed」のナビゲーションメニューが親要素から飛びだす…ということに全く気づいていませんでした。

また、横幅1366px以内の画面サイズで見ている分には問題ないので、なかなか気づきづらいところだなぁ…と。

色んな環境で検証してみるのがホントに大事だと再認識しました。

自分のサイトならどうとでもなるけど、お仕事でコーディングする場合は検証必須!ですね!

肝に銘じるニャ!

おねがい

この記事で書いた方法、いくらコーディングに正解がないとは言えども、無理やり感がすごくてあまり納得がいっていません。

もっとスマートな方法をご存知の方、ぜひ教えてください!