横並びリストのバグ

liタグに対し「display: inline;」を使い横並びにし、右側のボーダーを区切り線に使ったところ、IE6・IE7でテキストが左寄りになってしまいました。

ソースは以下になります。

htmlソース

<ul id="footer_nav">
    <li><a href="./">トップ</a></li>
    <li><a href="products.html">商品紹介</a></li>
    <li><a href="inquiry.php">注文フォーム</a></li>
    <li><a href="outline.html">店舗案内</a></li>
    <li class="end"><a href="info.html">ご利用について</a></li>
</ul>

CSSソース

ul#footer_nav li {
    collor: #FFFFFF;
    display: inline;
    border-right: solid #FFFFFF 1px;
    padding; 0 9px 0 10px;
}
ul#footer_nav li a {
    color: #FFFFFF;
    text-decoration: none;
}
ul#footer_nav li.end {
    border-right: nane;
}

原因

まず、「dislpay: inline;」でリスト要素を横並びにした時、改行・タグ・スペースがブラウザ上で半角スペースとして挿入されてしまいます。
このバグは厄介な事に、ブラウザによってその半角スペースの挿入位置が異なります。

下の例では、分かりやすくliタグに対して左右のボーダーを付けました。

IE6・IE7での半角スペースの挿入位置

IE6・IE7では、リスト要素のボーダーの内側、テキストの右側に挿入されています。
liタグの中に半角スペースが入っているようです。

Firefox・IE8の半角スペースの挿入位置

Firefoxではリスト要素のボーダーとボーダーの間に挿入されています。
ulタグの中に、liタグと同列に半角スペースが挿入されているようです。

この違いが、IE6・IE7で左側に寄っているように見える原因でした。

解決法

htmlソースの記述方法で半角スペースを見えなくする方法

htmlソース上で、半角スペースの原因となる改行やタブ、スペースをulタグ内に存在させない為には、以下の方法が考えられます。

改行を使わずulタグやliタグを連続的に記述
改行とタブ部分をコメントアウトしてしまう
しかし、通常、改行が使えないと、一般的なコーディング規約を適用したり、Dreamwaverのオートフォーマット機能が使えなくなるなど弊害があります。
よって、この方法は、ベストの方法ではありません。

では、次にCSSで解決する方法を探ってゆきましょう。

IE6・IE7で半角スペースを見えなくする方法

IE6・IE7特有のCSS解釈方法「hasLayout」で、半角スペースを見えなくする方法があります。

それは、「hasLayout」の値をtrueにする事で解消されます。
具体的には、インラインに対して扱え、かつ見た目に影響がないの「zoom: 1;」を指定すれば良いのです。

IE6・IE7でのスペースが消えました。

しかし、フォントのサイズを変更している場合はどうでしょうか。
私の会社では、YUI library準拠のコーディングをしています。
font.cssでは、全部のブラウザでフォントサイズをほぼ同じに見せるために、フォントサイズを13pxに設定し、さらにそれを77%に縮小しています。

この環境下でliタグに対して「zoom:1;」を使うと、高さが13pxテキスト用にリセットされてしまいます。かつ、中に入るテキストには77%が通常通りに適用されてしまうので、ボーダーだけが長くなったように表示されてしまいます。

なので、font.cssを使っている以上、「zoom: 1;」を使う事はできません。

    Tips!

    hasLayoutとは、IE6・IE7特有のCSS解釈方法です。

    まず通常のliタグに「display: block;」でブロックにした要素(例えばaタグ等)を挿入します。

    するとなぜかリストの間に隙間が出来てしまいました。
    さらに、そのブロックにした要素に高さを指定してみます。

    今度は隙間は消えてしまいました。これは「hasLayout」の値がfalseからtrueに変更された為です。

    「hasLayout」は、要素のレイアウト情報の有無を判断しています。
    「hasLayout」の値が初期値であるfalseの場合、回りの要素に影響され幅や高さが変化してしまう事があるのです。

    このことから、表示が思ったようにならない場合は「hasLayout」を疑ってみましょう。

    position absolute
    float left or right
    display inline-block
    width any value or auto
    height any value or auto
    zoom any value or normal
    writing-mode tb-rl

    対象の要素に、上のリストのどれでも良いのでプロパティと値を設定すると、「hasLayout」の値がtrueになります。

    先述の例では高さを指定しましたが、高さや幅などの設定はレイアウトの見た目そのものに関わってしまいます。
    そこで使用するのが「zoom」。「zoom」はIE6、IE7専用のプロパティで、要素の拡大縮小を指定します。
    100%である「1」に値に指定しても、他に影響を与える事は少ないと考えられます。

    「zoom: 1;」のプロパティを追加したのが以下の物です。

    隙間もなく、正しく表示されました。

Firefox・IE8で半角スペースを見えなくする方法

「hasLayout」はIE6・IE7のみの概念なので、Firefoxと「hasLayout」を廃止しているIE8でのボーダーとボーダーの間にある半角スペースを解消することはできません。
ではFirefoxやIE8ではどうすればいいでしょうか。

FirefoxやIE8で半角スペースを消すには、「display: table-cell;」を使用します。
これは要素を「テーブルのセル(tdやth)」とするプロパティの値なので、タグ同士の間に存在する改行が無視され半角スペースがなくなります。

なお、この値はIE6・IE7非対応なので、先ほどの「display: inline;」と「zoom:1;」を IE6・IE7用にハックで設定しておく必要があります。

Firefoxでの半角スペースが解消されました。

半角スペースは解消されましたが、他の点はどうでしょうか。
実は「display: table-cell;」が適応された要素は「テーブルのセル」になるので、親要素に「text-angle:」が設定してあっても無効となってしまいます。

すなわち左寄せのレイアウトにする場合は問題ないのですが、中央寄せ・右寄せに表示したい場合は親要素に幅と左右のマージンを設定しなければならず、結果としてそれぞれのliタグのサイズを固定してしまう必要があるのです。

これでは「float:left」でリスト自体をフロートさせて並べるのと大差なく、この方法をサイズが可変のテキストのフッターリンク等に使うのはあまり良くありません。

回避方法

つまり、CSSでスマートに半角スペースを見せなくする方法はありませんでした。
なので、半角スペースを含んでも大丈夫なコーディングに変更します。

テキストの左寄りの原因は、リスト要素のテキスト右の部分。そこで左側のボーダーを使用します。

左側のボーダーを使うと、IE6・IE7とFirefox・IE8で見え方が等しくなります。

そして左側に半角スペース分の幅を含んだpaddingを設定すれば、左右が均等になります。

もちろんボーダーを非表示にするリスト要素のクラスを左右で入れ替えなければなりません。

ブラウザによるフォントの見え方の違いがあるものの、だいたい均等に配置されます。

ソースは以下になります。

htmlソース

<ul id="footer_nav">
    <li class="start"><a href="./">トップ</a></li>
    <li><a href="products.html">商品紹介</a></li>
    <li><a href="inquiry.php">注文フォーム</a></li>
    <li><a href="outline.html">店舗案内</a></li>
    <li><a href="info.html">ご利用について</a></li>
</ul>

CSSソース

ul#footer_nav li {
    collor: #FFFFFF;
    display: inline;
    border-left: solid #FFFFFF 1px;
    padding; 0 10px 0 14px;
}
ul#footer_nav li a {
    color: #FFFFFF;
    text-decoration: none;
}
ul#footer_nav li.start {
    border-right: nane;
}

こうした多くのブラウザのバグは、CSSのハックで解消する事が多いかと思われますが、
バグの特製を理解した上でコーディングの方法を工夫する事で解決する事もあります。
共通のCSSが使えると管理もしやすく、ハックは極力使わないのが望ましい事ですね。

2011/07/05 13:29