a-blog cmsのユニットグループに5種類のグリッドシステム方法を検討する
1月のa-blog cms DAYでも言っていたのですが、ユニットグループがレスポンシブしない時代からレスポンシブ対応するために変わったように、レスポンシブ対応により適するためにも、もう少し変わった方が使いやすくなるんじゃないかなと個人的に感じています。
そこで、社内勉強会の当番が回ってきて社内の人の意見を聞けるいい機会だったので、現状の問題をまとめて、解決策になりそうなCSSの実装方法を調べてみました。
まずは現状の問題を整理する
機能の問題
左カラムよりも右カラムの方がコンテンツ量が少ない時に要素が回り込んでしまいます。
左カラムよりも右カラムの方がコンテンツ量が少ない時に問題
上記の問題に対して、対策としてユニットの配置を「全体」を指定して、3カラムの間にhrを挿入してフロート解除していたのですが、この場合に文章量によってはPCでは3カラム、タブレットでは2カラム、スマートフォンでは1カラムが難しくなります。
PCで3カラムをタブレットで2カラムにしようとするとレイアウトが崩れる
人の使い方の問題
そもそもこの「全体」の機能は直感的に使えるものではないんじゃないかとも思いはじめてきました。
正直ユニットグループを普段から使ってないと忘れがちな機能
ユニットグループ、このままでいいの?という考えがすこしよぎってしまったので、新しいCSSのプロパティも含めて、対応策を検討してみました。
検討したグリッドシステムの方法
そもそも、この問題はdisplay: block;の要素を横並びにするには幅を指定して、floatする必要があります。ただ、現状のこの方法だと、左の要素よりも右の要素の高さが足りなかったとき、下の段の要素が上の段に移動することが原因です。
以上の点を踏まえて5つの方法を考えてみました
- 行ごとにdivを用意する方法
hrではなくclear: both;を使った方法display: inline-block;を使った方法- Flexbox
- CSS Grid Layout
行ごとにdivで囲む
Bootstrap3では行を囲む親divを用意する方法で解決しています。要素の間にdivがあるため、floatができないようになっています。
こちらは現状のシステムでは実装ができないので、何かしら対策が必要です。
clear: both;を使う
CSSで左端の要素に指定してfloatさせない方法です。現状だと、:nth-type-of や :nth-child では左端の要素を必ず指定することができないので、左端の要素を何かしら判定してあげる必要が出てきます。
:nth-type-of や :nth-childなどのCSSの力だけで対応しようとすると、使っている部分をdivで囲んであげる必要が出てくるので、こちらも現状のシステムでは実装ができないので、何かしら対策が必要です。
display: inline-block; を使う方法
display: inline-block;を使うと、floatを使わずに横並びにすることができます。floatしているわけではないので、左の要素よりも右の要素の高さが足りなかったとき、下の段の要素が上の段に移動してしまう可能性がありません。
ただ、実はこの方法だと、display: inline-block;の要素の間に余白ができてしまい、カラムが落ちてうまく並べることができません。
キレイにレイアウトするには、以下のどれかの方法をとる必要があります。
- 親
divにfont-size: 0;を適応する - 親
divにletter-spacing: -1em;を適応・子要素にletter-spacing:normal; - HTMLタグの間にスペースを空けない
- HTMLタグの間にコメントを書く
などの対処方法が挙げられるのですが、一手間が入り、すこし難ありです。
そして、たまたまもう1つの方法を発見したのですが、親divにdisplay: flex;を適応しても余白を削除でき、キレイにレイアウトが出来るようです。少し気になってdisplay: flex;について調べてみたところ、以下のような仕様を発見しました。
flex コンテナの直接の子要素になっているテキストは、無名の flex アイテムに包まれています。しかし、ホワイトスペースのみを含む無名の flex アイテムはレンダリングされません。これは、display:none が指定されたような状態です。
CSS flexible box の利用 - Web developer guide | MDN
display: flex;を使うと、 IE10以上の対応になってしまいますし、あくまで余談でした。
ちなみに、このdisplay: inline-block;のグリッドシステムはCardinalというCSSフレームワークで採用されています。
Flexbox を使う方法
flexboxはautoHeightのようなjsを使わなくても、隣の要素と高さを合わせることができますし、CSSでレイアウトの順序を変更することができます。そのかわり、IE10からの対応になります。
CSSでレイアウトの順序を変更することができるのですが、これにはa-blog cmsのユニットグループは対応できません。というのも、flexboxの順序をしていする値は数字です。親divがすべてのユニットグループを囲んでおり、order: 1;やorder: 2;は用意できますが、order: 101;など用意していたらキリがありません。
1行ずつ囲むdivがあれば、この方法は解決できるかもしれませんし、順序を変換するorderプロパティを使わなければいい話かもしれません。
CSS Grid Layout
CSS Grid Layoutはまだ対応しているブラウザが少なく、ChromeやFirefoxでも対応していないのですが、マイクロソフトの人たちが中心になって進めている分、IE10から対応しています(2015年2月15日現在)。
新しいグリッドシステムの方法として注目したのですが、少し触ってみたのですが、a-blog cmsのユニットグループには使えない印象を受けました。
というのも、他の方法と違って、子要素に幅を指定するのではなく、この幅を親に指定するからです。サイト全体のレイアウトを調整するには良さそうですが、ユーザーに個々の幅を指定するユニットグループとは合わなさそうな印象でした。
CSS Grid Layoutイメージ図
.grid {
display: grid;
// 親の要素に高さ、幅を指定する
grid-template-columns: 200px 40px auto;
grid-template-rows: auto 1fr;
}
.grid-item-1 {
// 子要素に設定を割り当てていく
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
すべての実装方法をまとめる
| IE対応 | その他 | |
| divを行ごとに囲む | ok | 現状のシステムの機能ではできない |
| clear: both | IE9以上 | :nth-childを使う、グループごとにdivが必要 |
| inline-block | IE8 | 実装に難あり |
| Flexbox | IE10 | orderプロパティなど一部が使えない |
| CSS Grid Layout | IE10(他のブラウザx) | 問題外 |
Flexboxはなかなか良さそうではないかなと思っていますが、IE10からの対応です。inline-block以外はどれも現状のシステムでは解決できなさそうです。divを一つ囲んであげられるなら、解決できる問題がだいぶでてきます。
1行をdivで囲むには?
1行をdivで囲むとしたら、システムになにか加えることになってしまいますが、一応こちらの方法も考えてみました。
- Baser CMSの BurgerEditor やMail Chimp のような入力
- レイアウトモジュールのユニットバージョンを用意する
Baser CMSのBurgerEditorやMail Chimpの入力方法であれば、すこし自由度は下がってしまいますが、CSSの実装のパターンが決まってきて、制作者は楽になると思います。
社内勉強会の後
以上はすべてCSSで解決するための方法をまとめてきたのですが、現状CSSだけでは難しく、社内勉強会ではjs側で高さを揃えたり、左端をclear: both;させてフロートを解除するほうがいいんじゃないかという意見が出てきました。
まだテストが不十分なので具体的な対策を記述することはできませんが、勉強会の翌日に、早速問題に対応するための機能をプログラマーさんが用意していたので、なにかしら時期バージョンには対策したものが用意できるんではないかなと思います。
個人的には勉強会で話してみるものだなーと思いつつ、皆さんには「こんなこと考えてるんだ」程度に思っていただけたら幸いです。