direction: rtl を指定した要素の子孫を ltr で戻しても行内テキストが右寄せになってしまうケース

テキストと画像を横並びにするモジュールなどを display: table-celldirectionプロパティ(W3C)を使って作ることがあります。

ソースコードはこんな感じ。

<!DOCTYPE html>
<html lang="ja">
<head>
<title>`direction: rtl` を指定した要素の子孫を `ltr` で戻しても行内テキストが右寄せになってしまうケース</title>
<style>
.image-sbs {
  display: table;
}
.image-sbs.text-first {
  direction: ltr; /* テキストエリアを先頭(左側)に表示する */
}
.image-sbs.image-first {
  direction: rtl; /* 画像を先頭(左側)に表示する */
}
.image-sbs > li {
  display: table-row;
}
.image-sbs > li .text,
.image-sbs > li .image {
  display: table-cell; /* 画像とテキストエリアを横並びにする */
  direction: ltr;
}
</style>
</head>
<body>
<ul class="image-sbs image-first">
  <li>
    <div class="text">
      <p>foo</p>
    </div>
    <div class="image"><img src="http://dummyimage.com/80x40/666/fff.png&amp;text=bar" alt="bar"/></div>
  </li>
  <li>
    <div class="text">
      <p>hogehoge</p>
    </div>
    <div class="image"><img src="http://dummyimage.com/120x40/666/fff.png&amp;text=piyopiyo" alt="piyopiyo"/></div>
  </li>
</ul>
</body>
</html>
サムネイル画像
Firefox 22 の表示オリジナル画像

directionプロパティを使う利点は、ソースオーダーを変えずに画像とテキストのどちらを先頭(左側)に表示するか制御できることにあります。このサンプルでは画像が左側に表示されますが、右側に表示する場合でも .image-sbs に付随するクラス名 image-firsttext-first に変更するだけで済みます。

ところが、これを Google Chrome や Opera(15) で見ると、テキストや画像が右に寄って表示されてしまいます。 .text.image には direction: ltr を指定してデフォルト値に戻してあるのに…。

サムネイル画像
Chrome 28 の表示オリジナル画像

Opera 12.1 や Safari 6 では左寄せだったので、最初は Blink エンジンを搭載するブラウザの問題かと思ったのですが、 Webkit な Chrome 27 でも再現したので、そうとも限らないようです。

また、この問題には li 要素の存在が影響していると思われます。というのも、先のマークアップは順不同リスト(ul)を使っていますが、これをdiv要素や記述リスト(dl)に変更したところ、どのブラウザでも左寄せになったからです。不思議ですね。

なお解決方法は簡単で、text-alignプロパティ(W3C)でテキスト揃えを明示すれば問題ありませんでした。

.image-sbs > li .text,
.image-sbs > li .image {
  display: table-cell; /* 画像とテキストエリアを横並びにする */
  direction: ltr;
  text-align: start; /* for Chrome, Opera */
}