はじめに
「元々リンクテキストに下線が引いてあって、マウスホバーするとその下線が左から右へアニメーションする。」
そんなあるある要件を満たすためにいろいろと試してみました、が、悪しからず、完璧なIE11対応はできなかったので諦めました、という残念な記事です。
ぜひ、ナレッジがある方はお知恵を拝借できれば幸いです。
追記(2021/03/16): お知恵を頂き、追記しました。
実際にやってみた
ベースとなるHTMLは以下の通りです。
<a>リンクテキスト<br>2行目です</a>
まずはscale()
で実装
widthを使ったりいろいろ実装方法はあると思いますが、まず私はtransform: scaleX()
で実装しました。
transform-origin
を変えればアニメーションの起点を簡単に真ん中にしたり右端にしたり変えられると考えたからです。
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: 0;
left: 0;
content: "";
width: 100%;
height: 1px;
background: #000;
transform: scaleX(1);
transform-origin: left top;
}
a:hover::after {
animation: leftToRightUnderline 0.3s;
}
@keyframes leftToRightUnderline {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
See the Pen LeftToRight Mark.1 by heeroo-ymsw (@heeroo-ymsw) on CodePen.
疑似要素after
で高さ1pxの線を作ってテキストの下に配置し、左端を起点にanimationで要素を拡大させています。
今回はもともと下線が引いてあるので、マウスホバーを外したときのアニメーションはありません。
しかし、このコードには問題があり、テキストが2行以上になるとそのブロックの下に下線がひかれ、「テキストの下線」ではなくなってしまいます。
複数行にも対応させる
a {
background: linear-gradient(#000, #000) 0 bottom/100% 1px no-repeat;
text-decoration: none;
}
a:hover {
animation: leftToRightUnderline 0.3s;
}
@keyframes leftToRightUnderline {
from {
background-size: 0% 1px;
}
to {
background-size: 100% 1px;
}
}
See the Pen LeftToRight Mark.2 by heeroo-ymsw (@heeroo-ymsw) on CodePen.
疑似要素を用いるよりもスッキリした印象です。
linear-gradient()
とbackground-size
で幅100%/高さ1pxの下線を書いておき、background-size
をアニメーションさせることで実現しています。
しかし、こちらにも問題点が。
IE11はbackground-size
のtransition/animationに対応していません。
…
IE11に対応させる
a {
background: linear-gradient(#000, #000) 0 bottom/100% 1px no-repeat;
text-decoration: none;
}
a:hover {
animation: leftToRightUnderline 0.3s;
}
@keyframes leftToRightUnderline {
from {
background-position: -190px bottom;
}
to {
background-position: 0 bottom;
}
}
See the Pen LeftToRight Mark.3 by heeroo-ymsw (@heeroo-ymsw) on CodePen.
background-position
で左にずらしとくパターンです。
ただし、これも残念ながら万能策ではありません。
むしろ、問題が増えました。
- 下線を適応させたい要素に応じて、ずらし具合(例だと-190pxの部分)を調整しなくてはいけない
- ずらし具合の調整が地味に面倒
- アニメーション方向が変わった場合などの汎用性が低い
そのうちコーダーは考えるのをやめた
今回は以下の言い訳とともにIE11を切り捨て、background-size
で実装しました。
- 調べたらpolyfillもあったが、案件でそれを検証している時間がない
-
background-position
を使っても、実装当初はリンクが増える、もしくはテキストが変更になる可能性が大いにあり、その度にズレを調整していられない- ついでにレスポンシブ対応&PCサイズのときはリキッド対応の必要がある
そして、賢者が現れる
2021/03/16 追記
この記事を出したところ、賢者から知恵を頂くことができたので、改めてこの問題に向き合いました。
非常に勉強になります。ありがとうございます。
a {
background: linear-gradient(to right, #000 50%, transparent 50%) 0 bottom/200% 1px no-repeat;
text-decoration: none;
}
a:hover {
animation: leftToRightUnderline 0.3s;
}
@keyframes leftToRightUnderline {
from {
background-position: 100% bottom;
}
to {
background-position: 0% bottom;
}
}
See the Pen LeftToRight Mark.4 by heeroo-ymsw (@heeroo-ymsw) on CodePen.
端的に言えば、linear-gradient()
で横方向のグラデーションを作成し、それをbackground-positionで左右に動かすというものになります。
■□
←こんな感じのグラデーションを作って、横を2倍に引き伸ばして、background-position
は左端に寄せておいて下線を常時表示します。
アニメーション時は、background-position
を右端に寄せて左端へ動かすことで左から右へ下線が動くように見えます。なるほどすごい!
しかしながら、はたまた問題が。
IE11だとkeyframesでアニメーションしない……
transitionだと動くのですが、下線を元々表示したい関係でkeyframesを使っており、これが動きませんでした。
書き方が悪いのか、IE11の仕様なのか…現在調査中です。
まとめ
テキストの下線アニメーションの実装を行い、現段階では、background-size
のanimation / transitionでの実装が最適解かと感じました。
background-position
の代替案が出来たと思ったのですが、keyframesによるanimationがうまくいきませんでした。謎。
鋭意調査続行中であります。