CSSやjQueryで実装するhoverやスクロール時の下線アニメーション



グローバルナビゲーションや文章内などのテキストリンクなどで、ユーザーの目を引くような下線アニメーションを実装することもあるでしょう。

マウスカーソルを合わせた時の処理として、PCの表示で有効な:hover擬似クラスを使った効果は、CSSのみで実装することができます。
また、スクロール時のアニメーションでしたら、JavaScriptでスクロールのタイミングで処理を実装することができ、スマートフォンやタブレット端末で効果的です。

テキストリンクでよくある左から下線が引かれるアニメーションであったり、ナビゲーションなどで利用される中央から広がるアニメーションと、主にこの2パターンかと思います。

ここでは、hoverやスクロール時の下線アニメーションの実装方法についてご紹介していきます。

hover時の下線アニメーション


hover時のアニメーションは、CSSのみで手軽に実装することができます。
サンプルではまず、左から下線を引くアニメーションからご紹介します。

左から下線を引くアニメーション


HTMLの構造でテキストリンクを作成します。

HTML

<a class="uLine" href="#">
  <span class="uLine-text">Text Link</span>
</a>


aタグにはCSSクラス「uLine」を付与しておきます。
span要素に対してafter擬似要素で下線を実装していきますので、a要素のテキストをspanタグで囲います。

続いてはCSS。
spanのafter擬似要素で実装する下線の配置を調整するため、親要素のaタグに「position: relative;」、spanのafter擬似要素に「position: absolute;」でポジションを調整します。
下線は擬似要素の高さをheightプロパティで2pxとして表現します。下線の色はbackgroundプロパティで決めます。
ポジションはleftを0とし、また幅を「width: 0;」として通常は表示されないようにします。

CSS

.uLine {
  text-decoration: none;
  color: #f46400;
}

.uLine-text {
  position: relative;
  font-size: 1.3rem;
}

.uLine-text:after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -0.3rem;
  width: 0%;
  height: 2px;
  background: #f46400;
  transition: all 0.5s;
}

.uLine:hover .uLine-text:after {
  width: 100%;
}


spanのafter擬似要素のtransitionプロパティでは、アニメーションの変化の時間を指定します。ここでは0.5秒で変化するように設定します。
ユーザーがテキストリンクにカーソルを重ねた時に、:hover擬似クラスで下線の幅を100%として、0.5秒かけて左の0地点から右の100%にかけて下線を引きます。

hover時の左から下線を引くアニメーション

中央から下線が広がるアニメーション


続いては、中央から下線を広げるパターンです。
CSSクラスの名前を変更しているくらいで、HTMLはほぼ同じ構造になります。

HTML

<a class="uLine" href="#">
  <span class="uLine-center">Text Link</span>
</a>



CSSも先ほどとあまり変わりませんが、spanのafter擬似要素のポジションを中央配置にするため「left: 50%;」とし、またtransformプロパティを使って「transform: translateX(-50%);」として、中央から100%に広がるようにします。

CSS

.uLine {
  text-decoration: none;
  color: #f46400;
}

.uLine-center {
  position: relative;
  font-size: 1.3rem;
}

.uLine-center:after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -0.3rem;
  transform: translateX(-50%);
  width: 0%;
  height: 2px;
  background: #f46400;
  transition: all 0.5s;
}

.uLine:hover .uLine-center:after {
  width: 100%;
}
hover時の中央から下線が広がるアニメーション


hover時にどこのポジションを基準に下線を引くかを、positionプロパティや幅で調整していくところがポイントになります。

スクロール時の下線アニメーション


スクロール時の下線アニメーションはPCのみならず、マウスを重ねる表現がないスマートフォンやタブレット端末でも効果的です。
スクロール時についても左からと中央からと、2パターンのアニメーションの実装を見ていきます。

表示領域で左から下線アニメーション


まずは、HTML構造から見ていきましょう。
sectionでコンテンツブロックを作って、各ブロックコンテンツに見出しを用意しました。
h2のspan要素で下線を実装していきます。

HTML

<section>
  <h2><span class="headline">HEADLINE</span></h2>
</section>

<section>
  <h2><span class="headline lineAnimation">HEADLINE</span></h2>
</section>

<section>
  <h2><span class="headline lineAnimation">HEADLINE</span></h2>
</section>



CSSは、hoverのパターンとさほど変わらず、HTML構造に合わせてCSSクラスに対するスタイルを適応していきます。

CSS

section {
  width: 100%;
  height: 100vh;
  padding: 4%;
}

section:nth-child(2n) {
  background-color: #f2effb;
}

h2 {
  font-size: 2.6rem;
  text-align: center;
}

.headline {
  position: relative;
}

.headline:after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -14px;
  width: 0%;
  height: 4px;
  background: #f46400;
  transition: all 0.5s;
}

.headline.isActive:after {
  width: 100%;
}


span要素にCSSクラス「isActive」が付与された場合に、幅を100%としてアニメーションさせます。
スクロール時の下線アニメーションを適応させることになります。

スクロール時の処理は、JavaScriptで実装していきます。
CSSクラス「lineAnimation」を対象に下線をアニメーションさせます。

JavaScript

const scrollAnim = () => {

  const fadeElem = document.querySelectorAll(".lineAnimation");

  window.addEventListener("scroll", (event) => {
    fadeElem.forEach((fadeElem) => {
      const position = fadeElem.offsetTop;
      const scroll = window.scrollY;
      const windowHeight = window.innerHeight;
      if (scroll > position - windowHeight + 180){
        fadeElem.classList.add("isActive");
      }
    });
  });

}
scrollAnim();



scrollAnimという名前の関数を作成して実行しています。
変数「fadeElem」には、CSSクラス「lineAnimation」の要素を格納して、addEventListenerでスクロールイベントが発生した際に、forEachメソッドでマッチした各要素(CSSクラス「lineAnimation」)に対して処理をする関数を用意します。
「fadeElem.offsetTop;」で各対象要素の位置を変数「position」に格納して、「window.scrollY;」でウィンドウ最上部からのスクロール位置を取得して変数「scroll」に格納します。
また、表示するタイミングを少し調整するために、「window.innerHeight;」でウィンドウの高さを取得して、変数「windowHeight」に格納しておきます。

これら3つの変数の値をもとに、if文の条件「scroll > position – windowHeight」で、ウィンドウの高さを引いた要素のポジションよりスクロールの数値が大きくなった時(要素が表示領域まで来た時)に、classList.addメソッドでCSSクラス「isActive」を付与します。
CSSではisActiveのafter擬似要素に対して幅を100%としますので、下線がアニメーションしながら表示されます。

スクロール時に表示領域で左から下線アニメーション



下線アニメーションの発火タイミングを少し遅くする場合は、if文の条件を「scroll > position – windowHeight + 180」と180pxを足して、要素が表示領域に入ってからさらに180pxスクロールされたら、クラスが付与されてアニメーションが実行されます。



また、JavaScriptを簡易に書けるjQueryで実装する場合は、以下のようなプログラムになります。

jQuery

$(window).on('scroll',function(){
  $(".lineAnimation").each(function(){
    let position = $(this).offset().top;
    let scroll = $(window).scrollTop();
    let windowHeight = $(window).height();
    if (scroll > position - windowHeight + 180){
      $(this).addClass('isActive');
    }
  });
});



「$(window).on(‘scroll’,function(){});」で、スクロールした際に関数の処理を実行します。
each()メソッドで、マッチした各要素(CSSクラス「lineAnimation」)に対して処理をする関数を用意します。
「$(this).offset().top;」でHTML要素(CSSクラス「lineAnimation」)の位置を取得し、変数「position」に格納します。
「$(window).scrollTop();」では、ウィンドウ最上部からスクロールした現在位置までのピクセル数を取得し、変数「scroll」に格納します。
「$(window).height();」では、ウィンドウの高さを取得し、変数「windowHeight」に格納します。

あとは、純粋なJavaScriptのサンプルと同じように、if文の条件「scroll > position – windowHeight」で、ウィンドウの高さを引いた要素のポジションよりスクロールの数値が大きくなった時に、addClassメソッドでCSSクラス「isActive」を付与します。

表示領域で中央から下線アニメーション


続いては中央からの下線アニメーションです。
HTMLの構造は同じで、CSSでCSSクラス「headline」のafter擬似要素のポジションを、「left: 50%;」と「transform: translateX(-50%);」で中央とします。

CSS

section {
  width: 100%;
  height: 100vh;
  padding: 4%;
}

section:nth-child(2n) {
  background-color: #f2effb;
}

h2 {
  font-size: 2.6rem;
  text-align: center;
}

.headline {
  position: relative;
}

.headline:after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -0.3rem;
  transform: translateX(-50%);
  width: 0%;
  height: 4px;
  background: #f46400;
  transition: all 0.5s;
}

.headline.isActive:after {
  width: 100%;
}
スクロール時に表示領域で中央から下線アニメーション



JavaScriptやjQueryは変更する必要はありません。
CSSクラス「isActive」が付与されれば、あとは中央から100%に広がるように下線がアニメーションします。

蛍光ペンのようにマーカーを引く


コンテンツの文章内の重要なワードに下線アニメーションを実装して、ユーザーの注意を引くのもいいでしょう。
よくあるのが、蛍光ペンでマークするようなマーカーを引くデザインです。
以下、サンプルになります。

HTMLでは、文章内で目を引きたいテキストをspanタグで囲い、CSSクラス「marker-text」を付与します。
さらに入れ子でspanタグでテキストを囲います。(spanタグの入れ子は、テキストとマーカーの重ね順を調整しやすいようにするため)

HTML

<section>
  <h2><span class="headline">HEADLINE</span></h2>
  <p>abcdefghijklmnopqr<span class="lineAnimation marker-text"><span>stu</span></span>vwxyz</p>
</section>


CSSでは、これまでと同じようにafter擬似要素でマーカー線を引きます。
heightの数値を高くして、テキストの背景に線を引く表現をします。

CSS

section {
  width: 100%;
  height: 100vh;
  padding: 4%;
}

p {
  font-size: 1.4rem;
}

.marker-text {
  position: relative;
}

.marker-text span {
  position: relative;
  z-index: 2;
}

.marker-text:after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0.1rem;
  width: 0%;
  height: 10px;
  background: rgba(255, 145, 145, .8);
  z-index: 1;
  transition: all 0.5s;
}

.marker-text.isActive:after {
  width: 100%;
}


兄弟要素となるテキストと擬似要素のマーカーの重ね順を、z-indexで調整してテキストが上に重なるようにします。

スクロール時に蛍光ペンのようなマーカーを引く



これで、スクロールしながらコンテンツを見ていく中で、ユーザーの注意を引いて見てもらいたいポイントを強調することができます。

以下、ここまでの下線アニメーションの実装になります。
動画(2分55秒)

まとめ


hover時のアニメーションであればCSSのみで、スクロール時であればJavaScriptやjQueryで、手軽に下線アニメーションが実装できます。

after擬似要素やtransitionプロパティをうまく使いこなして、Webデザインの幅を広げてみてください。

また、CSSでも新たに追加されたプロパティのサポートが進んでいることもあり、CSSのみでもスクロール時のアニメーションが実装できるようになってきています。

CSSのみでのスクロール時のアニメーションについては、以下の記事でご紹介しています。