天むすのイラスト

CSS Grid Layout の gap を装飾する `column-rule` と `row-rule`

グリッドレイアウトで「列の間に線を引く」といった装飾は多くの場面で必要になります。しかし、flexbox や grid で列の間に線を引くためのプロパティは存在せず、ボーダーや背景色を利用して線のように見せるといったワークアラウンドが必要でした。CSS Grid Layout の gap を装飾する `column-rule` と `row-rule` を使用することにより、flexbox や grid で簡単に列や行の間に線を引くことができるようになります。

グリッドレイアウトで「列の間に線を引く」といった装飾は多くの場面で必要になります。CSS で「列の間に区切り線を引く」ためのプロパティとして column-rule がありますが、これらは段組みレイアウト(multicol)専用のプロパティであり、flexbox や grid には適用されませんでした。

flexbox や grid で列の間に線を引きたいという要望は多く存在したものの、それを実現する手段が存在しませんでした。そのためボーダーを特定の列にだけつける、あるいは背景色を利用して線のように見せたり、あるいは ::before 擬似要素を利用して線を引くといったワークアラウンドが使われてきました。

/* 方法1: 各アイテムの border-right / border-bottom を使い、最後の列・行だけ消す */
.card {
  border-right: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
}
.card:nth-child(3n) {
  border-right: none;
}
.card:nth-last-child(-n + 3) {
  border-bottom: none;
}
/* 方法2: gap を背景色で塗りつぶす */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background-color: #ccc;
}
 
.card {
  /* セルは背景色で塗りつぶす */
  background-color: white;
}

しかしこのようなワークアラウンドは直感的でなく、視覚的な表現のためだけに余分なコードが必要になるため、セマンティックな HTML の原則にも反します。またボーダーをつける方法では、列の幅が変わると線の位置も変わってしまうため、都度 nth-child で調整する必要があり、保守性も低いという問題もありました。

このような問題を解決するために従来の column-rule(multicol 専用だった)を flexbox や grid にも適用できるようにするための提案が行われ、補完的なプロパティとして行の間に線を引くための row-rule が追加されることになりました。これらのプロパティを使用することにより、flexbox や grid で簡単に列や行の間に線を引くことができるようになります。

Note

CSS Gap Decorations は現時点では実験的な機能です。Chrome と Edge 139 では Developer Trial として提供されており、使用するには chrome://flags/#enable-experimental-web-platform-features Experimental Web Platform Features を有効にする必要があります。

この記事では CSS Grid Layout の gap を装飾する column-rulerow-rule について解説します。

column-rulerow-rule の使い方

column-rulerow-rule を使用した「列の間に線を引く」ためのコードは非常にシンプルです。以下のように flexbox や grid のコンテナに対して、gap で余白を確保し、column-rule / row-rule で装飾します。

column-rulecolumn-rule-width(線の太さ)、column-rule-style(線のスタイル)、column-rule-color(線の色)の 3 つのサブプロパティのショートハンドです。row-rule も同様に row-rule-widthrow-rule-stylerow-rule-color のショートハンドです。

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  column-rule: 1px solid #ccc;
  row-rule: 1px solid #ccc;
}

flexbox でも同様に使用できます。display: flexflex-wrap: wrap を組み合わせた場合でも、column-rulerow-rule は gap に対して装飾を適用します。

.flex {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  column-rule: 1px solid #ccc;
  row-rule: 1px solid #ccc;
}

値の指定に repeat() を使用して複雑なパターンの線を引く

rule-color プロパティはギャップの装飾の色を指定するプロパティです。repeat() 関数と組み合わせることができるため、複雑なパターンの色を指定することもできます。以下の例では、列の間の線を赤と青の交互のパターンにしています。

.grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 20px;
  column-rule-width: 4px;
  column-rule-style: solid;
 
  /* 赤と青の交互のパターンにする */
  column-rule-color: repeat(auto, red, blue);
}

rule-width プロパティも同様に repeat() 関数と組み合わせることができます。数独のようなグリッドで、列の間の線を太くして区切りをわかりやすくする、といったことも簡単にできます。

.sudoku {
  --cell: 48px;
 
  display: grid;
  grid-template-columns: repeat(9, var(--cell));
  grid-template-rows: repeat(9, var(--cell));
  gap: 8px;
  padding: 8px;
  width: max-content;
 
  /* 3 列ごとに太い線を引く */
  column-rule:
    repeat(2, 1px solid #bbb),
    4px solid #111,
    repeat(2, 1px solid #bbb),
    4px solid #111,
    repeat(2, 1px solid #bbb);
 
  row-rule:
    repeat(2, 1px solid #bbb),
    4px solid #111,
    repeat(2, 1px solid #bbb),
    4px solid #111,
    repeat(2, 1px solid #bbb);
}

rule-break で交差点で線を途切方を指定する

rule-break は行の装飾が交差点で途切れるかどうかを指定するプロパティです。デフォルトは normal で T 字に交差する場合は線が途切れ、十字交差は線が途切れない状態になります。

スプレッドシートのような表形式のレイアウトを考えてみるとわかりやすいでしょう。セル結合して複数の列にまたがる見出しがある場合、T 字交差が発生します。rule-break: normal の場合は、セル結合している列の間の線は途切れていることがわかります。

rule-break には normal の他に以下のような値があります。

  • none: セルの結合状況を無視して、常に gap の端から端まで線を引く。セル結合があっても線は貫通する
  • intersection: column-rulerow-rule が交差する十字点で、両者が重なり合わないよう描画を調整する。格子の交点で自然な仕上がりになる

先程のセル結合の例で rule-break: none にすると、セル結合している列の間の線も途切れずに引かれることがわかります。

rule-break: intersectionrule-break: normal の違いは、十字交差点での見た目に現れます。normal では column-rulerow-rule がそのまま重なって描画されますが、intersection では交差点の描画が調整されるため、均一な格子線として見えます。テーブルのように行と列が対等に存在するレイアウトでは intersection が適しています。

まとめ

  • グリッドレイアウトで列の間に線を引くためにワークアラウンドが必要だった問題に対して、column-rule が flexbox や grid にも適用できるようになり、行の間に線を引くための row-rule も追加された
  • column-rulerow-rule を使用することで、シンプルに列や行の間に線を引くことができるようになった
  • 値の指定に repeat() を使用することで、複雑なパターンの線を引くこともできる
  • rule-break プロパティを使用することで、交差点で線を途切れさせるかどうかを指定できる。デフォルトは normal で T 字交差は線が途切れ、十字交差は線が途切れない状態になる。intersection に設定すると、テーブルのようなレイアウトで交差点で線が重ならない自然な見た目になる

参考

記事の理解度チェック

以下の問題に答えて、記事の理解を深めましょう。

`rule-break` の説明として、記事の内容に合っているものはどれですか?

  • gap の幅そのものを増減させるプロパティで、デフォルトは `none` である

    もう一度考えてみましょう

    `rule-break` は gap の幅を変えるプロパティではなく、交差点で装飾線を途切れさせるかどうかを指定するプロパティとして説明されています。

  • 行の装飾が交差点で途切れるかどうかを指定し、デフォルトの `normal` では T 字交差で線が途切れる

    正解!

    記事では、`rule-break` のデフォルトは `normal` で、T 字に交差する場合は線が途切れ、十字交差では線が途切れないと説明されています。

  • 線の色を交差点ごとに切り替えるプロパティで、`intersection` は赤と青を交互に指定する

    もう一度考えてみましょう

    線の色のパターン指定は `rule-color` と `repeat()` の説明で扱われています。`intersection` は交差点での重なりを調整する値として紹介されています。

  • flexbox では使えず、CSS Multi-column Layout だけに適用される

    もう一度考えてみましょう

    記事全体では、従来 multicol 専用だった `column-rule` を flexbox や grid にも適用できるようにする提案として CSS Gap Decorations が説明されています。