両端のborderがないテーブルをgridでスタイリングしようとすると、 :not(:first-of-type) をただ使うだけではうまくいかない。

gridにまかせて以下のようにすると、 :not(:first-of-type) は最初のcellにしかかかってくれない。

また、HTMLのマークアップとしても行が表現されておらずあまりきれいな状態とはいえない。

<div class="table">
  <div class="cell">One</div>
  <div class="cell">Two</div>
  <div class="cell">Three</div>
  <div class="cell">Four</div>
  <div class="cell">Five</div>
  <div class="cell">Six</div>
  <div class="cell">Seven</div>
  <div class="cell">Eight</div>
  <div class="cell">Nine</div>
</div>
.table {
  display: grid;
  grid-template-columns: repeat(3, auto);
  margin: 32px;
  border-top: solid 1px black;
}

.cell {
  padding: 4px;
  text-align: center;
  border-bottom: solid 1px black;
}

.cell:not(:first-of-type) {
  border-left: solid 1px black;
}

failure1

かといって、以下のようにただdivで囲うだけではgridレイアウト側の制約がかかり、デザインが崩れてしまう。

<div class="table">
  <div class="row">
    <div class="cell">One</div>
    <div class="cell">Two</div>
    <div class="cell">Three</div>
  </div>
  <div class="row">
    <div class="cell">Four</div>
    <div class="cell">Five</div>
    <div class="cell">Six</div>
  </div>
  <div class="row">
    <div class="cell">Seven</div>
    <div class="cell">Eight</div>
    <div class="cell">Nine</div>
  </div>
</div>

failure2

この問題を解決するために調べたところ display: contents を使うとうまく動くようだった。

gridが登場したことで発生した、マークアップの構造化の問題を解決するためのキーワード値なので、おそらくこのやり方が仕様にも則っている方法だと思われる。

.table {
  display: grid;
  grid-template-columns: repeat(3, auto);
  margin: 32px;
  border-top: solid 1px black;
}

.row {
  display: contents;
}

.cell {
  padding: 4px;
  text-align: center;
  border-bottom: solid 1px black;
}

.cell:not(:first-of-type) {
  border-left: solid 1px black;
}

success

参考サイト Link to heading

https://coliss.com/articles/build-websites/operation/work/how-to-work-display-contents.html