Home > XUL Apps > Text Shadow

Text Shadow テキストシャドウ Ver.0.3.2008042901 for Mozilla Firefox

An English version of this page is also available.

宣伝1。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

宣伝2。Firefox Hacks Rebooted発売中。本書の1/3を使って、再起動不要なアドオンの作り方のテクニックや非同期処理の効率のいい書き方などを解説しています。既刊のFirefox 3 Hacks拡張機能開発チュートリアルと併せてどうぞ。

Firefox Hacks Rebooted ―Mozillaテクノロジ徹底活用テクニック
浅井 智也 池田 譲治 小山田 昌史 五味渕 大賀 下田 洋志 寺田 真 松澤 太郎
オライリージャパン

What's this? これは何?

CSS2/CSS3のtext-shadowを表示できるようにする拡張機能です。このページやCSS3.infoのページのようにtext-shadowを使ったページで、影付きの文字が表示されるようになります。 (表示例1) (表示例2)

Download ダウンロード

不具合に遭遇した場合は、まずよくある質問をご覧下さい。それでも解決方法が見つからない場合の障害報告はGitHubのイシュートラッカーにお願いします。

Mechanism 動作原理

基本的な影の付け方

この拡張機能では、以下の手順によって「ぼかした影」を擬似的に表現しています。

(図:一つ目の影が left: -1px; top: 1px; opacity: 0.1; の状態でベーステキストの下に重なっている) まず、影を付けたい元テキスト(以下、ベーステキスト)と同じ内容のテキストを、半透明にして、ベーステキストの下に少しずらして置きます

(図:二つ目の影が left: 0px; top: 1px; opacity: 0.1; の状態でベーステキストの下に重なっている) 次に、もう少しだけ横にずらしてまた半透明のテキストを置きます。

(図:三つ目の影が left: 1px; top: 1px; opacity: 0.1; の状態でベーステキストの下に重なっている) さらにまた少し横にずらして、半透明のテキストを置きます。

(図:四つ目から六つ目までの影がベーステキストの下に重なっている) 同様にして、下方向にずらした次の「行」にも半透明のテキストを置きます。

(図:七つ目から九つ目までの影がベーステキストの下に重なっている) このようにして半透明のテキストをずらしながら重ねていくことで、あたかもぼかしフィルタをかけたような効果を得る事ができます。

インライン要素への影の付け方

上記の方法はブロック要素全体に対しては簡単に実行できますが、インライン要素に対しては使えません。インライン要素を絶対配置しようとすると強制的にdisplay: block;が指定されたのと同じ状態になり、先行するテキストや後続するテキストの配置がおかしくなってしまうからです。そこでこの拡張機能では、以下の手順によって「インライン要素と同じ位置に影付きのテキストを表示する」処理を実現しています。

(図:テキストが後続しているインライン要素のインラインボックスを図示したもの。このインライン要素にtext-shadow: 2px 2px 2px gray;の効果を適用する。) ここでは例として、段落の先頭にありテキストノードが後続しているem要素を想定してみましょう。

(図:絶対配置されたspan要素が元のテキストと同じ座標に表示されている。) まず、二つの新しいspan要素を生成し、em要素の内容テキストをそれぞれの中にコピーします(em要素の中に2つのspan要素が含まれ、直接の子にはテキストがないという状態にします)。この状態で、em要素にposition: relative;を適用し、span要素の一つはvisibility: hidden;で非表示に、もう一つはposition: absolute;で絶対配置にします。この時の要素の絶対配置の基準座標は直近の包含ブロックになりますが、ここではposition: relative;が適用されているため、em要素が包含ブロックになります。結果として、元テキストが合った位置と同じ座標に、絶対配置されたspan要素が表示されることになります。この絶対配置されたspan要素が、前述の「ベーステキスト」となります。

(図:ベーステキストの幅とインデントが調整された様子。) ベーステキストはdisplay: block;が適用されたのと同じ状態になっています。ここで、ベーステキストのspan要素の幅を、em要素が含まれているブロック要素の内容幅に合わせます。また、text-indentを使って、行頭の位置も元テキストと同じだけずらします。

(図:ベーステキストが元のテキストと完全に重なった様子。) 仕上げにlefttopを調整して、ベーステキストを元テキストの上に重ねます。こうして、「絶対配置されていながら元のインラインボックスと完全に同じ位置にあるブロックボックス」が作り出されました。後は、前述の手法で影のテキストを重ねれば、インライン要素の影付き表示は完了です。

右寄せ・中央寄せのテキストに対する影付け

左寄せのテキストは上記の手順でほぼ完全に対応できます。しかし、text-alignで中央寄せや右寄せになったテキストだと、最後の行がズレてしまうという問題が残ります。

(図:ブロックの中に、中央寄せのテキストがある。影付け対象のインライン要素は最終行の途中で終わっていて、残りは後続のテキスト。) 例として、このようなテキストを想定してみましょう。

(図:ブロック化されたベーステキストの最終行だけが、元のテキストより右にズレている。) 前項の手順で「絶対配置のブロック」にしたベーステキストは、元のテキストと比べた時に、最終行が右にズレています。本来であればこのインライン要素の最終行は、後続するテキストによって左に追いやられていなければならないのに、その後続するテキストがないため、最終行が右側に寄ってきている(中央寄せの中央に近づこうとしている)というわけです。

(図:元テキストと同じ配置の非表示のspan要素の末尾と、ベーステキストの末尾に、ダミーの空要素が挿入された様子。) ここで使うのが、ダミーの空要素です。元テキストと同じ配置の(visibility: hidden;の)span要素の末尾と、ブロック化されたspan要素の末尾に、それぞれ幅ゼロの空要素を挿入します。これらの要素の画面上におけるXの値を比較すれば、ベーステキストの最終行が本来あるべき位置から何ピクセルズレてしまっているのかが分かります。

(図:) あとは話は簡単で、ベーステキストの末尾に挿入した空要素のパディングなり幅なりを調整して、ベーステキストの最終行の文字を本来あるべき位置まで左に押し出してやればよいわけです。この時の計算には包含ブロックの位置と内容幅、そして元テキストの末尾に挿入した空要素の位置を使います。

なお、右寄せのテキストならこれで問題ないのですが、中央寄せの場合、こうして幅を広げたベーステキスト末尾の空要素は、ベーステキストの最終行を左に押し出すと同時に自分自身も右の方に押し出されていくので、上記の計算だけだとやはり最終行の位置がずれてしまいます。この拡張機能では、このあとベーステキストの空要素の幅を減らしたり増やしたりして調整して、中央寄せでも正しい位置にベーステキストの末尾がくるようにしています。

XBLの使用

この拡張機能では実際には、XBLを使って、影やダミー要素などの「本来は存在しなかった要素」を匿名内容として保持するようにしています。また、ベーステキストはXBLの<children/>要素を使って、本来の要素の子であるテキストノードをベーステキストの位置に挿入しています。これにより、

  • 文字を選択しても、影として挿入したテキストは選択されない
  • コピー&ペーストしても、影として挿入したテキストはコピーされない

という振る舞いを実現しています。

History 更新履歴

0.3.2008042901
  • Firefox 3 beta5で動作するようにした
0.3.2008031101
  • ステータスバー上のボタンから有効・無効を簡単に切り替えられるようにした
0.2.2007091601
  • CSSのセレクタをXPathに変換する処理の間違いを修正
0.2.2007090301
  • CSSのセレクタの詳細度の計算方法を間違えていたのを修正
0.2.2007081302
  • 複数の影を描画できなくなっていたのを修正
0.2.2007081301
  • button以外のフォームコントロール系要素の中のテキストには影を付けないようにした
  • 右寄せや中寄せの影付きテキストを表示する時にFirefox 3が固まる問題を修正
  • Firefox 3でbutton要素の内容の影を正しく表示できない問題を修正
0.2.2007081001
  • 名前空間接頭辞付きのセレクタに対応
  • リサイズ時の再描画やスタイルシート無効化時の処理について改善
  • :first-letter疑似要素の代わりに生成した要素に、:first-letterへのスタイル指定を再設定するようにした
  • span要素にスタイル指定があるサイトで影付きテキストの文字の大きさなどが変わってしまう問題を修正
  • 編集状態のドキュメントに対しての処理が行われてしまうことがあったのを修正
  • 影の色を取得する際に無関係な文字列を拾ってしまうことがあったのを修正
0.2.2007080703
  • 編集状態のドキュメントに対しては処理を行わないようにした
  • 再描画の度に影が濃くなるようになってしまっていたのを修正
  • スタイルシートを無効にした時に、同時に影も消すようにした
0.2.2007080702
  • :hover, :focus, :activeの3つのダイナミック疑似クラスに簡易的に対応
  • よりSafariに近い表示になるように調整
0.2.2007080701
  • 一部の環境で初期化に失敗する問題を修正
0.2.2007080602
  • userContent.cssの中に書かれた指定も解釈するようにした
  • userContent.cssの中に書かれた色指定なしの影について、自動で影の色を調整するようにした
  • 太字の影付きテキストが折り返されてしまうようになってしまっていたのを修正
  • 設定の変更が反映されていなかったのを修正
0.2.2007080601
  • 右寄せ・中寄せのブロック要素の最後の行に跨る影付きテキストが右寄せ・中寄せにならない問題を修正
0.2.2007080402
  • インデントで表示が崩れる問題を修正
0.2.2007080401
  • 中央寄せの文・右寄せの文の最後の行に跨って一回だけ改行されている影付きテキストの表示を改善(複数回改行されている場合はまだ正しく表示できない)
0.2.2007080302
  • 左寄せ以外のブロックに影を付ける時に表示が崩れていたのを修正したつもり
0.2.2007080301
  • 太字と影を同時に指定されたテキストの表示がおかしくなることがあったのを修正
0.2.2007080102
  • JavaScriptの実行が禁止されているサイトで影を表示できなくなっていたのを修正
  • 詳細度の計算間違いを修正
  • ウィンドウの高さだけが変わった時は影を再描画しないようにした
0.2.2007080101
  • コピー&ペーストで余計な文字列やタグが出ないようにした
  • スタイル指定の優先度を計算するようにした
  • 複数の疑似クラスの組み合わせに対応
  • ページの読み込みがキャンセルされた時にまで再描画が行われていたのを修正
  • テーブルセル内の影の表示がずれる問題を修正
  • 要素の中に多数のテキストノードがある時に固まったようになってしまっていたのを修正
0.1.2007073101
  • 内部処理を最適化し、処理速度を若干向上した
  • 「~」間接隣接結合子、CSS3の属性セレクタの未実装分、:not()疑似クラスに対応した
  • @importルールに対応
  • 影の位置やボカシの指定について、画面解像度を72dpiとみなして絶対単位を解釈するようにした
  • 疑似クラスや疑似要素の生成を禁止する隠し設定を追加(extensions.textshadow.silhouettePseudElementsAndClasses)
0.1.2007073001
  • :linkと:visitedの対応を改善
  • 一度に複数個の影を描画するようにした
  • text-shadowにnoneや透明な影、不可視の影が指定された場合、要素ノードの内容を完全に元に戻すようにした
  • @mediaルールに対する実装が欠落していたのを修正
  • 再描画の順番がページの上方からではなくノードの登場順になっていたのを修正
  • float化されたボックスの位置ズレを修正
0.1.2007072903
  • 一部の疑似要素セレクタ(:first-letter, :first-line)と一部の疑似クラスセレクタ(:first-child, :last-child, :first-of-type, :last-of-type, :only-child, only-of-type, :empty, :link, :visited, :root)に対応した
0.1.2007072902
  • Firefox 3に対応
  • 影の表示をSafariのレンダリング結果に近づけるようにした
  • ウィンドウをリサイズした時に自動的に影を再描画するようにした
  • 折り返された文字列の表示がおかしくなる事があったのを修正
0.1.2007072901
  • 長いインライン要素が折り返された時に表示がおかしくなる問題を修正
  • スラドなどで使われているSafari用ハックを無視するようにした
  • 分割ブラウザと連携できるようにした
0.1.2007072802
  • 2つの影を表示できるようにした(Firefoxの仕様上の問題で、3つ以上は表示できない)
  • line-heightがnormalの時に影を付けた要素の表示位置が大きくずれる事があったのを修正
  • ぼかし半径が0の影を正しく表示できていなかったのを修正
0.1.2007072801
  • @mediaルールに対応
  • ベーステキストの位置ズレについて改善
  • 影にはフォーカスしないようにした
0.1.2007072800
  • style属性でのスタイル指定に対応
  • text-indentで表示がずれる問題を修正
0.1.0 (2007.7.28)
  • 公開
Last modified:2015/11/07 17:33:45