あと一歩のところでうまくいかないCSSグリッドシステム

しばらく前からわたしはCSSグリッドシステムに取り憑かれたようになっている。このせいで成仏できないので取り憑く側といったほうが正しいのかもしれないが。

わたしが夢想しているグリッドシステムは以下の要件のもの。

  • HTMLとCSSだけで動く。JavaScriptに依存しない
  • リキッドレイアウトである
  • 行ごとに要素で囲む必要がない
  • グリッドの内容は、%指定でフレキシブルにすることもできるし、固定サイズにしておき領域幅をオーバーしたら改行するようにもできる
  • 使用があやういハックは使いたくない
  • IE8以上に対応する

この要件を満たしているサンプルはこちら。ブラウザの画面幅を加減すると、リキッドレイアウトのほうは自動的に幅が伸縮するし、固定幅レイアウトのほうは適宜改行されるようになると思う。

上記サンプルの動作環境はIE8+。うまくいっていない「あと一歩」はどこなのかというと、グリッドの基底要素(サンプルでいうところの .grid )にかけている font-size: 0 が、Android端末で認識されないという一点だ。ここ1年半くらいの間、この手法は安全牌だとおもって使い続けていたのだけど、なぜか今頃になってAndroidでうまくいっていないことが明らかになって、このあいだ途方に暮れたところだった。

ちなみに……。そもそもこの要件のグリッドシステムをわたしが欲しがっているワケは、レスポンシブデザインと相性がよく、サーバーサイドへの組み込みが容易なグリッドシステムを追い求めていたことに端を発する。レスポンシブデザインでは画面幅に応じて、3段組みだったレイアウトをいきなり2段組みに組み替えたいという要望がよくあるのだけど、行ごとにいちいち要素で囲んでいるとその要望に応えるのが困難になる。その点、世の中に出回っているグリッドシステムはほとんど使い物にならないと思っている。サーバーサイドへの組み込みの観点でも、ブロックを3個ずつ div で囲みながら繰り返してネ、などという対応は面倒くさいと思うし、時間の使い方として間違っているので、フロントエンドの人間としてそういうモノは成果物にしてはならないという責任感がある。

グリッドの基底要素で font-size: 0 として、子要素で復活させているのは、inline-blockを使う上で避けては通れない「空白文字のアキ問題」があるからだ。Androidでうまくいっていないのも同じ理由。他の回避方法(子要素間のホワイトスペースを無くす、コメントアウトする、<li>の終了タグを省略する、etc.)を使っていないのにも一応理由があって、それもやはりサーバーサイドの組み込みや、HTML量産の時の制約を増やしたくないという一点がある。サーバーサイドのテンプレートエンジンの制約とかで、子要素間のスペースをどうしても取り切れないとか、XHTML 5然とした整形式になっていないとダメ、とかはよくある話なので。

word-spacingに負の値を設定して空白文字を消すというハックもありますが、たいてい -0.31em というような根拠のない数字で、閲覧環境や表示フォントによって変動させるべきところを近似的に指定しているにすぎず、信頼性に欠いていると認識しています。

なんとなく個人的に考えている落としどころとしては、font-size: 0の技を使いつつ、子要素間のスペースが無いようにコーディングし、サーバーサイドの組み込みの人にはそのことを伝達しつつ、万が一のことを考えてJavaScriptを使って子要素間のテキストノードを殺して回しておく、とかになるのでしょうか。

まとめると、

  • わたしが求めているグリッドレイアウトは大体できているが、
  • Android端末が font-size: 0 を認識しない(最少フォントサイズがあるせい?)ため、
  • いろいろ試しているのだが、完璧な奴がどうしてもできない。
  • Flexboxはやく使いたい。

ということでした。今後も本記事のようなまとまりを欠いた駄文を量産してゆく所存です。