background-attachment:fixedが効かないブラウザ用パララックス
iOS (iPhoneやiPad) のブラウザ「Safari」で、背景画像を固定してスクロールしないようにするCSSプロパティのbackground-attachment:fixedが効かない場合があります。
background-attachment:fixedを効果的に使用すると、複数の画像がスクロールによって入れ替わるパララックス (視差) などの面白い演出が可能になります。
今回は、background-attachment:fixedを使用せず、このパララックスを実現する方法を紹介します。
background-attachment:fixedを使わずに画像を固定する方法として良く知られているのが、position:fixedを使う方法です。画像が固定できないなら、画像を設定した要素自体を固定してしまえという訳です。
上記のコードのように、背景画像を1つbody要素に適用するといった場合には、position:fixedによる代替方法で問題ありません。しかし、複数の画像がスクロールによって入れ替わるパララックスには使用できません。
そこで使用するのがposition:stickyです。
position:stickyのおさらい
position:fixedは祖先要素のレイアウト設定を無視して、ブラウザの描画領域を基準にして固定されます。そのため、どんなにスクロールしても同じ位置のまま動きません。
position:stickyもブラウザの描画領域を基準にして固定されますが、親要素の範囲内でのみ固定されます。
そのため、スクロールによって親要素が描画領域を外れると、親要素と一緒に描画領域から外れます。
position:stickyを設定した要素が固定される条件として、その幅が、親要素のコンテンツ幅 (box-sizing:content-boxの時のwidth値またはheight値) よりも小さく、子要素に占有されていないスペースがある場合に限られます。
position:stickyを使ったパララックス
HTMLコード
<div class="_parallax">
<p class="_parallax_text">…</p>
<p class="_parallax_img"><img alt="…" src="…" /></p>
<p class="_parallax_text">…</p>
<p class="_parallax_img"><img alt="…" src="…" /></p>
<p class="_parallax_text">…</p>
<p class="_parallax_img"><img alt="…" src="…" /></p>
<p class="_parallax_text">…</p>
</div>
HTMLコードのポイントは、画像部分 (._parallax_img) を挟むようにテキスト部分 (._parallax_text) を配置する点です。
img要素を使用していますが、空の要素にCSSのbackgroundを設定したものでも構いません。
CSSコード
._parallax_text {
background: #404040; /* ポイント! */
color: #fff;
border: solid 32px transparent;
box-sizing: border-box;
display: grid;
place-items: center;
margin: 0;
padding: 0 calc(50% - 320px);
min-height: 100vh; /* ポイント! */
position: relative;
z-index: 1; /* ポイント! */
}
._parallax_text:not(:first-child) {
margin-top: 100vh; /* ポイント! */
}
._parallax_text:not(:last-child) {
margin-bottom: -100vh; /* ポイント! */
}
._parallax_img {
background: #fff;
height: 100vh;
margin: 0;
position: -webkit-sticky;
position: sticky;
top: 0;
}
._parallax_img img {
display: block;
object-fit: cover;
width: 100%;
height: 100%;
}
CSSコードのポイントは、テキスト部分 (._parallax_text) に設定したbackground、min-height:100vh、margin-top:100vh、margin-bottom:-100vh、z-index:1の部分です。
position:stickyを設定した画像部分 (._parallax_img) が、テキスト部分に設定したmargin-bottom:-100vhとz-index:1によって、テキスト部分の背後に配置されます。min-height:100vhとbackgorundが設定してあるので、完全に隠れます。
スクロールされると、position:stickyによって固定された画像部分が、margin-top:100vhによって設けられたスペースに表示されます。
CodePenによる実際の表示
〆
最近、Internet ExplorerをWindowから投げ捨ててやりました。今まで、どれだけ無駄なコードを書いていたのかを思い知りました。よって、今回のパララックスはIE非対応です。
後は、今回のbackground-attachment:fixedのように、いつまでも残る謎仕様やバグが各ブラウザからなくなってくれると有難いですね。