パララックス効果があるタイプ

こういうヘッダーだと、パララックス効果をつけてみたくなるものです。ウィンドウ幅いっぱいのヘッダー画像にパララックス効果をつけたいときのためのメモです。ここではCSSのtransformプロパティを利用して、パララックス効果を作ります。
パララックスの作り方
JavaScriptでパララックス効果を再現する場合、ウィンドウのスクロール位置に合わせて、transform: translateY()
を使って要素の位置をちょっとずつズラして表現してます。※このブログの記事ヘッダー部分参照(2018.10現在)。
一方CSSだけで作るパララックス効果は、実際にtransform: translateZ()
を使って要素を画面の奥にズラして、本当に奥行きを使ってパララックスを表現します。
CSSでパララックス効果を作る方法について、詳しくは下記記事を参照のこと。
動くCSSのためのメモ。パララックス(2014.6.5)
スクロールする要素を作る
CSSのパララックスは、いつものウィンドウのスクロールでは出来なくて、スクロールする要素を別途用意しなくちゃいけません。
ここでは#wrapper要素の中身をスクロールするようにします。要素のサイズを固定して、overflowプロパティでauto
を指定すれば、その要素の中身がはみ出す場合にスクロールバーが表示されるようになります。
#wrapper {
position: absolute;
overflow: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
︙
-webkit-overflow-scrolling: touch
は、iPhoneでの慣性スクロールを有効にするための指定。
さらに、will-change: scroll-position
を指定することで、スクロール可能なコンテンツのレンダリングの最適化が図れます。
︙
-webkit-overflow-scrolling: touch;
will-change: scroll-position;
︙
そしてパララックスの要、perspectiveプロパティで、その子要素に指定した3Dを伴う変形の奥行きを指定します。
︙
perspective: 200px;
}
will-changeプロパティについて、詳しくは以下の記事を参照のこと。
- CSS will-changeプロパティについて知っておくべきこと | POSTD(2014.7.1)
- CSS: will-change指定時の挙動, パフォーマンスへの影響と考察(2016.7.28)
要素を奥に移動する
あとは、パララックス効果をつけたい要素を、transformプロパティで、手前or奥へ移動させればよいです。
まずはページタイトル。もともと、要素の中央に配置するためにtranslateY(-50%)
が指定してあったので、それを残しつつ、translateZ()
も指定しなくちゃいけません。そんな時は、(x, y, z)
をまとめて指定できるtranslate3d
で指定しましょう。3つめの値がz方向への移動の指定で、正の値が手前へ、負の値が奥への移動を表します。単位はpx
を使います。
header h1 {
transform: translate3d(0, -50%, -100px) scale(1.5);
︙
その際、奥へ移動するときの消失点(#wrapper要素のperspective-origin
)が、ウィンドウ中央になっているため、100px奥へ移動した分、表示位置が下に下がって見えてしまいます。そこで、ページタイトル自体の、変形するときの原点(transform-origin
)を適宜指定して、header要素の中央に表示されるように調整しています。ここではx方向に50%
、y方向に25vh
の位置を指定。
︙
transform-origin: 50% 25vh;
}
img要素にも、同じ要領で奥への移動と、transform-originプロパティの調整をすれば、できあがり!
header figure img {
︙
min-width: 66.6666vh;
transform-origin: 50% 100%;
transform: translate3d(-50%, -50%, -50px) scale(1.26);
}
※scale(1.26)
の指定は、ほんとはscale(1.25)
なのですけれど、スクロールバーが常に表示されてるタイプのデバイス(Windowsとか)の場合、その幅分、ウィンドウ幅とvh単位の値とに誤差が出てしまうみたいなので、img要素を若干header要素からはみ出すくらい大きめに拡大しています。
背景画像として表示するタイプでもパララックス
header要素にbackgroundプロパティで指定したままでは、パララックス効果を作るのは難しいため、header要素に::before擬似要素を使って、それに背景画像を表示させて、パララックス効果を作ります。
※::after擬似要素は、半透明のスクリーントーンの表示に使っているので、::before擬似要素を使います。
header::before {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url(../img/background.jpg) center / cover;
︙
パララックス効果のための指定は、img要素で表示するタイプのとほとんど同じですけれど、画面めいっぱい表示はbackground-size: cover
でできているので、transform
の指定は、translateZ()
とscale()
の調整だけでよいですね;)。
︙
transform-origin: 50% 100%;
transform: translateZ(-50px) scale(1.26);
}
Safari、Firefox、IEで表現できるパララックス
SafariやFirefox、IE/Edgeでは、perspectiveプロパティを指定した直接の子要素のみ、奥行きが適用されるようです。
そのため、今回のように、#wrapper要素にperspectiveプロパティを指定して、その子要素のheader要素の中の、figure要素の中の、img要素に指定した奥行きは、表現されません…¦(。
下記サンプルのように、#wrapper要素の直接の子要素であるheader要素自体を奥に移動してのパララックス効果は表現できました。
※IE/Edgeではスムーズにスライドしませんが、奥行きは適用されてる様子が伺えます…。
Safari、Firefox、IEでもChromeと同じ感じにパララックスする
HTMLを以下のように書き換えれば、Chromeと同じ感じのパララックス効果をつけれそうです。figure要素をheader要素から出して、スクロールコンテナである#wrapper要素の直下に移動してみました。
<header>
<h1>Halfscreen Photo Header</h1>
</header>
<figure>
<img src="img/background.jpg" alt="" width="1024" height="768">
<figcaption class="caption">license</figcaption>
</figure>
CSSもそれに合わせて修正します。
タイトル自体(h1要素)には奥行きが適用されないので、タイトルを奥へ移動するには、header要素ごと移動します。
figure要素をheader要素の外に出したため、figure要素の高さはheader要素と同じく50vh
に指定。そして、奥へ移動するのはimg要素ではなく、figure要素です。
header {
︙
height: 50vh;
transform-origin: 50% 100%;
transform: translateZ(-100px) scale(1.5);
}
figure {
︙
height: 50vh;
margin: 0;
transform-origin: 50% 100%;
transform: translateZ(-50px) scale(1.26);
}
Safariだけ、ページタイトルが表示されないですね…。
ここでは、header要素にtranslateZ(-100px)
、figure要素にtranslateZ(-50px)
しているため、header要素の方が奥にあるということで、figure要素の裏に隠れちゃってるみたいです。z-indexプロパティも効かないです。
たしかに、物理的に奥にあるのだから、こちらの方が自然なのだけれど…:ω。
Safariでできるパララックス効果
そんなわけで、Safariでもきちんと表示されるように、物理的に自然なカタチで、画像が一番奥、タイトルを画像の手前に配置するようにしました。
header {
︙
transform: translateZ(-50px) scale(1.25);
}
figure {
︙
transform: translateZ(-100px) scale(1.51);
}