2020-03-10

【BULMA】ColumnsではなくTileを使うと下が揃う

CardをColumnsで並べると下部が揃わない。今回はTileを利用することにより下側もきれいに揃える。

Article Image

めんどくなったので画像は適当である。

Columnsは左から右に並べる時に便利

まずはColumnsの例。理解しやすいのでHTMLにJSX構文で表記するが説明も入れるので知らなくても安心してほしい

まずはBULMAのコードのおさらいから

  <div class="columns">
    <div class="column">
      {test_card_short()}
    </div>
  </div>

columnsの中にcolumnを入れることによって左から右に並べていくことができる。

JSX構文で説明するのはこの { } 鉤括弧でくくられてる部分だけ覚えておいてほしい。この中にカードのタグが変数的に引っ張ってくるだけなので今回は完全に無視して良い(つまりカードのHTMLタグはこの外にtest_card_shortとして記述してある)

縦とか横とかわかりにくいので更に説明しておくと、例えばHTMLなら<h1><p>タグを書けば<br>を入れることなく次々に下側の段へと表示が積まれていく。

columnは英語で「柱」なので縦を印象付けるかもしれないがレイアウト的には下にいくのではなく、横側に積む印象で覚えても良いかと思う。

とりあえずcolumnでカードを左から右に並べる

  <div class="columns">
    <div class="column">
      {test_card_short()}
    </div>
    <div class="column">
      {test_card_short()}
    </div>
    <div class="column">
      {test_card_short()}
    </div>
  </div>

3つ並べてみた。実行結果は次のようになる。

# とりあえずcolumnでカードを横に並べる

説明通り左から右にカードが3枚積まれた。これはこれで美しい。

しかし、コレは問題がある。カード下部の文字列の長さをカードごとに変更してみると次のようになる。

カード下部の文字列の長さをカードごとに変更してみるとどうなるだろうか。

カードの長さが変わってしまった。スペースが出来てしまいこれでは美しいとは言えない。

この問題に直面した人は多いのではないだろうか。特にCardやBoxを使ってBLOG記事の一覧をレイアウトする場合は少し見にくい印象を受ける。

Tileを使ってみよう

Tileの詳しい説明はこちら(https://bulma.io/documentation/layout/tiles/)にある

英語が難しいとかそれ以前にtileが入れ子になっていて非常に分かりづらい。今回はこれを少しわかりやすくするのが目標だ。

試しに入れ子にしてみる

  <div class="tile">
    <div class="tile">
      {test_card_short()}
    </div>
    <div class="tile">
      {test_card_middle()}
    </div>
    <div class="tile">
      {test_card_long()}
    </div>
  </div>

test_card_short, test_card_middle, test_card_longは単純に下部の文章が長いか短いかで3種類に分けた。先程のcolumnで長さがズレた例そのままだ。

今回はcolumnstileに置き換えただけだ。公式の解説には色々書かれてあるが、とりあえず入れ子にしてみたらどうなるのか。

とりあえず入れ子にしてみたらどうなるのか。

おや、すでにこれでも十分機能している。よく見ると文章の長さが違うにも関わらず下が揃っている。

しかし問題がある。マージンが無く窮屈だ。

ここで重要になってくるのが

  • is-ancestor
  • is-parent
  • is-child

まずは入れ子の一番上のtileにis-ancestorをつけるらしい。これによりカードの外側のマージンが詰まって更にカードが大きくなる。

とりあえず一番上のtileにつけておけば良い程度に覚えておけばよいだろう。

次にカードの最初の1枚めだけにis-parentを付けてみよう。

![is-parentを付けてみよう。](img/2020-03-10_21h26_55.jpg "is-parentを付けてみよう。")

最初のカードに上手いことpaddingが入ったように見える。これなら3枚ともis-parentにしておけばスペースが確保されて見やすくなるだろう。

is-parent

完成である。

ここまでのコードは

  <div class="tile is-ancestor">
    <div class="tile is-parent">
      {test_card_short()}
    </div>
    <div class="tile is-parent">
      {test_card_middle()}
    </div>
    <div class="tile is-parent">
      {test_card_long()}
    </div>
  </div>

入れ子(Nesting)にする場合このようにancestor > parent > child の順で付けていくと概ね上手くスタイリングされるように出来ているようだ。

is-?

さて、御存知の通り通常レイアウトは12というマスを持っていてis-数字というコードを付けてやれば合計12になるまで横に積まれ、 オーバーしたら改行されて次の行に行くはずだ。

しかし、残念ながらBULMAのtileはこのコーディングが入っていないようで自前で改行しなければそのままカードはひたすら右に積まれていく。合計12を超えるがスクロールバーも表示されない

    <div class="tile is-parent is-6">
      {test_card_short()}
    </div>
    <div class="tile is-parent is-6">
      {test_card_middle()}
    </div>
    <div class="tile is-parent is-6">
      {test_card_long()}
    </div>
    <div class="tile is-parent is-6">
      {test_card_short()}
    </div>
    <div class="tile is-parent is-6">
      {test_card_middle()}
    </div>
    <div class="tile is-parent is-6">
      {test_card_long()}
    </div>

こうすると

2020 03 10 21h44 36

こうなってしまうので注意

下へ積むには?改行?

次の行に行くにはどうしたらいいのだろうか。

色々試行錯誤たが、ancestorを1行としてどんどん次のancestorを置いていくのが一番楽でコードも短かった。

  <div class="tile is-ancestor">
    <div class="tile is-parent">
      {test_card_short()}
    </div>
    <div class="tile is-parent">
      {test_card_middle()}
    </div>
    <div class="tile is-parent">
      {test_card_long()}
    </div>
  </div>

  <div class="tile is-ancestor">
    <div class="tile is-parent">
      {test_card_short()}
    </div>
    <div class="tile is-parent">
      {test_card_middle()}
    </div>
    <div class="tile is-parent">
      {test_card_long()}
    </div>
  </div>

これが2行の例

これが2行の例

きれいに揃うデザインなので概ねこれで解決だと思う。しかしまだ少し気になるコードが残っている。

is-verticalとは何か

is-verticalの場合それより内側のtileが縦に積まれるようになる。これを使えばより正しいコードになるのだろうかと考えた。今回はこの落とし穴に注意が必要だ。

  <div class="tile is-ancestor">
    <div class="tile is-parent is-vertical">
      <div class="tile is-child">
        {test_card_short()}
      </div>
      <div class="tile is-child">
        {test_card_short()}
      </div>
      <div class="tile is-child">
        {test_card_short()}
      </div>
    </div>

    <div class="tile is-parent">
      <div class="tile is-child">
        {test_card_short()}
      </div>
      <div class="tile is-child">
        {test_card_short()}
      </div>
      <div class="tile is-child">
        {test_card_short()}
      </div>
    </div>
  </div>

parentを2つ用意し、一つをis-verticalにした。

一つをis-verticalにした。

ご覧の通り片方が縦に積まれた。

この縦に積まれる方式を利用して先程のように3x2の美しいカード並びを再現してみようと試みる

  <div class="tile is-ancestor">

    <div class="tile is-parent is-vertical">
      <div class="tile is-child">
        {test_card_short()}
      </div>
      <div class="tile is-child">
        {test_card_short()}
      </div>
    </div>

    <div class="tile is-parent is-vertical">
      <div class="tile is-child">
        {test_card_long()}
      </div>
      <div class="tile is-child">
        {test_card_short()}
      </div>
    </div>

    <div class="tile is-parent is-vertical">
      <div class="tile is-child">
        {test_card_short()}
      </div>
      <div class="tile is-child">
        {test_card_middle()}
      </div>
    </div>

  </div>

非常にコードが煩雑になってきた。長くて入れ子のコードはあまりよろしくない。

左から右へ3段なのでis-verticaltileが3個必要だ。 その中に2個のtileを収めればそれぞれ上側のカード、下側のカードとなり3x2となる。

実践を考慮してカードの文章の長さを変えてレンダリングしてみる。

is-verticalのtileが3個必要だ。

ズレている

ご覧の通りズレている。 これは上から下にかけての箱の内側においてはそれぞれのtileの長さが自由であるから発生する。

つまり結論としてis-verticalは公式のtile説明にあるようにより複雑なレイアウト設計にのみ使用し、シンプルなレイアウトの場合は使わないほうがよさそうである。

使用例としてはPinterestのような画像のサイズに応じてフレキシブルにスペースを詰めていくデザインには極めて有効なのではないだろうか。

この先はコードが沼になるため今回はここまでにしておく。

まとめ

今回は非常に単純にカードの長さを揃えることに注目して解説したが、シンプルに揃えて改行するレイアウトはtileancestorで続ければ良いと考えている。

正直tileの利用方法はこれより更に複雑なレイアウトを表現するために存在するのだろう。

今回は詳しくやらなかったがis-verticalやその他を絡めたより複雑なレイアウトが自由自在に表現できたらそれはオシャレだろう。だが、 今回はここまでだ。

また必要になれば記事を追加しようと思う。



この記事のタグ

この記事をシェア


謎の技術研究部 (謎技研)