概要
Web 制作において、レイアウト設計は非常に重要な要素です。
position
の設定や z-index
の設定や管理など、仕様を理解してしまえば問題ないものの、思いもしなかった挙動で想定以上に時間を取られてしまうことがあります。
さて、この記事に辿り着いている人はひょっとしたら position: fixed;
が画面基準で配置されず、absolute のような配置になってしまってお困りなのではないでしょうか?
実は意外と知られていない position: fixed;
の仕様があり、要素配置の基準位置が画面基準とならないケースがあります。
本記事ではこの挙動に焦点を当て、なぜそれがウインドウに固定されない場合があるのかを確認していきます。
position: fixed による配置の仕様
まず MDN の仕様を確認していきましょう。
包含ブロックのセクション、3 の項目を確認します。
position プロパティが fixed の場合、包含ブロックはビューポート (連続的なメディアの場合) またはページ領域 (ページメディアの場合) によって確立されます。
おそらくこちらは fixed を使用する上でおおむね想定されている挙動かと思いますが、続けて 4 の項目を。
position プロパティが absolute または fixed の場合、包含ブロックは以下の条件を持った直近の祖先要素におけるパディングボックスの辺によって構成されることがあります。
- transform または perspective の値が none 以外である
- will-change の値が transform または perspective である
- filter の値が none 以外、または will-change の値が filter の場合 (Firefox のみで動作)
- contain の値が paint の場合 (例 contain: paint;)
position: fixed;
が想定されている箇所に配置されない場合、fixed を指定している親要素に上記の CSS プロパティを持つものが設定されている可能性が高そうです。
「されることがあります」なのでこの動作にならないパターンもありそうなので、実際の動作を確認していきます。
動作確認
CodePen で実際に 4 つのプロパティを親要素に指定して確認します。
上記で確認した限りでは、どのパターンでもビューポート基準でない配置となっていそうです。
MDN の仕様通りの挙動ですね。
解決策
実装のされているケースにもよるかと思いますが、大きく二つ解決策が考えられるかと思います。
- 親要素に指定している該当のプロパティを除去、または可能であれば別のプロパティや他の実装方法に置き換える(
drop-shadow
→box-shadow
への置き換えなど) - fixed に指定している要素の HTML 上の配置を変更する(HTML 側を該当するプロパティの外に出す)
結論
包含ブロックと fixed の仕様を確認することで、ビューポートに固定されない fixed の配置が仕様通りであることを確認できました。原因が特定できたことで、上記のもの以外の解決方法を検討できるケースもありそうです。
本記事が同じようにお困りの方の解決の一助となれば嬉しく思います。
メリークリスマス!🎄