3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

下線アニメをbackground-sizeのanimationで実装したらIE11で動かなかったけど切り捨てた

Last updated at Posted at 2021-03-15

はじめに

「元々リンクテキストに下線が引いてあって、マウスホバーするとその下線が左から右へアニメーションする。」

そんなあるある要件を満たすためにいろいろと試してみました、が、悪しからず、完璧なIE11対応はできなかったので諦めました、という残念な記事です。

ぜひ、ナレッジがある方はお知恵を拝借できれば幸いです。

追記(2021/03/16): お知恵を頂き、追記しました。

実際にやってみた

ベースとなるHTMLは以下の通りです。

HTML
<a>リンクテキスト<br>2行目です</a>

まずはscale()で実装

widthを使ったりいろいろ実装方法はあると思いますが、まず私はtransform: scaleX()で実装しました。
transform-originを変えればアニメーションの起点を簡単に真ん中にしたり右端にしたり変えられると考えたからです。

Mark.I(疑似要素で実現)
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行以上になるとそのブロックの下に下線がひかれ、「テキストの下線」ではなくなってしまいます。

複数行にも対応させる

Mark.II(複数行対応版)
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に対応していません。

r_655811_6dC5m.gif

IE11に対応させる

Mark.III(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 追記

この記事を出したところ、賢者から知恵を頂くことができたので、改めてこの問題に向き合いました。
非常に勉強になります。ありがとうございます。

MarkIV(IE11対応&汎用性UP)
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がうまくいきませんでした。謎。
鋭意調査続行中であります。

3
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?