パララックスWEBサイトの作り方(HTMLとCSSのみで実現するparallax効果)
パララックスWEBサイトとはパララックス効果による視覚的PRを目的としたWEBサイトの事です。
WEBページ上に奥行の概念を持たせ、各要素の奥行きの差により立体的な演出効果を出しています。
cssによるparallax効果ポイント
・要素が奥にあるほど動きは遅くなる
・要素が手前にある程動きが早くなる
・要素が奥にある程その形状サイズが小さくなる
・要素が奥にある程scale係数で大きさを維持する
・要素を連続で表現する場合はグループ化しておく事
本記事ではhtmlとCSSのみで実現したパララックス効果の例とその仕組みについてご紹介します。
パララックスWEBサイトとは?
あなたは「パララックスサイト」という言葉をご存知ですか?
パララックスサイトとは、parallax(視差)の効果を適用したWEBサイトのことです。
parallaxとはページをスクロールする際、手前と奥とでスクロールの速度に差をつけることで、奥行きや立体感を表現するものを指します。
パララックス効果のメリット
この手前と奥とでスクロールの速度に違いがでると、通常2次元の世界にあるWEBページが3次元の奥行きを感じる様になります。
視覚差を使ったエフェクトはPRしたい部分を強調でき、ユーザーにインパクトを与える事ができます。
その効果によりユーザーの興味・関心が高まることが狙いです。
パララックス効果の仕組み
パララックス効果を使う際、特に気にせずにjquery等のプラグインを導入して簡単に実現している人もいると思います。
しかし本来パララックスがどのように実現されているのか、その基本的な仕組みが把握できている人は少ないと思います。
そこで本記事では視差効果をどのように実現しているのかをHTMLとCSSのみで紹介します。
パララックス効果の基本を知る
パララックス効果の仕組みを詳しく説明する前に、効果を実現するベースとなるHTMLマークアップをしておきましょう。
HTMLソース
<div class="parallax"> <div class="parallax_layer parallax_layerback"> <div class="title">background1</div> </div> <div class="parallax_layer parallax__layerbase"> <div class="title">background2</div> </div> </div>
そしてここに基本的なCSSスタイルのルールを適用します。
CSSソース
.parallax {
perspective: 1px;
height: 400px;
overflow-x: hidden;
overflow-y: auto;
position: relative;
font-size: 200%;
}
.parallax_layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 400px 0;
}
.parallax_layerbase {
transform: translateZ(0);
}
.parallax_layerback {
transform: translateZ(-1px);
}
.title {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
htmlとcssのみによるparallax実行例
background1
background2
.parallaxクラス
視差のマジックを起こす基本ベースとなる枠が「parallax」クラスです。
上記CSSの様に「height」および「perspective」プロパティを定義すると、要素がその中心にロックされ、固定された部分となる3Dビューポート(奥行き)が作成されます。
overflow-y: autoの設定により、親要素のコンテンツは通常通りスクロールされますが、子要素はperspectiveにより、固定位置にレンダリングされます。
この部分が視差効果を作成するための鍵となりますね。
.parallax_layerクラス
次はparallax_layerクラスでその名前が示す通り、視差効果が適用されるコンテンツのレイヤーを定義します。
要素はposition: absoluteにより絶対配置がされ、親要素のスペースを満たすように構成されます。
装飾子クラス
最後に修飾子クラスである「parallax_layerbase」と「parallax_layerback」です。
これらは視差要素のスクロール速度を決定するために使用され、Z軸方向(モニターの奥)に向かって移動します。
モニター側(上)に移動するか、逆にモニターから離れる(下)かの移動が起きます。
※今回はわかりやすく、2つのレイヤー構成のみにしています。
要素の高低差の補正
(translateZ)を扱う場合はscale係数に注意
視差効果は3D変換を使用して作成されるため、要素が奥行(Z軸)に沿って移動する場合、特有の影響が出ます。
3Dビューポートから近づけたり遠ざけたりすると、それに応じて「対象の大きさ・サイズ」が変化してしまうのです。
自然界でも、遠くにいる人が小さく見え近くにいる人が大きく見えますよね、あれと同じです。
parallaxの世界では大小に変化する必要は無いので、元のサイズで見える様に要素にscale()変換を適用します。
スケール係数:scale()
つまり奥に移動した分だけ小さくなった要素を、scale係数を使って元サイズまで戻す事になります。
.parallax_layerback { transform: translateZ(-1px) scale(2); }
スケール係数は1 + (translateZ * -1) / perspective」で計算できます。
たとえばビューポートperspectiveが「1px」に設定されていて、要素を奥行Z軸に沿って-2px移動する場合、補正倍率は「3」になります。
計算式
1+-2×-1÷1=3、scale係数は3
.parallax_layerback { transform: translateZ(-2px) scale(3); }
こうする事により、ビューポートから離した時に起こる対象サイズの変化を維持する事ができます。
レイヤー速度の制御
レイヤーの速度は、遠近法とZ変換値の組み合わせによって制御されています。
マイナスのZ値を持つ要素は、正の値を持つ要素よりも奥にあるため、スクロールが遅くなります。
つまりマイナス値が大きくなるほど、その視差効果がより顕著に出る訳です。
具体的には、translateZ(-10px)の方がtranslateZ(-1px)より視覚効果が大きい事になりますね。
速度を変えたらスケール係数を変更
マイナスZ値が大きいという事は上で説明した3Dの考え方からいくと、より奥(遠く)にある事になります。
「要素の高低差が大きくなると同時にサイズも小さくなる現象が起きる」
これは先ほど説明した通りです。
ですので、先ほどのスケール係数の計算公式に当てはめてscale()の値も変更しなければなりません。
perspectiveが1のままなら、公式は「1 + (-10 * -1) / perspective」ですから、スケール係数scale()は「11」になります。
.parallax_layerback { transform: translateZ(-10px) scale(11); }
視差セクションをグループ化
前の例では非常に単純なコンテンツを使用した基本的な手法を示しました。
しかし視差効果を見せるWEBサイトの主流は、ページを異なるセクションに分割し、それを連続で表現する事で様々な効果を適用します。
つまり、一か所だけでなく複数を縦に並べて設置する訳ですね。
セクションごとのグループ化
連続でパララックス効果を演出するためには、まずparallax_groupレイヤーで各要素をグループ化する必要必要があります。
HTMLソース
<div class="parallax"> <div class="parallax_group"> <div class="parallax_layer parallax_layerback"> <div class="title">background1</div> </div> <div class="parallax_layer parallax_layerbase"> <div class="title">background2</div> </div> </div> <div class="parallax_group"> </div> </div>
CSSソース
.parallax_group { position: relative; height: 400px; transform-style: preserve-3d; }
group化実行例
この例では、groupクラスに各height: 400pxのビューポートで囲っており、必要に応じて各グループに任意の値を設定できます。
「transform-style: preserve-3d」は、ブラウザがparallax_layer要素自体を平坦化するのを防いでいます。
各グループ要素に対してposition: relativeで相対的にparallax_layerの子要素を配置できるようにするためです。
グループ化する際の注意点
要素をグループ化する際に注意するべきは、グループのコンテンツをクリップできないことです。
parallax_groupにoverflow: hiddenを設定すると、視差効果が失われます。
クリップされていないコンテンツは、子孫要素がz-indexによりオーバーフローしてしまいます。
ユーザーがWEBページをスクロールする時にコンテンツが正しく表示・非表示になるよう、グループの値を工夫する必要があります。
各グループ間の機能状態を確認する
実装は設計間で異なるため、階層化を処理するための厳格なルールはありません。
別ページのデバッグの様に視差効果がどのように機能するかを確認できれば良いと思います。
上記ページの左上の「debug」ボタンを押すと、構成している3Dビューポートを斜めから視認した状態を実現できます。
ブラウザのサポート
Firefox、Safari、Opera、Chromeはすべてこのパララックス効果をサポートしています。
IEはまだpreserve-3dをサポートしていないため、視差効果は機能しませんがそれでも問題ありません。
コンテンツは基本的に視差効果なしで機能するように設計するべきであるためです。
ですのでパララックスが動かなくても視覚的に問題ないかのチェックは必要です。
モバイルでは上記パララックスは動かない
ここまでパララックスの大まかな仕組みをご紹介してきました。
実はこれまで説明してきたコードではスマホなどの端末では動きません。PC専用のコードになります。
仕組みを理解してもらうためにご用意したものでしたので、その辺りはどうぞご容赦下さい。
ですので本記事をスマホで閲覧しているユーザーは事例を確認する事ができません。申し訳ございません。
PC・スマホ両方での実現にはプラグインを使う
スマホなどのモバイル端末でもパララックス効果を出したい場合は、各種プラグインを使う事がセオリーになります。
プラグイン「universal parallax」
スムーズにスクロールしつつ視覚効果の高いparallax効果を表現できます。
HTMLソース
<section class="container container--big"> <div class="content"> <h1>Universal Parallax</h1> <blockquote> Section One </blockquote> </div> <div class="parallax parallax--bg bg1"></div> </section> <section class="container container--small"> <div class="content"> <blockquote> Section Two </blockquote> </div> <div class="parallax parallax--bg" data-parallax-image="../../images/parallax_basic_img2.jpg"> </div> </section> <section class="container container--huge"> <div class="content"> <blockquote> Section Three </blockquote> </div> <div class="parallax parallax--bg" id="bg3"></div> </section> <section class="container container--big"> <div class="content"> <blockquote> Section Two Four </blockquote> </div> <div class="parallax" data-parallax-image="../../images/parallax_basic_img3.jpg"> </div> </section> <script src="universal-parallax.min.js"></script> <script> new universalParallax().init(); </script>
CSSソース(main.css)
*,:after,:before{box-sizing:border-box}body,html{height:100%;width:100%}body,p,h1,h2,h3{padding:0;margin:0}p,h1,h2{line-height:1.3;width:100%;text-shadow:0 0 5px rgba(0,0,0,.8)}body{font-family:source sans pro,helvetica,arial;font-weight:300;font-size:18px}p{font-size:1em}.p--copy{padding:3px 0 22px}.p--credits{font-size:.8em;font-weight:700}h1,h2{font-size:1.5em;font-weight:700}a{color:#fff;font-weight:700;text-decoration:none}.a--no-weight{font-weight:300}section{padding:0;margin:0;position:relative;width:100%;display:flex;align-items:center;flex-wrap:wrap}section .content{background:rgba(0,0,0,.4);color:#fff;border-radius:3px;padding:15px 20px;margin:0 auto;text-align:center}.parallax--container{position:absolute;clip:rect(0,auto,auto,0);width:100%;height:100%;top:0;left:0;z-index:-10}.parallax{position:fixed;width:100%;height:100%;top:0;left:0}.parallax--bg{background-repeat:no-repeat;background-position:center;background-size:cover}.container--huge{height:175vh}.container--big{height:100vh}.container--small{height:40vh}.container--random{height:452px}.bg1{background-image:url(../../images/parallax_basic_img4.jpg)}#bg3{background-image:url(../../images/parallax_basic_img5.jpg)}
JSファイル(universal-parallax.min.js)
var universalParallax=function(){var e=function(e,a){a<1.2&&(a=0),window.addEventListener("scroll",function(){for(var t=0;e.length>t;t++){var n=e[t].parentElement,l=n.scrollHeight,r=n.getBoundingClientRect().top,s=(window.innerHeight-l)/2,i=l+2*(s-s/a);e[t].style.height=i+"px";var o=r/a;e[t].style.top=o+"px"}})};this.init=function(a){void 0===a&&(a={}),a={speed:void 0!==a.speed?a.speed:4,className:void 0!==a.className?a.className:"parallax"};for(var t=document.getElementsByClassName(a.className),n=0;t.length>n;n++){var l=document.createElement("div");t[n].parentNode.insertBefore(l,t[n]),l.appendChild(t[n]);var r=t[n].parentElement;r.className+="parallax--container","relative"!==window.getComputedStyle(r.parentElement,null).getPropertyValue("position")&&(this.style.position="relative");var s=t[n].dataset.parallaxImage;void 0!==s&&(t[n].style.backgroundImage="url("+s+")",1===t[n].classList.length&&"parallax"===t[n].classList[0]&&Object.assign(t[n].style,{"background-repeat":"no-repeat","background-position":"center","background-size":"cover"}))}e(t,a.speed)}};
cssファイルの方は任意で変更してください。jsファイルの方はそのままコピペして使ってもらってOKです。
universal parallax例
まとめ
以上パララックス効果の基本的な仕組みをご紹介しました。
ポイントはcssのプロパティで3Dビューポート(奥行き構造)を構成し、その上で各要素の奥行きの差を設定している点ですね。
cssによるparallax効果ポイント
・要素が奥にあるほど動きは遅くなる
・要素が手前にある程動きが早くなる
・要素が奥にある程その形状サイズが小さくなる
・要素が奥にある程scale係数で大きさを維持する
・要素を連続で表現する場合はグループ化しておく事
3D世界を仮想設定しているので、奥にあればあるほど動きは遅くなりますが、遠くにある分だけサイズが小さくなる点を修正しながら構成するところです。
プラグインを使ってしまえばすぐに動くのでに気にする事は無いのでしょうが、基本的な構造を知る事はスキルアップにつながります。
是非押さえておいて頂けれると嬉しく思います。