0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【CSS】疑似要素を使ってtbody間に余白を設ける方法

Posted at

はじめに

以下のように、<table>内で<tbody>をループして動的に生成するコードがあります。
データの切れ目がわかるように<tbody>間に余白を設けたいのですが、marginを指定しても効きません。

<script setup>
import { ref } from 'vue'

const userList = ref([
  { name: "John", age: 12 },
  { name: "Mike", age: 54 },
  { name: "Hanako", age: 23 }
])
</script>

<template>
  <table>
    <tbody v-for="(user, index) in userList" :key="index">
      <tr>
        <th>名前</th>
        <td>{{ user.name }}</td>
      </tr>
      <tr>
        <th>年齢</th>
        <td>{{ user.age }}</td>
      </tr>
    </tbody>
  </table>
</template>

<style scoped>

/* tbodyにmarginを指定しても効かない */
tbody {
  margin-bottom: 1rem;
}


/* 後略 */
</style>

image.png

二番目以降の<tbody>に疑似要素を指定することで上手くいったので、紹介します。

サンプルコードはVue.jsを用いていますが、本題では特にVue.jsに限定した機能は用いていません

疑似要素を用いた解決策

結論から示すと、以下で上手くいきます。

tbody:not(:first-of-type)::before {
  content: "";
  display: block;
  height: 1rem;
}

image.png

解説

  • :first-of-type
    • 兄弟要素の中の最初の1個
    • 今回は最初の1個以外の上に余白が欲しいので、:notを指定
  • ::before
    • 実際のDOMにはないが、指定した要素の前に疑似的に要素を作り出す
  • content: "";
    • 疑似要素を表示させるために必要。空で良い
  • display:block;
    • ::befoeinlineなので高さを指定できるようにblockに変更
  • height: 1rem;
    • これで疑似的な余白を作成(remでなくてもOKです)

サンプルコード全体

サンプルコード全文
<script setup>
import { ref } from 'vue'

const userList = ref([
  { name: "John", age: 12 },
  { name: "Mike", age: 54 },
  { name: "Hanako", age: 23 }
])
</script>

<template>
  <table>
    <tbody v-for="(user, index) in userList" :key="index">
      <tr>
        <th>名前</th>
        <td>{{ user.name }}</td>
      </tr>
      <tr>
        <th>年齢</th>
        <td>{{ user.age }}</td>
      </tr>
    </tbody>
  </table>
</template>

<style scoped>

tbody:not(:first-of-type)::before {
  content: "";
  display: block;
  height: 1rem;
}

/* tbodyにmarginを指定しても効かない */
/*
tbody {
  margin-bottom: 1rem;
}
*/

/* 以下は装飾 */
table {
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
  font-family: sans-serif;
  background-color: #fdfdfd;
  border-collapse: collapse;
}

th, td {
  padding: 0.5rem;
  vertical-align: top;
  border: 1px solid #ccc;
}

th {
  background-color: #f0f0f0;
  width: 30%;
}

td {
  background-color: #fff;
}

</style>

おわりに

<tbody>の下に<span>を作ったり色々試したのですが上手くいかず。なんとか解決して良かったです。

ちなみに、今回の本筋とは関係ないのですが、<tbody>は複数作成しても良いらしいです。

連続していれば、1 つの表の中に複数の <tbody>を使用することができます。これにより必要に応じて、巨大な表の行を複数のセクションに分割し、個別に整形することができます。

参考

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?