hamura.css > issue 22, hamura.css > issue 23 での解決事項を記事に追記しています。(2022/04/27)
本記事の内容を一般化して述べると、フォント画像やフラットデザインのアイコン等の単色画像への画像置換を大々的に行っているウェブページの強制カラーモード対応の実際について、です。ソースコードと併せて読み進めてみてください。
hamura.css は、各ブラウザエンジンとバージョンの実装状況に合せて異なるプロパティと技術を駆使して、同等の表現を実現します。
このプロパティと技術の取捨選択が複雑多岐になる為、この機会にガッツリと文書にまとめておきます。
特に画像置換に強制カラーモード(ハイコントラストモード)が絡むと、使用プロパティと技術の選択がシビアでした。なんとかモノになって本当に良かったです。という hamura.css 開発者用の記録です。
- はじめに
- 使用する技術とプロパティ
- pbLCD.css の絶対配置の図
border-color
にtransparent
を使えないIE6以下用の変更- IE5 の CSS-P とインタラクションの制限
1. はじめに
hamura.css を読み込むことで、PB-100 の LCD を模した画像状のコンテンツ(pbLCD.css)と LCD セグメントを模した画像状のコンテンツ(pbChr.css)を HTML で表現出来ます。
また pbList.css では Web フォントに非対応なブラウザに対して pbChr.css と同じ方法で画像フォントでフォールバック表示します。但し、この時に使用するフォント画像は白抜きのマスク画像です。
これらのマークアップは注意深く設計されている為、ツールチップなどの豊かな表現力を備える pbLCD.css でも多重の <div>
の入れ子のようなマークアップではありません。一般的なセマンティックなマークアップにだいたいなっています。
1.1. コンピュータの入出力内容のマークアップ
先に挙げた『HTML5スタンダード・デザインガイド』にある通り、hamura.css でも PB-100 の画面のマークアップには <pre><samp>
を使っています。
次に示すのは、ターミナル操作と出力のマークアップの例です。
<pre><samp>PS > <kbd>npm start</kbd>
> node local-web-server.js
Listening on port 8022</samp></pre>
1.2. CSS によるテキストの画像置換
CSS を使ったテキストの画像置換はロゴ(ロゴタイプ)などに使われる古くからあるテクニックです。hamura.css では pbLCD.css と pbChr.css のキャラクター表示と、pbList.css のフォント画像によるフォールバックで大々的に使っています。
画像置換とは
画像置換とは HTML 内のテキストを非表示にし、その範囲を背景画像へと置き換える CSS の手法です。最近はあまり使われなくなりましたが、以前は SEO 対策として利用されたテクニックです。
CSS による画像置換では主に、content:url
か background-image
を使います。(この他には特定の状況で mask
を使いました。)
なかでも content:url
には、ハイコントラストモード時や、印刷時に背景画像を印刷しない設定でもコンテンツが欠落しない利点があります。しかしサポートするのは比較的新しめのブラウザになってしまいます。
画像置換のクロスブラウザに関する情報は『【画像スプライト編】Web文書のグレースフルデグラデーションをムキになってやってみる』にあります。この機会に覚えておきましょう。
1.3. テキストだけの情報提供
ブラウザが CSS と画像に非対応の場合、テキストでコンテンツが提供されます。これは hamura.css の定義する HTML が、検索ボットやスクリーンリーダーにテキストと適切な HTML タグでコンテンツを伝えることが出来ることでもあります。
多くのブラウザは画像を無効に出来ます。更に Firefox は 表示 > スタイルシート から スタイルシートを使用しない を選択できる為、これらの状況への対応も頭の隅に入れておきます。
2. 使用する技術とプロパティ
ブラウザ | CSS Generated Content | フォント画像ファイル | pbChr | pbLCD | pbList | |||
---|---|---|---|---|---|---|---|---|
キャラクタ表示 | カーソルの点滅 | キャラクタ表示 | 透過 | ゴースト | マスク画像ファイル | |||
モダンブラウザ(*1) | ◎ | x3.gif, x3.svg, x3.anime.svg(*6) | :after + content:url
| animation gif, CSS Animation(*5, *6) | :after + content:url
| opacity
| :before + content:url
| x3mask.png, x3.anime.svg(*6) |
IE 9 | ◎ | x3.gif, x3.svg(*6) | :after + content:url
| animation gif, DHTML(*6) | :after + content:url
| opacity
| :before + content:url
| x3mask.png, x3.svg(*6) |
IE 8 | 〇(*2) | x3_x10.png, x3_csr.gif | :after + content:url
| animation gif | :after + content:url
| 透過 png | :before + content:url
| x3mask.png |
Opera 9~9.2x | △(*3) | x3.gif | background-image
| animation gif | :after + content:url
| opacity
| :before + content:url
| x3mask.png |
Opera 7.2~8 | △(*3) | x3_x10.png, x3_csr.gif | background-image
| animation gif | :after + content:url
| 透過 png | :before + content:url
| x3mask.png |
Opera 7~7.1 | ×(*4) | x3_x10.png | background-image
| DHTML(*7) | background-image
| 透過 png(*11) | DHTML | x3mask.png |
Gecko 0.9~1.9.0 | ×(*4) | x3.gif | background-image
| animation gif | background-image
| -moz-opacity
| DHTML | x3mask.png, x3mask.gecko0.9.1.png(*8) |
Gecko ~0.8.1 | ×(*4) | x3_x10.png, x3_csr.gif | background-image
| animation gif | background-image
| 透過 png(*9, *11) | DHTML | x3mask.png |
IE 7 | - | x3_x10.png, x3_csr.gif | background-image
| animation gif | background-image
| 透過 png | DHTML | x3mask.png |
IE 5~6 | - | x3_x10_8.png, x3_csr.gif | background-image
| animation gif | background-image
| 疑似透過 png(*10), -ms-filter
| DHTML | x3mask.png |
MacIE 5 | - | 未実装 |
- モダンブラウザは IE10 以上、Firefox 3.5(3.1 beta)以上、Opera 9.5以上、Safari, Chrome
- IE8 には CSS Generated Content に
-ms-filter
を使えない制限がある。IE8 の-ms-filter
はハイコントラストモード時のツールチップの尻尾に使っています。 - CSS Generated Content を CSS-P する場合、ブロック要素でないと意図した動作をしない。この為に pbChr.css では画像置換に
background-image
を使う。 - CSS Generated Content をサポートするが CSS-P することが出来ない。この為に全ての画像置換に
background-image
を使う。 - EdgeHTML は、高圧縮されたアニメーション GIF でリピートしない為、カーソルの点滅に CSS アニメーションを使う。
- 「モダンブラウザと IE9 の強制カラーモード(ハイコントラストモード)」にて詳しく。
- Opera 7~7.1x は背景画像のモーション gif に非対応の為、カーソルの点滅は javascript で行う。
- Gecko 0.9.1, このバージョンだけ透過 png の透明色が黒くなる為、透過 gif に切り替えている。この手法でも pbLCD.css のコンディション部分の問題が解決していない。
Gecko 0.6~0.8.1,
-moz-opacity
を指定する要素が Viewport に入るとブラウザがクラッシュする。- IE6以下は、透過 png に非対応の為、疑似的な透過 png を使う。キャラクターの組み合わせによっては背面にあるキャラクターが隠れてしまう。javascript で
-ms-filter
の可否を判定して正しい透過表示に切り替える。この機能は以前のバージョン(pbDisplay)から備えている。 - Opera 7~7.1x, Gecko ~0.8.1, 透過キャラクタの画像スプライトの
background-position
の指定は javascript で行っている。これらのブラウザがbackground-position-y
を非サポートの為、各キャラクタの透過度ごとにbackground-position
を指定すると CSS が巨大になってしまうためです。
2.1. 強制カラーモード(ハイコントラストモード)
強制カラーモードと画像置換は大変に相性が悪いですが、様々な手法を駆使して相性問題を解消しています。
2.1.1. Edge 72~, Chrome 89~, Firefox 89~ の強制カラーモード
forced-colors
メディア特性をサポートするこれらのブラウザの pbChr.css と、pbList.css の画像フォールバックでは mask
を使ってボーダーをフォントの形で切り抜いています。CSS の上書きはやや複雑になりますが、通常のカラーモードの x3.gif をそのまま mask-image
に使える為、別の画像のダウンロードが不要な利点があります。
2.1.2. IE10~, Edge ~18 の強制カラーモード
-ms-high-contrast
メディア特性をサポートするこれらのブラウザの pbChr.css と、pbList.css の画像フォールバックでは x3.anime.svg でキャラクタを表示します。カーソルの点滅は SVG ファイル内に記述した CSS Animation で行います。
2.1.3. IE9, Gecko 1.9.1~88, Goanna の強制カラーモード
先のメディア特性をサポートしないブラウザの pbChr.css と、pbList.css の画像フォールバックでは x3.svg でキャラクタを表示します。SVG には <path style="fill:WindowText" />
のスタイルが設定されていて、閲覧者の選択したテキストカラーが塗り(fill
)に反映されます。カーソルの点滅は javascript で行っています。
2.1.4. IE8 の強制カラーモード
dark-on-light(黒いテキストカラーに白地など、テキストカラーの方が暗い), light-on-dark(白いテキストカラーに黒地など、テキストカラーの方が明るい) を Javascript で検出し、light-on-dark の場合は outline
を使って色を反転(invert
)させてカラー設定に馴染ませています。
テキストカラーと背景色が黒と白の場合には意図した描画を得られますが、これ以外の色の場合、必ずしも良好な描画ではありません。
light-on-dark, dark-on-light は hamura.css が使用するクロスブラウザライブラリが独自に定義したものです。詳しくは『ユーザー設定の調査』を参照します。
2.2. Gecko の奇妙な挙動への対処
Gecko 1.1 には
-moz-opacity
が設定されている<b>
要素が<a>
要素の下に居ないと非表示になってしまう問題がありました。解決していますが、発生条件と回避条件を特定できてはいません。Gecko 1.1.1 で現象を確認しています。Gecko 1.0(Netscape Navigator 7.0), Gecko 1.2 では問題は発生していません。
Gecko 0.6~1.3 には CSS-P している要素が親要素ボックスをはみ出すと描画されない問題がある。この問題を迂回するためにレイアウトを変更している。(後述)
この変更によってフォーカス
とレンジの描画が他のブラウザに劣ります。(後述)
3. pbLCD.css の絶対配置の図
pbLCD.css は200x70ピクセルの画像状のコンテンツをマークアップで記述することが出来ます。CSS-P と画像置換で HTML を PB-100 の LCD 風に置換しています。
3.1 Gecko ~1.3のペイントの問題
さて、Gecko ~1.3 には CSS-P している要素が親要素を上下にはみ出す部分について、onload
時に当該要素が ViewPort 外の場合にペイントされない問題がありました。
マウスで周辺を触ると描画される。さらにスクロールで ViewPort 外に出た後に再び ViewPort に入ると描画されていない場合もあります。
そこで2種類の異なる座標系の CSS を用意しました。
3.2. 多くのブラウザの座標系
<pre>
とこの直下の <samp>
要素は、200x70ピクセルのサイズです。液晶画面全体を表示しているのは <samp>
です。
LCD セグメントに対応する <b>
にツールチップやレンジを関連付ける <a>
要素は、<b>
より一回り大きいサイズです。この為、ツールチップは <a>
要素の上下にはみ出す位置に出現します。
マウスホバーやタブフォーカスといった閲覧者のインタラクションで、<a>
に背景色が付きます。これは <b>
より一回り大きいサイズになります。
3.3. バグを回避する為の座標系
<pre>
, <samp>
, <a>
要素の高さを、上下のマージン30pxづつを加えた130pxとします。液晶画面全体を表示しているのは <small>
です。
ツールチップが親要素をはみ出すことが無くなった為、ペイントが欠落する問題は解消されました。
しかしこの変更によって、フォーカス時の塗りとレンジが他のブラウザに劣るものになってしまっています。
3.4. Gecko 1.3.1以下のフォーカスとレンジの問題
レンジの下線が LCD セグメント毎に切れる問題は hamura.css > issue 22 で解決しました。(2022/04/27)
Gecko 1.3ではフォーカス時に現れる破線は対象の LCD セグメントを囲む形にはなりません。
レンジの下線は、LCD セグメント毎に切れてしまっています。(解決済)
4. border-color
に transparent
を使えないIE6以下用の変更
hamura.css では、border
を駆使して三角形を描画するテクニックをツールチップの尻尾で使っています。このテクニックは広範なブラウザで使えて便利なのですが、IE6 以下では border-color
に transparent
を指定できない制限があります。
hamura.css はライブラリとして公開されている為、ウェブページの背景色は未定です。この為に transparent
を使えないのは具合が悪いのです。
この制限の為、IE6 以下ではツールチップの尻尾は常に LCD の青色のベゼルの上にあるように変更しています。これならばウェブページの背景色は問題になりません。
5. IE5 の CSS-P とインタラクションの制限
この問題はツールチップのタグ構造を変更して hamura.css > issue 22 で解決しました。(2022/04/26)
未解決の問題として、IE5 のツールチップのインタラクションでの CSS-P が正しくない問題があります。
この他にも、IE6 ないし IE5.5 以下には、CSS-P の問題に遭遇しています。随分昔に取り組んだことなので失念しています。