CSSのみで実装できる!テキストリンクのホバー時に、カラーをアニメーションで変更させる実装方法のまとめ
Post on:2020年3月26日
テキストリンクをホバーした際に、テキストのカラーをスライドのアニメーションで変更させるピュアCSSの実装方法を紹介します。
IEには対応してないけど実装が簡単な方法、IEに対応しているけど実装がちょっと面倒な方法など、プロジェクトの要件に適したテクニックをご利用ください。
4 Ways to Animate the Color of a Text Link on Hover
by Katherine Kato
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- はじめに
- 1. background-clip: text;を使ったテクニック
- 2. widthまたはheightを使ったテクニック
- 3. clip-pathを使用したテクニック
- 4. transformを使用したテクニック
- まとめ
はじめに
ホバー時にテキストリンクのカラーを変更するエフェクトをピュアCSSで実装します。単にカラーを変更するのではなく、その新しいカラーをスライドさせます。
ホバー時に新しいカラーをスライドさせて、テキストリンクのカラーを変更
これを実現するには、4つのテクニックがあります。
ブラウザのサポート、アクセシビリティ、パフォーマンスなど重要な事柄を念頭に置いて、それらを見てましょう。
1. background-clip: text;を使ったテクニック
background-clip: text;は2020年3月現在、IE11以下ではサポートされていません。
参考: background-clip: text;のサポート状況
このテクニックの特徴は、ハードカラーストップのグラデーションを使用して、ノックアウトテキスト(背景が見えるように切り取られたように見えるテキスト)を作成します。HTMLは、ハイパーリンクを作成するlink要素(<a>)一つのみです。
1 |
<a href="#">Link Hover</a> |
では、テキストリンクにスタイルを定義します。
overflow: hidden;を使用することで、ホバー中にハイパーリンク外のコンテンツがすべてクリップされます。
1 2 3 4 5 6 7 8 |
a { position: relative; display: inline-block; font-size: 2em; font-weight: 800; color: royalblue; overflow: hidden; } |
50%のハードストップを持つ線形グラデーションを使用して、リンクの最初と変更後のカラーを定義します。
1 2 3 4 |
a { /* 上記は省略 */ background: linear-gradient(to right, midnightblue, midnightblue 50%, royalblue 50%); } |
background-clipプロパティでグラデーションをクリップし、値にtextを使用してテキストを表示します。また、background-sizeおよびbackground-positionプロパティを使用して、最初のカラーを表示します。
1 2 3 4 5 6 7 8 |
a { /* 上記は省略 */ background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-size: 200% 100%; background-position: 100%; } |
仕上げに、transitionプロパティと:hover疑似クラスを加えます。ホバー時にリンクを左から右に塗りつぶすには、background-positionを使用します。
1 2 3 4 5 6 7 |
a { /* 上記は省略 */ transition: background-position 275ms ease; } a:hover { background-position: 0 100%; } |
これで完成です。
実際の動作は、下記のデモをご覧ください。
See the Pen
Hover Text Fill Effects with CSS (background-clip) by Katherine Kato (@kathykato)
on CodePen.
このテクニックでホバーエフェクトは得られますが、SafariとChromeはテキストの装飾やシャドウもクリップされるので、表示されません(参考: background-clip: text)。つまり、text-decorationプロパティを使用した下線などのスタイルを適用することができません。下線を使用する時は、次に紹介するテクニックを使用してください。
2. widthまたはheightを使ったテクニック
このテクニックは、<a>タグと同じテキストを含むdata属性を使用して、width(左から右、または右から左へスライド)またはheight(上から下、または下から上へスライド)を0%から100%の範囲で設定することで機能します。
HTMLは、下記の通りです。
1 |
<a href="#" data-content="Link Hover">Link Hover</a> |
CSSは、1. background-clip: text;を使ったテクニックからbackgroundプロパティを除いた感じです。大きな違いは、text-decorationプロパティが使用できます。
1 2 3 4 5 6 7 8 9 |
a { position: relative; display: inline-block; font-size: 2em; color: royalblue; font-weight: 800; text-decoration: underline; overflow: hidden; } |
このテクニックでは、data-content属性のコンテンツを使用する必要があります。<a>タグのコンテンツの上に配置されます。data属性のテキストをコピーし、要素の::before疑似要素のcontentプロパティでattr()関数を介して表示させます。
1 2 3 4 5 6 7 8 9 10 |
a::before { position: absolute; content: attr(data-content); /* 属性の値を出力 */ top: 0; left: 0; color: midnightblue; text-decoration: underline; overflow: hidden; transition: width 275ms ease; } |
テキストが次の行に折り返されないようにするには、white-space: nowrap;を加えます。リンクの塗りつぶしのカラーを変更するには、::before疑似要素を使用し、widthが0から始まるcolorプロパティの値を定義します。
1 2 3 4 5 |
a::before { /* 上記は省略 */ width: 0; white-space: nowrap; } |
最後に、::before疑似要素のwidthを100%に増やして、カーソルを置いたときのテキストエフェクトを完成させます。
1 2 3 |
a:hover::before { width: 100%; } |
これで完成です。
実際の動作は、下記のデモをご覧ください。
See the Pen
Hover Text Fill Effects with CSS (width/height) by Katherine Kato (@kathykato)
on CodePen.
このテクニックはうまくいきますが、widthまたはheightプロパティを使用してもパフォーマンスの良いCSSトランジションは生成されません。transformプロパティまたはopacityプロパティを使用して、スムーズな60fpsトランジションを実装することをお勧めします。
参考: CSS Triggers -width
text-decorationプロパティが使用できるということは、CSSでさまざまな下線スタイルを表示できるということです。次に紹介するclip-pathプロパティを使用して、文中にさまざまな下線を適用することもできます。
See the Pen
Link Fill on Hover by Katherine Kato (@kathykato)
on CodePen.
3. clip-pathを使用したテクニック
このテクニックでは、clip-pathプロパティでポリゴンシェイプを使用します。ポリゴンシェイプには4つの頂点があり、ホバーすると2つの頂点が右に展開されます。
clip-pathを使用したテクニックの仕組み
HTMLは前と同じで、再度::before疑似要素を使用しますが、CSSは少し異なります。
1 2 3 4 5 6 7 8 |
a::before { position: absolute; content: attr(data-content); color: midnightblue; text-decoration: underline; clip-path: polygon(0 0, 0 0, 0% 100%, 0 100%); transition: clip-path 275ms ease; } |
前のテクニックとは異なり、text-decoration: underline;は::before疑似要素で定義する必要があります。
clip-pathプロパティに注目してみましょう。
1 |
clip-path: polygon(0 0, 0 0, 0% 100%, 0 100%); |
clip-pathプロパティのポリゴンの頂点はパーセントで設定され、記述された順番で座標を定義します。
- 0 0 = top left
- 0 0 = top right
- 100% 0 = bottom right
- 0 100% = bottom left
塗りつぶしの方向は、座標を変更することで変更できます。ホバー時にポリゴンを右に広げるには、下記のように記述します。
1 2 3 |
a:hover::before { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); } |
これで完成です。
実際の動作は、下記のデモをご覧ください。
See the Pen
Hover Text Fill Effects with CSS (clip-path) by Katherine Kato (@kathykato)
on CodePen.
このテクニックは非常に有効ですが、clip-pathプロパティのサポートはブラウザによって異なります。
参考: clip-pathのサポート状況
clip-pathを使ったテクニックは、widthまたはheightを使ったテクニックよりも優れた選択肢です。ただし、ブラウザのペイントに影響します。
4. transformを使用したテクニック
最後に紹介するテクニックは、span要素によるマスキングです。別の要素で複製されたコンテンツを使用するため、aria-hidden="true"を使用してアクセシビリティを向上させます。こうすることで、スクリーンリーダーからコンテンツが非表示になり、コンテンツが二度読まれないようになります。
1 |
<a href="#"><span data-content="Link Hover" aria-hidden="true"></span>Link Hover</a> |
span要素のCSSには、左から開始されるトランジションが含まれています。
1 2 3 4 5 6 7 8 |
span { position: absolute; top: 0; left: 0; overflow: hidden; transform: translateX(-100%); transition: transform 275ms ease; } |
次に、span要素を下記のように右にスライドさせます。
実装の仕組み
これを実装するには、translateX()関数に0を定義します。
1 2 3 |
a:hover span { transform: translateX(0); } |
次に、span要素に::before疑似要素を使用して、前に行ったdata-content属性を使用します。X軸に沿って100%移動させ、位置を設定します。
1 2 3 4 5 6 7 8 |
span::before { display: inline-block; content: attr(data-content); color: midnightblue; transform: translateX(100%); transition: transform 275ms ease; text-decoration: underline; } |
最後に、span要素と同様に::before疑似要素の位置もtranslateX(0)に設定します。
1 2 3 |
a:hover span::before { transform: translateX(0); } |
これで完成です。
実際の動作は、下記のデモをご覧ください。
See the Pen
Hover Text Fill Effects with CSS (transform) by Katherine Kato (@kathykato)
on CodePen.
このテクニックは最も多くのブラウザに対応していますが、より多くのHTMLとCSSが必要です。transformプロパティを使用すると再描画が行われないため、60fpsのトランジションが滑らかで、パフォーマンスにも優れています。
まとめ
同じ効果を得るために、4つの異なるテクニックを紹介しました。それぞれに長所と短所があり、ピュアCSSでテキストのカラーをスライドして変更させることは可能です。テキストリンクにインタラクティブ感を少し与える素敵なエフェクトです。
sponsors