CSS实现井字棋盘效果的N种方法【如何实现只有内部边框的table】

1,179 阅读3分钟

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

没有外部边框,只有内部边框的table,类似于井字棋盘(tic-tac-toe board)的效果。无意中看到 A Table With Borders Only On The Inside 介绍的实现方式,感觉还不错。本文也主要参考自此文,并结合评论和其他一些小改动,介绍可能的几种方式。

table的结构和内容如下:

<table>
    <!-- 如果考虑 th
    <tr>
        <th>Heading 1</th><th>Heading 2</th>
    </tr> -->
  <tr>
    <td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td>
  </tr>
  <tr>
    <td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td>
  </tr>
  <tr>
    <td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td>
  </tr>
  <tr>
    <td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td>
  </tr>
  <tr>
    <td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td><td>💁🏼</td>
  </tr>
</table>

给定 table 的基本CSS样式:

table{
    margin: 0 auto;
}
table td{
    padding: 3rem;
}

显示的井字棋盘效果:

方法一:直接移除不需要的边框

首先添加所有的边框,然后移除不需要的:

  1. 移除顶部的边框(对应于第一行的每个cell的顶部)
  2. 移除底部的边框(对应于最后一行的每个cell的顶部)
  3. 移除左侧的边框(对应于每一行的第一个cell的左侧)
  4. 移除右侧的边框(对应于每一行的最后一个cell的右侧)
table {
  border-collapse: collapse;
}
table td {
  border: 5px solid black; 
}
table tr:first-child td {
  border-top: 0;
}
table tr td:first-child {
  border-left: 0;
}
table tr:last-child td {
  border-bottom: 0;
}
table tr td:last-child {
  border-right: 0;
}

如果考虑 th 标题标签的话,还可以改为如下:

table {
  border-collapse: collapse;
}
table td,table th {
  border: 5px solid black; 
}
table tr:first-child th {
  border-top: 0;
}
table tr td:first-child,table tr th:first-child {
  border-left: 0;
}
table tr:last-child td {
  border-bottom: 0;
}
table tr td:last-child,table tr th:last-child {
  border-right: 0;
}

方法二:table 使用 border-style: hidden; 样式

直接使用如下的 css 小技巧,隐藏 table 的 border-style,只给 td 设置 border 即可。

table {
  border-collapse: collapse;
  border-style: hidden;
}
table td {
  border: 5px solid black;
}

MDN中的说明:

“在 table 、cell 边框折叠的情况下,隐藏值具有最高优先级:这意味着如果设置了任何其他冲突边框,它将不会显示。

“In case of table cell and border collapsing, the hidden value has the highest priority: it means that if any other conflicting border is set, it won’t be displayed.”

方法三:table 设置 border-color: transparent; 遮挡住 cell 中的 border 来实现【两种方法】

通过设置 border-color: transparent;,可以同样实现隐藏 table 四周的边框,本质应该是 transparent 的颜色,遮挡住 cell 的 border,实现 table 外部无边框。

  • table 设置 border-width 大于 td 的 border 宽度。
table {
    border-collapse: collapse;
    border: 6px solid transparent;
}

table td {
    border: 5px solid black;
}
  • table 设置 border-style 为 double 遮挡 td 的 border。
table {
    border-collapse: collapse;
    border: 5px double transparent;
}

table td {
    border: 5px solid black;
}

方法三:巧妙的使用相邻选择器实现

通过相邻选择器,巧妙的实现,只有存在相邻元素时才设置border,这样第一行、每一行第一个td,都可以做到不满足存在相邻元素的条件,即没有边框,实现井字棋效果。

table {
   border-collapse: collapse;
}
table td + td {
   border-left: 5px solid black;
}
table tr + tr td {
   border-top: 5px solid black;
}

方法四:css 的 not 属性

借助 not 属性,选出不是第一行或第一个td的元素,和上面相邻选择器一样。

table {
   border-collapse: collapse;
}
table td:not(:first-child) {
   border-left: 5px solid black;
}
table tr:not(:first-child) td {
   border-top: 5px solid black;
}

方法五:借助 :nth-child(an+b) 伪类

与上两个一样,通过 :nth-child(n+2) 伪类,找到从第二个 td 或 第二行 tr 开始的元素,并设置属性。

table {
   border-collapse: collapse;
}
table td:nth-child(n + 2) {
   border-left: 5px solid black;
}
table tr:nth-child(n + 2) > td {
   border-top: 5px solid black;
}

方法六:使用 rules 属性

rules 属性已经被遗弃,但大多数浏览器都保留着兼容支持(推荐使用 border 属性,实现相同效果)。

rules="all" 表示规则在行和列之间显示。

<table rules="all">
     <tr>
         <td>💁🏼</td>
         <td>💁🏼</td>
         <td>💁🏼</td>
         <td>💁🏼</td>
         <td>💁🏼</td>
     </tr>
     <!-- 省略 -->
     <tr>
         <td>💁🏼</td>
         <td>💁🏼</td>
         <td>💁🏼</td>
         <td>💁🏼</td>
         <td>💁🏼</td>
     </tr>
 </table>

rules="all" 效果如下:

如果使用 rules="rows",则显示为:

如果,想要控制边框的样式、边框宽度等,需要使用 css 的 border 相关属性。

如:

table td {
   border: 6px double black;
}