IE7でのインライン要素の背景指定は変?(アイコン追加にて) ではIE8では?
- Category: Diary | Knowledge | Web Design
当サイトでは、外部サイトへのリンクを用いる場合、CSSで”インライン要素であるaタグの右側に適度な余白(padding-right:)を作り、アイコンを背景画像として右に配置”しています。これは割とメジャーなテクニックかと思われます。

しかし、なぜ今まで気づかなかったのか、Internet Explorer 7(以下「IE7」)ではインラインの背景をブロック要素のように取るため、以下の赤線のようなボックス状の中に画像を配置するようです。

ということは、実際のIE7での見た目は下の画像のようになり、アイコンは欠けたり、見えなくなったりします。

padding-rightで与えた右の余白はしっかりと2行目に入ってるのですが、background-position: right center;で”X軸:右、Y軸:中央”として与えた背景は”2行合計のX軸:右、Y軸:中央”にされてしまっています。
2行合計で計算されていますから、background-position: left top;で”X軸:左、Y軸:上”にすると、今度は1行目のaタグ冒頭に余白ができ、1行目の全体頭に(aタグではない部分)にアイコンが来るようです。上の画像だと”UI”と書かれてるあたりにアイコンがカブります。
IE8ではこのテクニックは通用します。しかしながら、IE8を意識し、モダンブラウザをメインターゲットに捉え、過去のブラウザと決別するのであれば、CSS3で実現すればいいという考えも浮かびます。そのためのコードは以下の通りで、当サイトもこの形式に変更してみました。
アイコンを追加したい部分のaタグに向けて……
content: url(‘icon_outside.png’);
}
div.post p a[href^='http://www.eight-bits.net']:after {
content: url(‘empty.png’);
}
このa[href^='http']がCSS3によって実装されているセレクタを利用した部分で、1つ目の部分の意味は”href属性の内容がhttpで始まっているaタグだったら”ということになり、続く:afterは”その後にどうする”ということになります。また、content: urlの中で、icon_outside.pngという”外部リンク用アイコンの画像”を指定することにより、アイコンの表示が可能になります。
2つ目の指定は、そうじゃなかった場合に1つ目で指定したものを打ち消すために仕方なく書いたコードです。本来なら「~でないなら」的なコードを書きたかったのですが、ざっと探した限りでは見つからず、またcontent: none;のような「そうだった場合に、”消す”」的なものは、一部ブラウザで動作しなかったため断念。意味としては”href属性の内容がhttp://www.eight-bits.net(つまり自分のドメイン)で始まる場合は、その後にempty.pngという1*1pxの判別しづらい透明画像を追加する”となります。
以上のコードを要約すると、「httpで開始する外部リンクは後方にアイコンを付加、そうでないときは何もしない、しかし、意図しない自分のドメインへの絶対パスがリンクに設定されている場合は、代わりの判別しづらい画像を後方に追加する。」ということになります。
Windows用のIE8、Firefox3、Opera9.64、Safari3.2.2、Google Chrome1.0、Mac OSX用Safari3で動作しました。2つ目の指定をもっとスマートに書けないものかなぁ……
2009年3月28日追記
なぜ上記のようなとてつもなくやっつけ半分なコードになっているかについてですが、vanguardeさん(ご協力ありがとうございます)よりコメント欄にてご意見いただいているように、よりスマートな書き方としては……
content: url(‘icon_outside.png’);
}
という書き方が存在します。これは”href属性がhttpで開始されているaタグのうち、http://www.eight-bits.net(自分のドメイン)での開始を除いたものの後にicon_outside.pngを追加する”という意味になりますが、この方法ですと、IE8では動作しませんでした……そもそも:notが対応していないようです。
また、その他にも2つ目に挙げたコードをちょっとでもスマートにしようと……
content: url(‘icon_outside.png’);
}
div.post p a[href^='http://www.eight-bits.net']:after {
content: none;
}
“href属性がhttpで開始するaタグにicon_outside.pngを追加するが、href属性がhttp://www.eight-bits.net(自分のドメイン)で開始するaタグの場合は何も追加しない”的なコードにしてみたのですが、こちらはWindows用Opera 9.64、Windows用Safari 3.2.2、Google Chrome 1.0で動作しませんでした。2つ目の指定が1つ目に対して上書きされていないのかと思い、content: none !important;としてみてもやはり動作せず。
正しいというか、スマートなコードを書きたければCSS3の導入はもう少し先にすべきかもしれません。
ちなみにこれは余談ですが、jQueryによる仮想CSS3にて今までこの動作をさせていたのですが、これがIE8ではJavaScriptエラーが発生し気持ちが悪かったために、CSS3への転換を決意したというのが事の発端です。

こんにちは。
二つ目の指定ですが、CSS3の:not()を利用するのはいかがでしょうか。
div.post p a[href^='http']:not([href^='http://www.eight-bits.net']):after { … }
こんな感じです。セレクタは長ったらしいんですが、empty.pngよりはスマートであるように思います。
>vantguardeさん
コメントありがとうございます。
:notを用いる件についてですが、こちらでも導入を検討していたものの、テストでIE8がnotの動作をしない状態になっているようでした。
無論vantguardeさんの言うように、empty.pngとかほんとスマートじゃないですよ。
何か指定がおかしいのかなぁ……
おおー、すみません。IE8も入るんですね。
IE8は基本的にCSS2レベルのサポートしかしないので、notは使えないんですよー
http://lh3.jp/works/2009/wsdbook/app4
あ、でもこの場合ならempty.pngじゃなくて content: none; でいいですね。
>vantguardeさん
毎度お越しいただいてありがとうございます。
そうなんです。IE8は:notに完全な対応をしていないんですよね。で、content: none;はモダンブラウザの先駆けともいえるWindows用Opera最新版9.64および、Windows用Safari最新版3.2.2、Windows用Google Chrome最新版1.0で動作しないというまったくもって困った状況なんですね。
このあたりもっと「なぜ、そうしなかったのか」という部分も含めて当エントリーも改変した方がいいかななんて思っております。
(まぁCSS3自体正式に勧告されてるわけでもないので、時期尚早かなんて見解もあったりしますが……)