リンクの先頭にFontAwesomeのアイコンを置いていて、ホバーした瞬間にアイコンまで下線がびよーんと伸びる。私はこれが地味に気になってしまうタチで、パンくずリストの家マークやSNSリンクの矢印を入れるたびに「うーん、アイコンの下の線だけ余計だな」と思っていました。同じ引っかかりを感じているWeb制作者は、けっこう多いんじゃないでしょうか。
アイコンを先頭に付けると「どこへ飛ぶか」「何のリンクか」がひと目で伝わって便利なのですが、テキストと一緒に下線が引かれると、そこだけ間延びした印象になります。
この記事では、FontAwesomeのアイコンには下線をつけず、リンクテキストにだけ下線を出すやり方を、コード付きでまとめます。仕組みまで理解しておくと、他のアイコンやWebフォントでも同じ手が使えるようになります。
FontAwesomeのホバー下線をテキストだけにする方法
私のブログでは、CSSの:before擬似要素でFontAwesomeのアイコンを表示しています。通常は下線なし、テキストにマウスを乗せたら下線が出る、という設定です。まずはよくある書き方から。
.breadcrumb li a{
text-decoration: none;
}
.breadcrumb li a:hover{
text-decoration: underline;
}
.breadcrumb li:first-child a:before{
font-family: FontAwesome;
content: '\f015';
margin-right: 5px;
}
これでも動きはします。ただ、ホバー時の下線が:beforeのアイコンまで届いてしまい、見た目が少しだけカッコ悪くなります。
回避するには、アイコンを出している:before擬似要素に display:inline-block を足すだけです。
.breadcrumb li:first-child a:before{
font-family: FontAwesome;
content: '\f015';
margin-right: 5px;
display: inline-block;
}
たったこれだけで、ホバー時の下線はテキストだけに収まります。
なぜinline-blockで下線が切れるのか
ポイントはtext-decorationの仕組みにあります。MDNによると、text-decorationプロパティ自体は継承されませんが、下線などの装飾は親要素から子のインライン要素へと「伝播」して描画されます。つまり、aに引いた下線は、その中に並ぶインラインの中身(テキストも:beforeのアイコンも)をまとめて貫くように描かれるわけです。
ところが、擬似要素にdisplay:inline-blockを指定すると、その部分は「独立した矩形のボックス」として扱われます。仕様上、インラインブロックの子孫には親の下線が伝播しません。結果、リンクテキスト側の下線だけが残り、アイコンには線が入らなくなる、という理屈です。
逆に言うと、display:inlineのままだとアイコンは同じ行のインラインの一部とみなされるので、下線がつながってしまうんですね。
もうひとつの解:aは下線なし、テキストを要素で包む
もし擬似要素ではなく、アイコンとテキストが別々のタグで並んでいる場合は、考え方を逆にする手もあります。親のaはtext-decoration:noneにしておき、テキストだけをspanなどで包んで、そこに下線を付けるという方法です。
.link a{
text-decoration: none;
}
.link a:hover .label{
text-decoration: underline;
}
HTML側はこんなイメージです。
<a href="#"><i class="fa-solid fa-house"></i><span class="label">ホーム</span></a>
下線の対象を「アイコンを含むaの全体」ではなく「テキストを包んだ要素」に絞る、という発想です。擬似要素を使わない構成ではこちらのほうが素直に効きます。
Font Awesomeの現行バージョンでの注意点
この記事のコードは、アイコンをCSSのcontentで呼び出す旧来の書き方(font-family: FontAwesome)です。Font Awesomeの5系・6系では、<i class=”fa-solid fa-house”></i> のようにi要素で書いて、擬似要素側で表示するのが標準になりました。この場合、下線の伝播が起きるのはi要素なので、アイコンのi要素そのものに display: inline-block を当てるのが手っ取り早い対策になります。
a .fa-house{
display: inline-block;
}
さらに、Font AwesomeをSVG + JS方式で使っている場合は、アイコンが<svg>要素に置き換わります。SVGは置換要素で、そもそも下線の伝播対象になりにくいため、この問題自体が起きないことも多いです。自分の環境がフォント方式かSVG方式か、まずそこを確認しておくと迷いません。
下線が字にかぶるのが気になるなら text-decoration-skip-ink
アイコンの下線とは少し別の話ですが、「下線が文字のgやyの下の部分にかぶってうるさい」と感じることもあります。そんなときはtext-decoration-skip-inkが使えます。
MDNによれば、autoでは下線が文字のはみ出した部分(ディセンダ)を避けて途切れ、noneにすると避けずに一直線で引かれます。日本語などのCJKフォントで避けを強めたいときはallも選べます。2022年以降、主要ブラウザで広く使える標準機能です。今回のアイコン下線の話とあわせて、下線まわりの見え方を整える引き出しとして覚えておくと便利です。
まとめ:ちょっとの工夫で見た目は変わる
細かい下線一本でも、UIの印象はけっこう変わります。アイコンフォントは便利な反面、CSSの装飾しだいで意図しない見た目になることがあるので、仕組みを押さえておくと調整がラクです。
- :beforeでアイコンを出していると、ホバー時の下線がアイコンまで伝播する
- 原因は、親aの下線が中のインライン要素へ伝播して描かれるから
- 擬似要素やi要素に display: inline-block を足すと、その部分は独立したボックスになり下線が伝播しなくなる
- 擬似要素を使わない構成なら、aは下線なしにしてテキストを包んだ要素にだけ下線を付ける手もある
- Font Awesomeのフォント方式かSVG方式かで挙動が変わる点にも注意
この小技、地味ですが効き目は確実です。アイコン付きリンクを使うプロジェクトで、下線が気になったら試してみてください。