画面内に入った要素の背景色を横から延ばす方法

WEBサイトで、ページをスクロールさせているとサーっと横から背景色が伸びてきて、白かった要素の背景に背景色がつくページを見たことはありませんか?


この仕掛けは比較的簡単に作れて、見てくれる人に「おっ!」と思わせる効果があるような気がします。

ゆんつ
僕は結構好きです

今日はHTMLとCSS、jQueryを使ってページがスクロールして特定の要素が現れたら、その背景の背景色が伸びてくる仕掛けを作りたいと思います。

実装

作り方は簡単です。

対象となる要素に疑似要素をつけて、その疑似要素に

  • 背景色
  • width: 0(これにより初期状態は背景色が無し)
  • height: 100%
  • position(left:0,top: 0;なら左からright: 0,top: 0;なら右から背景色が伸びてくる)
  • transition(背景色が伸びる速度の調整)

などを設定します。

そして jQueryでスクロールを監視し、要素が画面内に表れるのに合わせてその疑似要素のwidthを100%に上書きするクラスを付けてあげれば良いだけです。

実際に作ってみましょう。

<div id="content">
  <section class="blue"><span>青背景固定</span></section>
  <section class="yellow"><span>左から黄色背景</span></section>
  <section class="red"><span>右から赤背景</span></section>
</div>
.blue,
.yellow,
.red {
  height: 500px;
  text-align: center;
  line-height: 500px;
  position: relative;
  font-size: 30px;
}

span {
  position: relative;
}

.blue {
  background: blue; 
}

.yellow::before{
  content: '';
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  background: yellow;
  transition: 0.5s;
}

.red::before{
  content: '';
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  width: 0;
  height: 100%;
  background: red;
  transition: 0.5s;
}

.fade::before {
  width: 100%;
}
$(function(){
  $(window).scroll(function (){
    $('.yellow, .red').each(function(){
      
      //要素の位置の取得
      var target = $(this).offset().top;
      
      //スクロール量を取得
      var scroll = $(window).scrollTop();
      
      //ウィンドウの高さを取得
      var windowHeight = $(window).height();
      
      //目的の要素が画面内に少し入ったらクラスを付与する
      if (scroll > target - windowHeight + 200){
          $(this).addClass('fade');
      }
    });
  });
});

See the Pen fade1 by konpure (@yuntu) on CodePen.

先頭のクラス名がblueのセクションは、背景色が青色で固定されており特に変化はありません。

しかし、後に続くクラス名yellowとredに関しては、クラス名と同じ背景色が画面スクロールにより左または右から出現します。

jQueryの働きについてはコード中のコメントを参照してください。

target - windowHeight + 200の「+200」の意味合いは言ってみれば「ブレーキの遊び」の部分みたいなものです。

画面内に対象の要素が入ってきてすぐにアニメーションさせるのではなく、画面内に入ってからさらに200pxスクロールすることで背景色が出現するようにしています。

要素が画面内に入った瞬間に背景色をアニメーションさせたければ「+200」は不要です。

と、まあこんな感じでスクロールにより要素の背景色が伸びてくるアニメーションを行います。

もう1つのCSSの書き方

先ほどのCSSでは背景色のアニメーションをさせたい要素にwidth: 0の疑似要素をつけて、それを後からwidth: 100%の疑似要素で上書きするという形をとりました。

これ以外にもCSSの書き方があります。

それはtransformプロパティのscaleを使う方法です。

このようなCSSになります( HTMLとjQueryは先ほどと全く同じです )。

.blue,
.yellow,
.red {
  height: 500px;
  text-align: center;
  line-height: 500px;
  position: relative;
  font-size: 30px;
}

span {
  position: relative;
}

.blue {
  background: blue; 
}

.yellow::before{
  content: '';
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  background: yellow;
  transition: 0.5s;
  transform-origin: left top;
  transform: scale(0, 1);
}

.red::before{
  content: '';
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  background: red;
  transition: 0.5s;
  transform-origin: right top;
  transform: scale(0, 1);
}

.fade::before {
  transform: scale(1, 1);
}

See the Pen fade2 by konpure (@yuntu) on CodePen.

先ほどのCSSとは違い疑似要素のwidthは最初から100%ですが、transform: scale(0, 1);としておきます。

またそれに伴いtransform-originも設定します(左から出現させるならならleft top、右から出現させるならright top)。

そしてjQueryでスクロールを監視し、一定のスクロール量に達したらtransform: scale(1, 1)が設定されたクラスを付与して scale(0, 1) を上書きするという方法になります。

アニメーション的には先ほどの「width: 0 → width: 100」のものと同じになるので、どちらでも好きな方を使うと良いと思います。

ちょっとしたワンポイントとして使うと良いかも

背景色をアニメーションさせたからといって、アクセスが増えるという事はないと思いますが、 こういうちょっとした遊び心も楽しいんじゃないかと思います。

簡単にできるので、もしよかったらやってみてください。

ゆんつ
それでは、またー