table系にはposition:relativeが効かない

同じ事を書いている記事は他にもありますが、個人的に一番わかりやすくて細かいと思っていた記事が消えていたので。

というわけで、細かい話 は、ほぼ table系にはposition:relativeが効かない ( http://gyauza.egoism.jp/clip/archives/2007/11/071129-tablepositionrelative/ ) にあった内容を引っ張ってきて、文調と表現を若干変えてうちのブログに合わせただけです。許可も取ってませんが、お許し下さい。

Firefoxが正しい

<td> や <div style=”dispaly:tablec-cell”> の中身を絶対位置で指定したいなー

親の<td> や <div style=”dispaly:tablec-cell”> に position:relative を指定

chrome や IE で確認、よし出来た?

あれ? Firefox では position:relative が効いてないぞ

<div>
    <table>
        <td>
            <div class="left">左上</div>
            <div class="right">右下</div>
        </td>
        <td>
            <div class="right">右下</div>
            <div class="left">左上</div>
        </td>
    </table>
</div>
div {
    position: relative;
}

td {
    position: relative;
    width: 200px;
    height: 100px;
    border: solid 1px #000;
}

.left {
    position: absolute;
    left: 5px;
    top: 5px;
    color: red;
}

.right {
    position: absolute;
    right: 5px;
    bottom: 5px;
    color: blue;
}

table
サンプル

あると思います。

これは Firefox のバグではなく、 Chrome(webkit・blink全体?Androidでは効かないという情報あり) や IE が独自の実装をしているのです。効かない方が正しい表示です。
「Androidでは効かないバグかー」といったようなツイートを見かけたこともありますが、どちらかと言えば効いている方がバグみたいなものです。

細かい話

CSS2.1 Visual formatting modelによると

The effect of ‘position:relative’ on table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption elements is undefined.

CSS2.1 – Visual formatting model – 9.3.1 Choosing a positioning scheme: ‘position’ property

テーブルの中身系に対する position:relative の指定は、定義されていません。よって、この通り実装している Firefox では無視されるわけです。

尚、親の table や display:table; に position:relative; を指定しても、そこを基準に絶対配置はしてくれません。御存知の通り、 position:absolute を指定した要素は、祖先の包含ブロックに position:static 以外を指定したとき、そこを基準に絶対配置するのですが、どの要素が包含ブロックを作るかは決まっていて、最初の包含ブロックは viewport、ようするにブラウザの表示領域ですが、それ以下の要素に関しては

For other elements, if the element’s position is ‘relative’ or ‘static’, the containing block is formed by the content edge of the nearest block-level, table cell or inline-block ancestor box.

CSS2.1 – Visual formatting model details – 10.1 Definition of “containing block”

block-level / table cell / inline-block が、この包含ブロックを作りますが、table はブロックレベルのような振る舞いをするだけで、実はブロックレベルではないらしく、包含ブロックは作れないようです。Tableの項を見ると

In terms of the visual formatting model, a table can behave like a block-level (for ‘display: table’) or inline-level (for ‘display: inline-table’) element.

CSS2.1 – Tables – 17.4 Tables in the visual formatting model”

正に「tableはブロックレベル(やインライレベル)のように振る舞える」だけでブロックレベルではないようです。

おわり

最近は display:table-cell とか非常に便利ですが、この辺は理解しておかないとドハマリするよ、ということで、毎度あげさせてもらっていた記事が消えていたので、勝手にそこだけ復旧的な記事でした。