この記事は2年以上前に書かれた記事です。現状にそぐわないかもなのでご注意を。

[jQuery] IE6/7/8で角丸(not PIE.htc) 2013

角丸に便利なCSS3プロパティの border-radiusですが、IE8以下には対応していません。
これに対応させる PIE.htc というものもあるにはあるのですが、
大きめの(wrapperクラスを当てるようなdiv要素のような)ブロック要素にあてると
位置がズレたり印刷時に真っ白になったりと、軽々には使えません。

そこで、jQueryを使ってPIE.htcを使わずに角丸を実現する方法を考えてみました。

Point

  • HTMLに角丸のための余計な要素・クラスを追加しない
  • CSSスタイルの設定は1箇所に集約。ハックは最低限に。

まずはモダンブラウザ用に普通に角丸スタイルを作成。

.smnbox
{ padding:20px; background: #fff; border:solid 1px #ccc;
-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;}

次に Old IE用に以下のような角丸の画像を用意します。
幅が異なるブロックには、その幅の種類だけ画像を用意します。

これの上半分と下半分をそれぞれ背景画像にしたスタイルを準備します。

.smn-head, .smn-foot
{ display: block; background-repeat:no-repeat; height:5px;
line-height:1px; font-size:1px; overflow:hidden; zoom:1; }
.smn-head { background-position: left top; vertical-align:bottom; }
.smn-foot { background-position: left bottom; }
.smn-head, .smn-foot
{ background-image: url(images/km-210.png); }

画像を読み込んでいる部分以外は全サイズ共通化できるように分けてます。
いくつかIE6用のおまじないが入ってますがそこは臨機応変に。

で、ここからがこのやり方のキモ。
jQueryで角丸要素の前と後ろに↑で設定したスタイルを適用させたボックスを生成させます。

$('div.smnbox').before('<div?class="smn-head"></div>').after('<div?class="smn-foot"></div>');

あとはメインボックスの上下のボーダーを消して、paddingを微調整すればモダンブラウザと見た目の違いはなくなります。

$('div.smnbox').css({'padding-top':'-=5px','padding-bottom':'-=5px','border-width':'0 1px'});

このjQueryソースを

<!--[if lt IE 9]><![endif]-->

で括って完成。

あとは背景の角丸画像に透明PNGを使う場合の対策も必要になってきますが
それはまた別の機会に。

追記(2013.2.17)

Old IE用にjQueryで角丸用ボックスを追加するのがキモでした。
が、所詮絶滅を期待してやまない Old IEのために追加する要素です。
それをわざわざクリーンにして、画像・CSS・jQueryの調整に手間をかける必要はないと思い、角丸要素の幅やクラスの増加に対して、手間を最小限にする方向で改良してみました。

用意する角丸画像は最少の1サイズで。これで全ての幅に対応します。
IE8用の透明PNGと、IE7/6用の透明GIFを用意。

kadomaru

角丸用のCSSは以下。

どんな幅の角丸ボックスにもこれだけで対応します。
角丸のサイズに応じて、width / heightは調整の必要があります。

.kadomaru { height:5px; line-height:1px; font-size:1px; overflow:hidden; position:relative; z-index:90; }
.kadomaru em { position:absolute; width:5px; height:5px; background-image: url(../images/kadomaru.png); *background-image: url(../images/kadomaru.gif); background-repeat:no-repeat; overflow:hidden; zoom:1; z-index:91; }
 em.kdmr-tr { top:0; right:0; background-position:right top; }
 em.kdmr-tl { top:0; left:0; background-position:left top; }
 em.kdmr-br { bottom:0; right:0; background-position:right bottom; }
 em.kdmr-bl { bottom:0; left:0; background-position:left bottom; }
.kadomaru div { height:4px; margin:0 5px; background:#fff; zoom:1; }
 div.kdmr-tc { border-top: solid 1px #ccc; }
 div.kdmr-bc { border-bottom: solid 1px #ccc; }

jQueryのソースは以下。
角丸にしたい要素を追加指定していくだけです。

$('div.kadomarubox')
.css({'padding-top':'-=5px','padding-bottom':'-=5px','border-width':'0 1px'})
.before ('<div class="kadomaru"><em class="kdmr-tr"></em><em class="kdmr-tl"></em><div class="kdmr-tc"></div></div>').after ('<div class="kadomaru"><em class="kdmr-br"></em><em class="kdmr-bl"></em><div class="kdmr-bc"></div></div>');

だいぶ手数を減らすことができました。

※追記(2013.2.20)

追加した角丸用ボックス(.kadomaru)に謎の高さが発生する場合、
角丸用ボックスの親要素のブロック要素をインライン要素にすると治る場合あり

(以下のプロパティを親要素に追加)

width:100%; *display:inline;zoom:1;

スポンサーリンク