初めに
よし、ヘッダーを画面上に固定してやろ(^ω^)
って時に
え、ヘッダーの上に文字が来るんですけど( ‘д‘⊂彡☆))Д´) パーン
とか
スクロールして、動的におしゃれに上部メニューを表示させたいのにスクロール中に表示されない( ‘д‘⊂彡☆))Д´) パーン
とかそんな事件の対処法をテンションに任せて書いていこうと思います。
事件1「z-index」
概要
ヘッダーにposition:fixed
を指定してtop:0
,left:0
で画面上部に固定しているのに
なんで他の要素が上に来ているの!?という事件。
DEMO
キャプチャ
code
html
<body>
<div class="div_elm">
hoge
</div>
<div class="fixed_elm">
hoge
</div>
<div class="div_elm">
hoge
</div>
</body>
css
.fixed_elm {
height: 100px;
width: 100px;
background: red;
position: fixed;
top: 0px;
left: 0px;
}
.div_elm {
position: relative;
background-color: yellow;
text-align: center;
}
解決策
position:fixed
にしている要素の前後に同じdiv要素を配置しているのに、なんでposition:fixed
にしている要素の次の要素は上に来ているのか・・・
原因はdiv要素にposition:relative
を指定している時は、position:fixed
にしている要素にz-index
を指定していないからでした。
下記のように修正するときちんと動きました。
.fixed_elm {
height: 100px;
width: 100px;
background: red;
position: fixed;
top: 0px;
left: 0px;
z-index: 1;
}
事件2「Transform」
概要
ヘッダーにposition:fixed
を指定してtop:0
,left:0
で画面上部に固定しているのに
位置がなぜか画面上部にならない!?
DEMO
キャプチャ
code
html
<body>
<div class="fixed_elm">
hoge
</div>
</body>
css
body {
transform: translate3d(0, 0, 0);
height: 300px;
background-color: black;
}
.fixed_elm {
height: 100px;
width: 100px;
background: red;
position: fixed;
top: 0px;
left: 0px;
}
解決策
原因はbodyに指定しているtransform: translate3d(0, 0, 0);
です。
どうやら親要素にtransform
が指定してあると子要素のposition:fixed;
は親要素からの相対位置になるっぽいです。
w3cでもバグ?として言われているっぽいです。
https://www.w3.org/TR/css-transforms-1/#transform-rendering
解決策は親要素からtransform
を外すか、position:fixed;
の要素の親子関係を解消させるか現状なさそうでうす。
事件3「スクロール」
概要
iPhoneでスクロールして、動的に上部メニューにposition:fixed;
を指定して画面上部に固定させたいのにスクロール中に画面上部に固定されない・・・
stack overflowにも同じような悩みの人が・・・
iOS 9 Safari: changing an element to fixed position while scrolling won't paint until scroll stops
解決策
どうやらスクロール中にクラスを付与してposition:fixed;
を指定してあげても
描画はCPUが行うのでスクロールが終わるまで反映されないそうです。
そのため、解決策としてはposition:fixed;
を指定するクラスに
transform: translate3d(0, 0, 0);
を指定するとスクロール中にも反映されます。
これは、transform: translate3d(0, 0, 0);
を指定すると描画をGPUが行うため解決できるそうです。
最後に
position:fixed;
は便利ですが、たまにはまったりするので気をつけましょう(´・ω・`)