Topics

Google Chromeで:hover時のアンダーラインが出ない場合の対応

何だこれ?という奇妙なバグ

今作っている最中のサイトの仕事で、「ページ下部ののリンクはマウスオーバーでアンダーラインを表示させてください。」というご依頼をいただき、対応しました。
まあ、チョロい直しです。

すぐに修正して、各ブラウザでチェックしたのですが、なぜかChromeだけアンダーラインが表示されず、「あれ?」と思いました。
サイトのヘッダーやフッターなど共通部分はHTML、CSSともにお客さまから支給されたものなので、たいていこういう時は、問題の原因の調査と切り分けのために

  • !importantを書いてみる。
  • そのスタイルの指定をCSSの後ろの方に移動してみる。
  • ブラウザのキャッシュをクリアする。
  • HTML側にスタイルを書いてみる。

とかやってみるんです。でもおかしいんです。ダメなんです。

先に調べておけばよかったんですけど、これChromeのバグみたいでした。しかも不思議とaタグにtext-decoration:underline;を指定した場合はアンダーラインは表示され、aには指定せずに、a:hoverに指定したときに発症するバグのようでした。

どういう条件で発症するか?

調べた結果わかった対応方法は、「a:hoverにpadding-bottom:1px;を適用する。」というものでした。
そして、確かにこれで直りました。

なのですが、この方法ですと、ハックするか、スクリプト等でChromeだけに適用させるか制御しない限り、他のブラウザでも1pxの影響が出てしまいます。見た目的に問題が起こりにくいサイズなので、多くの場合は問題ないと思いますが、ボーダーや背景などとの組み合わせがある場合はちょっと問題があるかもしれないと思い、ちょっと現象を調べてみました。

  1. CSS側のサイズ指定ではなく、ブラウザで10px以下のサイズでレンダリングされたときに発症する。
  2. したがってfont-size:.8emとか80%とかの指定をした場合でもレンダリングサイズが10px以下になれば発症する。
  3. 同様にブラウザ側のズームが等倍(100%/デフォルト)で表示していた時に発症していても、拡大すれば下線は表示される(直る)。
  4. 逆に発症していなくてもブラウザ側のズームを縮小して文字が10px以下になれば発症する(なんか、これは別のバグもついてくる)。
  5. aがブロックの時は発症しない。

ということで、CSSの書き方を問わず、表示されるときに10pxを切ると発症するみたいなのです。なので、ブラウザのズーム表示を縮小した場合は、100%以上で表示していた場合に発症しなかった部分でも対応していない部分は発症することになります。

対応方法

いくつか試行錯誤する中で、次の対応方法で問題なさそうな気がします。

A.aの下方向のパディング(padding-bottom)を1px以上取る。(既出)
B.displayプロパティをblockまたはinline-blockにする。
C.10.5px以上のサイズにする。(10pxよりも大きなサイズでレンダリングされる指定を行う)。

Cの場合は10pxで設定した場合とあまり文字の大きさは変わりません。気になるようでしたらletter-spacingと組み合わせてください。ですが、これも若干とはいえ文字の大きさは変わりますので、妥当な方法とは言い切れないです。むしろデザインに影響がないのであれば、Aの方がいいと思います。

なのですが、このバグ自体、あまり大騒ぎするほどのものではないです。ブラウザ側のズームが100%表示でユーザーが設定した文字サイズがデフォルトであった場合のことだけを考えるのであれば、サイト全体ではなく局所的な対応くらいでいいと思います。また、気にならなかったら何も対応するほどのものでもないかもしれません。

で、今回はBのinline-blockの方を採用しました。これが一番いいかと思います。

デザインに応じていずれかの方法を使い分ければいいでしょう。

この設定で発症

font-sizeは10pxという絶対値のみではなく、em、%等といった相対サイズを指定した場合でも、ブラウザ側で10px以下でレンダリングされる場合に発症するようです。

ul.linkList li{font-size:10px;}
ul.linkList li a{color:#666;}
ul.linkList li a:hover{color:#f00; text-decoration:underline;}

対応方法

デザインやマークアップの条件等に合わせいずれかの方法で対応します。

下方向のpaddingを1px以上取る

ul.linkList li{font-size:10px;}
ul.linkList li a{color:#666; padding-bottom:1px;}
ul.linkList li a:hover{color:#f00; text-decoration:underline;}

aをblockまたはinline-blockにする。

ul.linkList li{font-size:10px;}
ul.linkList li a{color:#666; display:inline-block;}
ul.linkList li a:hover{color:#f00; text-decoration:underline;}

ちょっとだけ文字を大きくする。

文字間隔気になる場合はletter-spacingで微調整する。

ul.linkList li{font-size:10.5px; letter-spacing:-0.04em;}
ul.linkList li a{color:#666;}
ul.linkList li a:hover{color:#f00; text-decoration:underline;}

ですが

そんな神経質に対応するほどのことでもないと思います。

それと、ちなみにChromeの設定にある「最少フォントサイズ」というのとは関連性はなさそうです。