[CSS]親要素を基準に子要素を position: fixed させる方法
posted : 2021.02.07
こんにちは、ma-ya’s CREATE[まーやずくりえいと]です。
ページスクロールに追従するposition:fixed、結構使いますよね。
「ページトップへ戻る」ボタンとかで特に。
でもこのposition:fixed、ちょっと癖があるのがたまにキズ。
position: fixed の左右の位置を親要素基準にしたい
結論から言うと、position:fixed + ポジション系プロパティ(top / right / bottom / left)を使用すると、
ビューポート(ブラウザ)の左上を起点にして要素が配置されてしまうことは避けられないです。
親要素にposition:relativeを指定しようが無駄ァ!
もうこれはCSSの仕様というわけ。
でも現実問題「それでもおいらは親要素基準にしたいんや!」ということもあるのが人情。
そんな時に用いるのがCSSハックです。
fixedした子要素の左右位置を親要素基準に見せかけるCSSハック
このハックは親要素に左右のパディングが設定されているかどうか、そして親要素の左右どちら側に子要素を配置するかで記述が分かれます。
大事なことなのでもう一回言います。
親要素に左右のパディングが設定されているか / 親要素の左右どちら側に子要素を配置するかで記述が分かれる
サンプルコードは親要素に左右のパディングが設定されているかどうかで二つ作成し、それぞれのサンプル内で子要素を左右に配置しています。
ではサンプルを先に見てみましょう。
ポイントとなるCSSコードにはコメントで★マークを付けています。
親要素に左右のパディングが設定されていないケース
親要素に左右のパディングが設定されているケース
どうでしょう?いかにもハック!といった記述ですね。
特に子要素を右側に配置するパターンなんかfloat使ってます。
アンチCSSハックな人には怒られそうな勢い。
なんて言っていてもしょうがないのでポイントをまとめていきます。
まずはどのパターンでも共通の指定から。
共通のCSS設定
親要素側のCSS指定
- position: relative;
- widthを指定(max-widthも指定可)
子要素側のCSS指定
- 子要素の中でさらに親(ラッパー) / 子(コンテンツ)のHTML構成にする必要あり
- position: fixed;
- left / right 指定をしない
- 最終的な位置調整は子要素、もしくは子要素(ラッパー)の子要素(コンテンツ)にてtransformやマージン(もしくはマイナスマージン)で調整
※①子要素の中でさらに親(ラッパー) / 子(コンテンツ)のHTML構成にする必要あり、というのは子要素を親要素に対して左側に配置する場合は必要ありませんが、念のためやっといたほうが後々コンテンツ部分のスタイリングがしやすいです。
※④マージン(もしくはマイナスマージン)で調整する場合は子要素の横幅を数値に指定。transformだと子要素が可変幅でも対応できますが、ブラウザによって1pxほどの隙間が発生する難あり。
親要素の左右どちらに子要素を配置するか
左側のCSS指定
- 上述の共通指定のみ
右側のCSS指定
- 上述の共通指定
- 親要素と同じ横幅指定(max-widthなど含む)
- 子要素の子要素(コンテンツ)にfloat: right
親要素に左右のパディングが設定されているかどうか
親要素に左右のパディングが設定されていない
- 上述の共通指定 + 親要素の左右どちらに子要素を配置するかの指定のみ
親要素に左右のパディングが設定されている
上述の共通指定 + 親要素の左右どちらに子要素を配置するかの指定に加えて、
- 親要素の左側に子要素を配置:margin-leftで親要素のパディング分だけマイナスマージン
- 親要素の右側に子要素を配置:margin-rightで親要素のパディング分だけプラスマージン
補足:親要素の右に子要素を配置するしくみ
親要素の右に子要素を配置する場合、なんでfloatなんか使うん?と思ってちょっと調べてみたら、↓のような仕組みみたい。
- 子要素の中の親(ラッパー。サンプルで言うところのdiv.fixed-child-right)に親要素と同じ幅を指定
- 子要素の中の子(コンテンツ。div.content)をfloat:rightで右寄せ
- さらに子要素の中の子(div.content)の幅分をtransformもしくはmargin-right(マイナスマージン)で移動
position: relative;内でポジション系プロパティ(top / left / right / bottom)を使わずに子要素を absolute / fixed すると、その要素は本来あるべき場所に配置されます。
今回のサンプルで言うと、「This is parent !」のpタグの下あたり。
その上でポジション系プロパティを指定すると位置が再計算されるわけですが、fixedの場合はその再計算が強制的にブラウザのビューポート基準となってしまう。
なのでポジション系プロパティは極力使用せず、他のCSSプロパティで要素を再配置していくのがこのハックの種明かしなのでした(だと思う)。
まとめ
なんか解説したら余計わかりにくくなりましたかね苦笑
基本的にはサンプルコードを見てもらうのが一番早いと思います。
上述したようにポイントとなる部分には★マークを付けているので、それを追っていただければと。
それでは今回はこの辺で。