CSSでflex、grid、column-countの罫線をGap Decorationsで描画する方法

CSSのborderだとflexやgridでは問題が生じる

CSSでレイアウトを作る際、要素同士のすき間を指定できるgapプロパティは便利です。

Webデザインによっては「すき間の真ん中に罫線を入れたい」というケースがあります。

従来は以下のようにborderプロパティを使用して罫線を追加していました。

※ 以下はflexでの例ですが、同じくgapが使えるgridやcolumn-countでも同様です。

CSS
@scope(.dashboard-container) {
  :scope {
    display: flex;
    max-width: 1200px;
    margin: 0 auto;
    background-color: #faf6f0;
    border-radius: 20px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
    overflow: hidden;
  }

  .column {
    padding: 20px;
  }

  .column-title {
    font-size: 14px;
    color: #8a827e;
    letter-spacing: 0.1em;
    margin-top: 0;
    margin-bottom: 24px;
    font-weight: 600;
  }

  .menu-column {
    flex: 1;
    min-width: 200px;
  }

  .menu-list {
    list-style: none;
    padding: 0;
    margin: 0;
  }

  .menu-item {
    position: relative;
    padding: 12px 16px 12px 32px;
    color: #2c2a29;
    font-size: 16px;
    border-radius: 10px;
    margin-bottom: 8px;
    cursor: pointer;
    transition: background-color 0.2s ease;

    &::before {
      content: "";
      position: absolute;
      left: 14px;
      top: 50%;
      transform: translateY(-50%);
      width: 6px;
      height: 6px;
      background-color: #8a827e;
      border-radius: 50%;
    }

    &.active {
      background-color: #ece7e1;
      font-weight: 500;

      &::before {
        background-color: #cc0000;
      }
    }
  }

  .content-column {
    flex: 1.5;
    border-left: 1px dashed #ded4c9;
    border-right: 1px solid #ded4c9;
  }

  .details-column {
    flex: 1.5;
  }

  .gradient-box {
    width: 100%;
    height: 120px;
    background: #8daaff;
    border-radius: 12px;
    margin-bottom: 24px;
  }

  .skeleton-wrapper {
    display: flex;
    flex-direction: column;
    gap: 14px;
  }

  .skeleton-line {
    height: 16px;
    background-color: #e6dfd5;
    border-radius: 8px;

    &.full { width: 100%; }
    &.long { width: 90%; }
    &.medium { width: 70%; }
    &.short { width: 50%; }
  }

  @media (width < 600px) {
    :scope {
      flex-direction: column;
    }

    .content-column {
      border-left: none;
      border-right: none;
      border-top: 1px dashed #ded4c9;
      border-bottom: 1px solid #ded4c9;
    }
  }
}
HTML
<div class="dashboard-container">
  <aside class="column menu-column">
    <h2 class="column-title">MENU</h2>
    <ul class="menu-list">
      <li class="menu-item active">Dashboard</li>
      <li class="menu-item">Analytics</li>
      <li class="menu-item">Reports</li>
      <li class="menu-item">Settings</li>
    </ul>
  </aside>

  <main class="column content-column">
    <h2 class="column-title">CONTENT</h2>
    <div class="skeleton-wrapper">
      <div class="skeleton-line full"></div>
      <div class="skeleton-line long"></div>
      <div class="skeleton-line medium"></div>
      <div class="skeleton-line long"></div>
      <div class="skeleton-line short"></div>
      <div class="skeleton-line long"></div>
    </div>
  </main>

  <section class="column details-column">
    <h2 class="column-title">DETAILS</h2>
    <div class="gradient-box"></div>
    <div class="skeleton-wrapper">
      <div class="skeleton-line medium"></div>
      <div class="skeleton-line long"></div>
      <div class="skeleton-line short"></div>
      <div class="skeleton-line full"></div>
    </div>
  </section>
</div>

CONTENT

DETAILS

レスポンシブWebデザインなので、幅が600px未満になると3カラムが1カラムになります。

このborderを使用して罫線を描画する方法には3つ問題があります。

1. マルチカラムレイアウトの変更だとborderの位置が変わる

前述のレイアウトは600px以上は3カラムですが、600px未満だと1カラムとなり、罫線は左右ではなく上下に表示されます。

そのため、600px未満(1カラム)のときは3カラムの左右のborderを消して、上下のborderを付けるという、罫線の指定箇所がわかりにくいコードになります。

CSS
@media (width < 600px) {
  :scope {
    flex-direction: column;
  }

  .content-column {
    border-left: none;
    border-right: none;
    border-top: 1px dashed #ded4c9;
    border-bottom: 1px dashed #ded4c9;
  }
}

2. カラムが非表示になるレイアウトの変更に弱い

真ん中の.content-columnの左右にborderを付けているため、ここが非表示になることがあるレイアウトの場合は、非表示になるとborderが消えてしまいます。

また、.content-columnの左右のborder-widthを変更すると、.content-columnの幅まで変わってしまう問題もあります。

DETAILS

3. borderはgapの間に罫線を描画できない

borderはgapの間に罫線を描画できないので、4行4列→6行3列→8行2列のように行数と列数が変則的に変化するレスポンシブWebデザインだと、borderで指定すると横の罫線を常に表示だけでもコードが複雑になってしまいます。

CSS Gap Decorationsでgapに罫線を描画する

CSS Gap Decorationsを使用すればgapに罫線を描画できるため、前述の1から3の問題を解消できます。

CSS Gap Decorationsはgapプロパティを追加している箇所に横の罫線を「row-rule」、縦の罫線を「column-rule」でborderの値のように指定するだけで実装できます。

CSS
:scope {
  display: flex;
  gap: 2px;
  row-rule: 2px dashed #000000;
  column-rule: 2px dashed #ded4c9;
  max-width: 1200px;
  margin: 0 auto;
  background-color: #faf6f0;
  border-radius: 20px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

CONTENT

DETAILS

CSS Gap Decorations Demoで表示を確認

CSS Gap Decorations Demoというページを使用すれば、CSS Gap Decorationsの表示を数値などを変更しながら確認できます。

CSS Gap Decorationsに慣れていない場合は、こちらで色々試せます。

CSS Gap Decorations Demo

まとめ

flex、grid、column-countのレイアウトにおいて、列と列の間に線を引きたい場合、row-ruleやcolumn-ruleを使わずにborderで描画するとレイアウトが破綻しやすいです。

2026年6月8日現在はChromeとEdgeではv149から利用できますが、Safariが未対応なのでSafariも対象であれば使用できません。

row-rule | Can I use... 

将来的にはborderではなくCSS Gap Decorationsでgapに罫線を描画するのが定石になるので覚えておくと良いでしょう。

カテゴリーcss