outline-color: invert

端的にいってFirefoxのoutlineはわかりにくいです。1pxなので目立たないというのもありますが、そもそも視認できない状況がいくつかあります。

currentColor

例えば、outlineを表示する要素の前景色が、その要素の外側の領域の色と同じ場合、ユーザーはoutlineを視認できません。Geckoのoutline-colorのデフォルトがcurrentColor相当になっているためです。具体的には、「白背景のページ」に「灰色背景で白文字のリンク」がある場合を考えてみましょう。outlineは要素の外側に描画されるので、白背景の上に描画されます。outlineの色は要素の前景色、白です。つまり、白背景の上に白いoutlineが描画されるので視認できません(OS Xでは違うかもしれません)。

Firefoxで「白背景のページ」にある「灰色背景で白文字のリンク」にフォーカスを合わせた場合(a)。outlineは視認できない。スクリーンショットArs Technicaのもの。

一応、例もおいておきます。

例:outlineを表示する要素の前景色が、その要素の外側の領域の色と同じ場合

invert

だいぶ昔のGeckoはinvert(周囲の色を反転させる)を初期値としていましたが、cairoに移行する段階でinvertをやめ、currentColor相当になりました。当時のcairoではinvert相当のことができなかったためです。CSS Basic User Interface Module Level 3 (CSS3 UI)のinvertにも次のようにあります。

Conformant UAs may ignore the ‘invert’ value on platforms that do not support color inversion of the pixels on the screen. If the UA does not support the ‘invert’ value then the initial value of the ‘outline-color’ property is the ‘currentColor’ [CSS3COLOR] keyword.

さて、この前Compositing and Blending Level 1の勧告候補をつらつらと眺めていたら、differenceにつぎのように書かれていることに気が付きました。

Painting with white inverts the backdrop color; painting with black produces no change.

GeckoCanvas 2D Contextなどですでdifferenceをにサポートしています。ということは、今のGeckoではinvertを再実装できる余地があるということです。

ということで実装してみたのが以下です。

invertを実装したFirefoxで「白背景のページ」にある「灰色背景で白文字のリンク」にフォーカスを合わせた場合(b)。outlineは視認できる。スクリーンショットArs Technicaのもの。

Differenceの問題

ただdifferenceを使ったinvertの実装にも問題があります。それは50%灰色は反転しても50%灰色のままなので、視認できないという問題です。differenceは次のような処理を行っています。

画面上の色 = | 背景色 − 入力色 |

なので入力色(のRGB値)が背景色(のRGB値)の2倍の関係になっていると、画面上の色は背景色のままになります。

画面上の色 = | 背景色 − (2 × 背景色) | = | − 背景色 | = 背景色

differenceを使って色を反転させるには白(#FFFFFF)を入力色として使うので、背景が50%灰色(#808080)の場合には反転しても色が変わりません。この問題を解決するにはdifferenceをあきらめるしかありません。

あるいは、outline-style: autoとして、常に視認できるoutlineを実装することでしょうか。

関連情報