蛍光ペンでマーカーを引いたような、線。
Webサイトで良く用いられる表現なので、皆さんも何度か見たことあるんじゃないでしょうか?
今回はそんなマーカーの引き方。
画面に入った際に、スッと線を引いたようなアニメーションをjQueryなしで実装しましょう。
マーカーの引き方
アニメーションを実装する前に、まずはマーカーの引き方を覚えましょう。
HTML
<p class="marker">マーカーを引くテキスト</p>
<p>マーカーを<span class="marker">この中だけ</span>引きたい</p>
今回、マーカーのクラスを「marker」で作成しました。
マーカーを引きたい文章を「marker」クラスで囲むだけです。
CSS
.marker {
/* マーカーを引く
rgba(255, 153, 0,0.5) の部分はマーカーの色を指定しています。
実装される際は、お好きな色、透明度をお入れ下さい。 */
background:linear-gradient(transparent 50%, rgba(255, 153, 0,0.5) 50%); /* マーカーを引く */
/* インライン属性を指定する */
display: inline;
}
cssもこれだけです。
これで、下記のようなマーカーが引けたと思います。
CSSの解説
それでは、cssの中身を一つずつ見ていきましょう。
background:linear-gradient
「background:linear-gradient」は背景にグラデーションを指定するプロパティです。
グラデーションというと、徐々に色が変わっていくイメージがありますが、それだけでなく、グラデーションさせずに色を二色、三色にきっちり分ける事も可能です。
それを踏まえてもう一度cssを確認しましょう。
「transparent」と「マーカーの色(rgba)」を50%)ずつ指定して、下半分のみに色を付けています。
background:linear-gradient(transparent 50%, rgba(255, 153, 0,0.5) 50%);
今回は50%でしたが、この部分を変更することで好きな太さに調整できます。
●80%
background:linear-gradient(transparent 80%, rgba(255, 153, 0,0.5) 80%);
●10%
background:linear-gradient(transparent 10%, rgba(255, 153, 0,0.5) 10%);
display: inline;
markerクラスをわざわざインライン要素にしているのは、「複数行にマーカーを引くため」です。
ブロック要素でもマーカーは引けますが、複数行を引くことはできません。
それを証明するために、文章を改行してみました。
このように、ブロック要素では、2行の真ん中にマーカーが引かれていますが、インライン要素では2行それぞれにマーカーが引かれています。
インライン要素にする理由がお分かりになられたと思います。
グラデーションのマーカーを引く
先述の例では、マーカーの色は1色でしたが複数色やグラデーションのマーカーを引くことも可能です。
.marker {
/* 90degでグラデーションの向きを横方法にする */
background-image: linear-gradient(90deg, #ec008c,#f3c600 100%);
/* グラデーションの繰り返しをオフ */
background-repeat: no-repeat;
/* 横方向を100% 線の太さを2番目で指定します。ピクセルでも%でも指定可能です */
background-size: 100% 0.3em;
/* 線の位置を指定 今回は1番下に線が来るように指定 */
background-position: 0 100%;
}
横方向にグラデーションを指定し、「background-size、background-position」で太さ、位置を指定しています。
グラデーションマーカーを引く際はツールを使おう
軽く説明しましたが、ある程度理解したらツールを使って時短しましょう。
グラデーションのマーカーを作成するジェネレーターです。
選ぶ項目も少なく、直観的に作成できるので簡単に使用できると思います。
■Underline Generator
https://underline-generator.netlify.app/
スクロールでマーカーが引かれるアニメーションを作成
次にスクロールすると、マーカーが引かれるようなアニメーションを作成しましょう。
CSS
今回アニメーションの動き自体はCSSを使用して作成します。
マーカーのスタイルも少し変化するので見てみましょう。
.marker {
background:linear-gradient(transparent 50%, rgba(255, 220, 123) 50%);
display: inline;
/* 背景の繰り返しを停止 */
background-repeat: no-repeat;
/* マーカーの横方向を0にして縮める */
background-size: 0% 100%;
/* マーカーが引かれる速度を指定 */
transition:background-size 1.5s;
}
/* マーカーが引かれる際に付与するクラス */
.marker.on {
/* 横方向を100%にして、マーカーを引く */
background-size: 100% 100%;
}
仕組み自体は簡単で、「background-size:0 100%」でマーカーの長さを0にして、「marker」クラスに「on」クラスが付与されると、長さを100%にするという仕組みです。
そのマーカーが引かれる速度を「transition:background-size 1.5s;」で指定しています。
ここはお好みの秒数を指定しましょう。
JavaScript
次に、スクロールで「marker」クラスに「on」クラスを付与する処理を作成します。
今はjQueryを使用しない事が流行りつつあるので、素のJavaScriptで実装しましょう。
window.addEventListener('scroll',function() {
const height = window.innerHeight; //画面の高さを取得
const scroll = this.pageYOffset; //スクロール量
const marker = document.querySelectorAll('.marker'); //マーカーを引く要素を取得
const value = scroll - height + 300 //後ろの数字を弄ることで、イベント位置をずらす
// markerクラスを持っている要素全てに処理を行う
marker.forEach(function(element){
//要素が画面内の指定の位置に来たら「on」クラスをつける
if (scroll > element.getBoundingClientRect().top + value) {
element.classList.add('on')
}
});
})
まず、「document.querySelectorAll('.marker')」で「marker」クラスが付いている要素を全て取得しています。
const marker = document.querySelectorAll('.marker'); //マーカーを引く要素を取得
「forEach」関数を使用し、取得した「marker」クラスを持つ要素全てに同じ処理を行います。
「marker」クラスを持った要素が画面の下に来たら「on」クラスを付与しています。
// markerクラスを持っている要素全てに処理を行う
marker.forEach(function(element){
//要素が画面内の指定の位置に来たら「on」クラスをつける
if (scroll > element.getBoundingClientRect().top + value) {
element.classList.add('on')
}
});
})
ちなみに、「on」クラスを付与する条件は以下の通りです。
スクロール量 > マーカー要素の画面上からの高さ + (スクロール量 - 画面の高さ)
この式で画面に要素が入ってきたら発火するイベントを作成できます。
他のスクロールイベントでも利用できるので、頭の片隅に置いておきましょう。
また、「300」という数字は、画面に要素が入ってから処理を実行するまでの猶予になります。
この数字が大きいほど画面の上の方で処理が実行されます。
const value = scroll - height + 300 //後ろの数字を弄ることで、イベントを画面内の土の位置で実行するかを指定する
まとめ
以上 cssで蛍光ペンのようなマーカーを引く方法でした。
終わってみれば、仕組み自体は簡単でしたね。
結構デザイン的には、使用することも多いのでコピペできるように、スニペットとして残しておくと楽かもしれません。
また、JavaScriptは簡単に扱える半面、自己学習するには奥が深い言語になります。
そういった時は、動画で学習することがオススメです。
実際の動作やコードの入力風景などを確認しながら学習が出来ます。
そんな動画学習でオススメが「Schoo」です。登録・生放送授業は無料です。
是非、一度お試しください。