LoginSignup
10
5

More than 3 years have passed since last update.

今更学ぶ CSS Multi-column Layout の使い所

Last updated at Posted at 2020-08-02

はじめに

横並びのレイアウトは近年では Flexbox や CSS Grid 、少し前でしたら float によるレイアウトなどの手法があります。
自分はまず反射的に Flexbox を使用することが頭に浮かびますが、場合によっては CSS Multi-column Layout を使うことで、文書構造に沿った HTML のまま段組レイアウトを実装することができます。

MDN web docs 段組みレイアウト

ブラウザ対応状況

マルチカラムレイアウトは column-count プロパティによって段組レイアウトが行われます。
比較的長く使われているプロパティで、対応ブラウザの幅も広いようです。

スクリーンショット 2020-08-02 17.50.58.png

CSS Multi-column Layout でできること

よくサンプルとして上げられるのは、雑誌などに見られる段組テキストのレイアウトです。
column-count プロパティを設定することで、各カラムが同程度の高さに調整されたマルチカラムレイアウトを実現することができます。

index.html
<p class="text">吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。</p>
main.css
.text {
  column-count: 2;
}

スクリーンショット 2020-08-02 19.25.28.png

3 カラム以上のレイアウトも同様に実装可能です。

main.css
.text {
  column-count: 3;
}

スクリーンショット 2020-08-02 19.35.45.png

またcolumn-width プロパティや column-gap プロパティを使用することによって段組幅やギャップ(列間隔)の調整を行うことも可能です。

表の段組レイアウトで使用する

横方向へ見ていく表であれば Flexbox が良さそうですが、縦方向の表となるとすこし厄介です。

スクリーンショット 2020-08-02 23.35.54.png

Flexbox でのレイアウトを行おうとすると、本来不要な位置でマークアップを分割する必要が出てしまいますが、マルチカラムレイアウトを使用することでマークアップを分割することなく調整が可能です。
また子要素数の増減も HTML への要素の追加・削除のみで簡単に行うことができます。

マークアップ
index.html
<div class="nutrition">
  <dl class="nutrition_list">
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">エネルギー</dt>
      <dd class="nutrition_listAmount">240kcal</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">タンパク質</dt>
      <dd class="nutrition_listAmount">4.4g</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">脂質</dt>
      <dd class="nutrition_listAmount">10.2g</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">炭水化物</dt>
      <dd class="nutrition_listAmount">18.7g</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">糖質</dt>
      <dd class="nutrition_listAmount">19.7g</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">食物繊維</dt>
      <dd class="nutrition_listAmount">2g</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">食塩相当量</dt>
      <dd class="nutrition_listAmount">0.64g</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">カルシウム</dt>
      <dd class="nutrition_listAmount">120mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading"></dt>
      <dd class="nutrition_listAmount">1mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">マグネシウム</dt>
      <dd class="nutrition_listAmount">230mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">リン</dt>
      <dd class="nutrition_listAmount">47mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンA</dt>
      <dd class="nutrition_listAmount">205μg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンB1</dt>
      <dd class="nutrition_listAmount">0.2mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンB2</dt>
      <dd class="nutrition_listAmount">0.3mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンB6</dt>
      <dd class="nutrition_listAmount">0.3mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンB12</dt>
      <dd class="nutrition_listAmount">0.7μg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ナイアシン</dt>
      <dd class="nutrition_listAmount">3mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">パントテン酸</dt>
      <dd class="nutrition_listAmount">1mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">葉酸</dt>
      <dd class="nutrition_listAmount">50μg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンC</dt>
      <dd class="nutrition_listAmount">20mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンD</dt>
      <dd class="nutrition_listAmount">1.3μg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">ビタミンE</dt>
      <dd class="nutrition_listAmount">1.4mg</dd>
    </div>
    <div class="nutrition_listInner">
      <dt class="nutrition_listHeading">(備考)<br>カリウム</dt>
      <dd class="nutrition_listAmount">40mg</dd>
    </div>
  </dl>
</div>

main.css
.nutrition_list {
  column-count: 2;
  column-gap: 24px;
}

.nutrition_listInner {
  break-inside: avoid;
  display: flex;
  margin-bottom: 4px;
}

_::-webkit-full-page-media, _:future, :root .nutrition_listInner {
  // Safari 調整用
  margin-top: 4px;
  margin-bottom: 0;
}

.nutrition_listHeading {
  flex-basis: 45%;
  padding: 8px 16px;
  background-color: hsl(100, 60, 84);
  font-size: 14px;
  font-weight: bold;
}

.nutrition_listAmount {
  display: flex;
  align-items: center;
  flex-grow: 1;
  padding: 8px 16px;
  background-color: hsl(210, 6, 94);
}

break-inside: avoid; を指定する

上記のような表のレイアウト時には break-inside: avoid; プロパティを指定しておくことで、子要素の途中での改ページ/改カラムを防ぐことができます。
(似たもので page-break-inside プロパティがありますが、break-inside: avoid; によって置き換えられたプロパティのようです。)

スクリーンショット 2020-08-02 21.43.45.png

参考: Safari での若干の挙動の違い

上記のようなプロパティの指定を行なったマルチカラムレイアウトによる表の段組では、 Safari で若干挙動の違いが見られました。
下キャプチャのように、改カラム位置での margin-bottom が次カラムに影響を及ぼし、ズレが発生するようことがあるようです。

  • Chrome
    スクリーンショット 2020-08-02 23.34.27.png

  • Safari
    スクリーンショット 2020-08-02 23.34.12.png

Safari 対応用の CSS ハックによってレイアウトを調整しておきます。

_::-webkit-full-page-media, _:future, :root .nutrition_list {
  // Safari 調整用
  margin-top: -4px;
}

_::-webkit-full-page-media, _:future, :root .nutrition_listInner {
  // Safari 調整用
  margin-top: 4px;
  margin-bottom: 0;
}

まとめ

あまり使用頻度の高いプロパティではないので自分は使ったことがなかったですが、必要に応じて使うことができるとよいプロパティだと思います。
Safari での挙動の違い以外にも、レイアウトがブラウザに一任されますのでブラウザごとで若干の挙動の違いがありそうです。
(挙動の差を許容・対応できるかどうか、がマルチカラムレイアウトを使用するかどうかの分かれ目になりそうですね。)
ポリフィルなどによる IE 対応を考えずに使用できるのは嬉しいところです。

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5