Tailwindcss では class に 「underline」 と書くだけで下線を引いてもらえる便利な機能があります。
けれども、 hover:underline だとパッと瞬間的に下線が引かれてしまい、視覚的に物足りないように思います。
下からスッと線が伸びるようなアニメーションを付けたいけれど、CSS だけでどう実現するかわからない・・・。
そんな悩みを解決します。
underline の定義
Tailwindcss のリファレンスを参照すると、
Tailwindcss の underline = CSS の text-decoration-line: underline;
と同じと書いてある。
これをどうにかして・・・と思ったけれど、CSSでアニメーションって出来るの?
と思い、一旦JavaScriptで下線を引けないか考えてみることにしました。
JavaScript で 下線を引けないか考えてみる
JavaScript で下線を引くには下記の記述で出来た。
document.getElementById('test').style.textDecoration = 'underline';ん、でもこれじゃさっきの CSS と同じだよね?
うーん、もうコンパイルされている underline 自体をアニメーションにするのは無理そう。。。
それならば、始点と終点を指定して、それをアニメーションにするしかないと思った。
しかし、ドキュメントを読んでも、どうにもアニメーションの使い方が分からず
この方法も断念せざるを得なかった。
document.addEventListener('mouseover', function() {
document.querySelector('#test').animate(
{
translate: ['calc(-100% - 1rem)', 0]
},
{
duration: 700,
}
);
});↑ダメだったコード。
どこかから飛んでくる上に、既に線が引かれている。
もしかして、JavaScriptじゃダメ?
もう一度 Tailwindcss で下線を引くアニメーションが出来ないか考えてみる
JavaScript 難しすぎる・・・ということでもう一度 Tailwindcss で考えてみることにしました。
始点: hover される前が left が 0
終点:hover されたら徐々に動いて left が 100
のようになる線を引いてくれるアニメーションということ、これが実現できればOK。
実際、出来ました!
<div id="parent" class="group relative inline-block text-2xl px-1">
test
<span id="child"
class="absolute left-0 bottom-0 h-[2px] w-full
scale-x-0 origin-left
bg-red-500
transition-transform duration-700
group-hover:scale-x-100">
</span>
</div>まとめると、
- relativeで範囲を決めて、absolute で下線が引かれる位置を固定
- left-〇:下線を引く位置(今回は0。指定しないと、文字列の後ろから引かれる)
- scale-x-〇〇:アニメーションを行う下線の位置
始点(hover前)は0、終点(hover後)は100 - origin-〇〇:アニメーション自体をどこから行うか(今回は左位置からやりたいので left )
- transition-transform:アニメーションの指示
- group-hover:class で 「group」が指定してある場所からhoverされているか判定する
(これが無いと下線が引かれない)
①子要素にするものを<span>タグでインライン要素を作る(これ超重要)
②その親要素(上記で言うと<div>タグ)の class を group でグルーピング
③group-hover:(<span>タグだけでなく親要素)で終点まで線を伸ばす
といった流れで下線をアニメーションさせることが出来ました。
アニメーションは分かりづらいと思うので、CSS に書き直して CODE PEN で見られるように作ってみました。
「test」と書いてある箇所にマウスオーバーしてみてください。
See the Pen underline animation by gulf_stream (@Hitomi-Kuge) on CodePen.
CSSに直す上で分かりにくかったのが、group と group-hover:。
いろいろ考えて出した結論が
- group = ただの飾り文字
- group-hover: = <親>:hover <子>
でした(2時間ぐらい悩んだ)
応用例
上部や下部にメニューを置く場合は、<a>タグでhoverさせると視覚的におしゃれな印象のメニューが出来ますよ!
<div class="grid grid-cols-3 divide-x-4 divide-indigo-500 text-center">
<a href="#" id="parent1" class="group relative inline-block text-2xl px-1">
Menu
<span id="child1"
class="absolute left-0 bottom-0 h-[2px] w-full
scale-x-0 origin-left
bg-indigo-500
transition-transform duration-700
group-hover:scale-x-100">
</span>
</a>
<a href="#" id="parent2" class="group relative inline-block text-2xl px-1">
About
<span id="child2"
class="absolute left-0 bottom-0 h-[2px] w-full
scale-x-0 origin-left
bg-indigo-500
transition-transform duration-700
group-hover:scale-x-100">
</span>
</a>
<a href="#" id="parent3" class="group relative inline-block text-2xl px-1">
Contact
<span id="child3"
class="absolute left-0 bottom-0 h-[2px] w-full
scale-x-0 origin-left
bg-indigo-500
transition-transform duration-700
group-hover:scale-x-100">
</span>
</a>
</div>実際に作ってみて
今回は hoverするとTailwindcss や CSS で下線を引かれるアニメーションの作り方の過程をご紹介しました。
Tailwindcss や CSS でここまでちゃんとアニメーションが作れるとは・・・侮れませんね(汗)
機会があれば、JavaScript でも出来る方法がないか考えてみようと思います。
まとめ
・Tailwindcss(CSS)で下線を引くアニメーションを実装する方法
・なぜこのコードが動くのか
・実際のUIでどう使えるか
初心者の方も意外と簡単に出来るので、是非チャレンジしてみてくださいね。

