クロスブラウザで display:inline-block させる jQuery プラグインを作ってみた

更新履歴

2009-11-11
ご要望があったので jQuery.exInlineBlock.js の圧縮版をダウンロードできるようにしました。

CSS には display:inline-block というボックス要素を横並びに配置させる機能があります。

通常のボックス要素(diplay:block)は、横に伸び、縦に縮む性質があり以下のように段積みになります。



幅を指定してサイドに空間を設けても、ブロック要素なので段積みになります。


inline-block の場合は、横にも縦にも縮む性質があり、span や a の inline 要素のように要素を横並びにします。



inline 要素と同様、親(先祖)要素で text-align:center とすればセンタリングもされます。



画面のレイアウトやパーツを配置する上でとても便利な機能ですが、IE6/7 、 Firefox2 以下ではこの機能が実装されていません。

未実装ブラウザで inline-block を実現する方法


これについてはいつもお世話になってるブロガーの方々が記事にされています。


シンプルに書くなら下記記述で概ねクロスブラウザな inline-block を実現できるようです。

<style>
.inline-block{
    display: -moz-inline-box;   
    display: inline-block;   
    /display: inline;   
    /zoom: 1;
}
</style>
<div class="inline-block">sample</div>


但し、Firefox2以下の場合、後述のような問題が生じます。

Firefox2以下における inline-block の問題

inline-block 要素の子要素が inline-block 要素と同じ高さになってしまう

<div class="inline-block" style="height:100px;background:#e0e0e0">
    <input/>
    <span style="background:#aaccff">text</span>
</div>

Firefox2 Firefox3

親(先祖)要素に text-align:center の指定があっても inline-block 要素の子要素が inline-block 要素に対しセンタリングされない

<div style="text-align:center">
    <div class="inline-block" style="width:300px;background:#e0e0e0">
        <input/>
        <span style="background:#aaccff">text</span>
    </div>
</div>

Firefox2 Firefox3

position:relative な inline-block 要素が position:absolute な要素を子として持ってる場合、absolute 要素は inline-block 要素を基準とした配置位置にならない

<div class="inline-block" style="position:relative;background:#e0e0e0;">
    <input/>
    <span style="position:absolute;top:0;left:0;background:#aaccff">text</span>
</div>

Firefox2 Firefox3

Firefox2以下でも正しく inline-block させる


前述の問題は以下のように記述することで解決できます。

inline-block 要素の子要素が inline-block 要素と同じ高さになってしまう


inline-block 要素の子要素をもう1枚の div で(div.inner-inline-block) 囲むと解決します。

<div class="inline-block" style="height:100px;background:#e0e0e0">
    <div class="inner-inline-block">
        <input/>
        <span style="background:#aaccff">text</span>
    </div>
</div>

Firefox2 Firefox3

親(先祖)要素に text-align:center の指定があっても inline-block 要素の子要素が inline-block 要素に対しセンタリングされない


div.inner-inline-block に inline-block 要素と同じ幅を指定すると解決します。

<div style="text-align:center">
    <div class="inline-block" style="width:300px;background:#e0e0e0">
        <div class="inner-inline-block" style="width:300px">
            <input/>
            <span style="background:#aaccff">text</span>
        </div>
    </div>
</div>

Firefox2 Firefox3

position:relative な inline-block 要素が position:absolute な要素を子として持ってる場合、absolute 要素は inline-block 要素を基準とした配置位置にならない


div.inner-inline-block に inline-block 要素と同様に position:relative を指定すると解決します。

<div class="inline-block" style="position:relative;background:#e0e0e0;">
    <div class="inner-inline-block" style="position:relative">
        <input/>
        <span style="position:absolute;top:0;left:0;background:#aaccff">text</span>
    </div>
</div>

Firefox2 Firefox3

inline-block させる jQuery プラグインを作成してみる


CSS 定義やマークアップが面倒そうなので、指定要素を inline-block させる jQuery プラグインを書いてみました。

処理概要

  • IE6/7 の場合は、display:inline , zoom:1 を設定する
  • Firefox2 以下の場合は、display:-moz-inline-box を設定する。さらに子要素を div で囲み div には inline-block 要素と同じ position , width を設定する。
  • その他のブラウザの場合は、display:inline-block を設定する。
ソース

(function($j){
    $j.ex = $j.ex || {};
    $j.ex.inlineBlock = function(targets,config){
        var version = $j.browser.version.split('.');
        var noneSupportIE = $j.browser.msie && (version[0] < 8 || !$j.boxModel);
        var noneSupportMOZ = $j.browser.mozilla && version[0] == 1 && version[1] < 9;
        targets.css(
            (noneSupportIE) ? {
                'display':'inline',
                'zoom':'1'
            } :
            (noneSupportMOZ) ? {
                'display':'-moz-inline-box' 
            } : {
                'display':'inline-block'
            }
        );
        if(noneSupportMOZ){
            targets
                .each(function(idx){
                    var target = targets.eq(idx);
                    target.wrapInner('<div style="width:'+target.css('width')+';position:'+target.css('position')+';"/>');
                });
        }
        return targets;
    }
    $j.fn.exInlineBlock = function(config){
        return $j.ex.inlineBlock(this,config);
    };
})(jQuery);
使い方

jquery.js 、jquery.exinlineblock.js の順で読み込ませてください。

<script src="jquery.js"></script>
<script src="jquery.exinlineblock.js"></script>

jQuery セレクタで inline-block 化させたい要素を取得し、exInlineBlock メソッドを実行します。

jQuery(function($){
    $('#target').exInlineBlock();
});
Firefox のバージョン判定


$.browser.version の値が予想外だったのでメモしときます。
$.browser.version による Firefox のバージョン情報は単純に 2.0 とか 3.0 とかが返ってくるわけではなく、1.8.1.3 とか返ってきます。$.browser.version のもととなってる navigator.userAgent をバージョン別に確認すると以下のようになります。

Firefox1.5 - 1.8.1.3(Aptana IDE で確認)



Firefox2 - 1.8.1.17



Firefox3.5 - 1.9.1.12



Firefox の場合は、$.browser.version の頭3桁でバージョンの切り分けをするようにしました。

2009/11/18
以下のように parseFloat をことで簡単に判断できるようです。

isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);