CSSで、グリッドやフレックスの間に区切り線を引く方法

​​CSS​CSS Grid,Flexbox,Playwright

グリッドやフレックスのアイテムの間に区切り線を引くには、コンテナーに gap で間をあけ、column-rule と row-rule で線の太さ・種類・色を指定します。アイテムに border を付けたり、線の代わりの要素を置いたりしなくて済みます。Chrome と Edge の 149 から使えます(Firefox と Safari は未対応)。

補足

検証環境は Ubuntu 24.04、Node.js 22.23.4、Playwright 1.63.0、ヘッドレスの Chromium 153 です。線がどこに描かれたかは、スクリーンショットの画素の色で調べました。ブラウザーの対応状況は @mdn/browser-compat-data 8.1.8 のデータです。Firefox と Safari、スマートフォンの実機、段組み(column-count)での線は試していません。

基本の書き方

column-rule は列と列の間の縦の線、row-rule は行と行の間の横の線です。値の書き方は border と同じで、太さ・種類・色を並べます。

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

column-rule は、もともと段組み(マルチカラム)の段の間に線を引くプロパティです。策定中の CSS Gaps Module Level 1 の仕様で、グリッドやフレックスのコンテナーにも使えるように広げられ、横の線を引く row-rule が加わりました。MDN の row-rule のページでも、グリッド、フレックス、段組みの行の間に引く線を指定するプロパティだと説明しています。

上の CSS を検証環境の Chromium で表示したのが次の画面です。下半分は、同じ指定を flex-wrap: wrap のフレックスに付けたものです。

グリッドとフレックスで、アイテムの間に縦の水色の線と横のピンクの線が引かれた画面
column-rule と row-rule をグリッドとフレックスに付けた画面

グリッドでは、縦と横の線がコンテナーの端から端まで通ります。縦と横が交わる点では横の線(ピンク)が上に描かれました。重なりの順は rule-overlap で決まり、初期値の row-over-column は横の線を上にします。

フレックスでは、縦の線はその行のアイテムの間だけに引かれます。アイテムの幅も並び方も行ごとに違うので、縦の線の位置は行ごとにそろいません。横の線は、折り返した行と行の間に、コンテナーの幅いっぱいに引かれました。

縦と横を同じ線にしたいときは、まとめて指定できる rule も使えます。

css
.grid {
  rule: 1px solid #9aa5ab;
}

線は場所を取らず、gap の中に描かれる

仕様では、線は場所を取らず、線があっても太くても、ほかの要素の配置は変わらないとされています。線が gap より太いときは、隣のアイテムが線の上に重なります。

検証環境で、gap: 4px のグリッドに太さ 12px の column-rule を付けて、付けないときと比べました。2番目のアイテムの位置と大きさは、どちらも同じでした。gap の部分は線の色になりましたが、gap からはみ出した部分は、背景色のあるアイテムに隠れて見えませんでした。

同じ理由で、gap が 0 だと線は見えません。背景が透明なアイテムに変えると、境目に線が描かれていました。線は描かれていても、アイテムの背景の下に隠れているということです。線を見せたいときは、線の太さ以上の gap をあけてください。

結合したセルで線を止める位置を変える

あるアイテムが2列ぶんにまたがっていると、その部分には列の間の gap がありません。線をどこで止めるかは rule-break(縦の線の column-rule-break と横の線の row-rule-break をまとめて指定するプロパティ)で変えられます。値は次の3つです。

値 線が止まる位置
normal(初期値) グリッドでは、T字に交わる点で止まり、十字に交わる点は通り抜ける。フレックスでは none と同じ
intersection T字と十字の両方の交点で止まる
none 交点で止まらず、gap の端から端まで1本でつなぐ

違いを見やすくするため、線の端を 6px ずつ短くする rule-inset: 6px を付けて比べました(rule-inset は次の節で説明します)。

2列ぶんにまたがるアイテムがあるグリッドで、rule-break を normal、intersection、none にしたときの線の違い
rule-break の3つの値と、線が止まる位置

normal では、1列目と2列目の間の縦の線が、2列ぶんのアイテムの下にあるT字の交点で止まり、交点から 6px 離れた位置から下へ描かれました。十字の交点では線は切れず、下の端まで1本で通っています。intersection では十字の交点でも線が切れ、セルごとの短い線になりました。none では、T字の交点でも切れず、コンテナーの上端から 6px 下がった位置から、下端の 6px 手前まで、1本の線になりました。2列ぶんのアイテムと重なる部分は、アイテムの背景に隠れて見えません。アイテムの背景を透明にすると、その部分にも線が描かれていました。

空いたセルの横に線を引かない

グリッドのセルが全部埋まっていないと、初期値では空いたセルの横にも線が引かれます。rule-visibility-items を between にすると、両側にアイテムがある部分だけに線を引きます。片側にアイテムがあれば引く around と、いつも引く all もあります。初期値の normal は、グリッドでは all と同じです。

css
.grid {
  rule-visibility-items: between;
}

3列×2行のグリッドに、アイテムを4つだけ入れて比べました。

アイテムが4つの3列2行のグリッドで、rule-visibility-items が normal のときは空いたセルの周りにも線があり、between のときはアイテムの間だけに線がある画面
rule-visibility-items の normal と between の違い

normal では、2行目の空いたセルの間にも縦の線が、空いたセルの上にも横の線が引かれました。between では、縦の線は1行目だけになり、横の線は1番と4番のアイテムの間だけに残りました。なお仕様では、このプロパティはグリッドと段組みのコンテナーに使うもので、フレックスは対象に入っていません。

線の端を短くする

rule-inset を指定すると、線の始まりと終わりを、指定した長さだけ内側に寄せられます。コンテナーの端まで線が届かないようにしたいときに使います。

css
.grid {
  rule-inset: 6px;
}

前の節の rule-break の画面は、この指定を付けたものです。線は、コンテナーの端や、線が止まる交点から 6px ずつ離れて描かれました。仕様では、端の側と交点の側で別の長さにする column-rule-inset-cap や column-rule-inset-junction などの細かいプロパティも用意されています。

線ごとに色を変える

色や太さは、カンマで区切って並べると、左の gap から順に当てはまります。列の数が決まっていないときは、repeat(auto, ...) で繰り返す部分を書けます。仕様の例にある書き方を、5列のグリッドで試しました。

css
.grid {
  column-rule: 2px solid;
  column-rule-color: #9aa5ab, repeat(auto, #00c8e8, #d85878), #9aa5ab;
}

4本の縦の線は、左から灰色、水色、ピンク、灰色になりました。最初と最後が灰色で、その間を水色とピンクの繰り返しで埋めています。

対応していないブラウザーへの備え

@mdn/browser-compat-data 8.1.8 では、row-rule や rule-break などのグリッドやフレックスの線のプロパティは、Chrome と Edge の 149 から対応となっています。Firefox と Safari(iOS 版も含む)は未対応です。

対応しているブラウザーにだけ線の指定を当てたいときは、@supports で分けられます。検証環境の Chromium では、CSS.supports("(row-rule: 1px solid)") は true を返しました。

css
@supports (row-rule: 1px solid) {
  .grid {
    column-rule: 1px solid #9aa5ab;
    row-rule: 1px solid #9aa5ab;
  }
}

​Posted by 86