如何在 table 行中对 tds 进行分组和设置样式?

How to group and style tds in a table row?

我正在尝试“分组”一组单元格/<td> 行中的<tr> 元素/<table> 中的<tr> 以便我可以对它们应用样式。下面的代码实现了我有点想做的事情,但它有一些限制:

/* Styles I'm having issues with */
.row td:not(:first-child) {
  background-color: lightgray;
  /* potentially a box-shadow */
}

.row td:nth-child(2) {
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
}

.row td:last-child {
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
}


/* Base styles for table to make it look decent */
table {
  margin: 0 auto;
  font-size: 20px;
  border-collapse: separate;
  border-spacing: 0 1em; 
}
table td {
  padding: 10px;
}
<table>
  <thead>
    <th>A</th>
    <th>B</th>
    <th>C</th>
    <th>D</th>
  </thead>
  <tbody>
    <tr class="row">
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr class="row">
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
    </tr>
  </tbody>
</table>

以上实现了我想要的视觉效果(减去每组灰色框周围的框阴影),其中每行的最后 3 个单元格被分组。但它有一些问题:

  1. 这种对最后三个单元格进行样式设置的解决方案涉及到我必须更改每个 <td> 的样式,这意味着样式设置很乏味(例如:我必须设置边框半径的样式每个角,并且不能为组指定一个简单的 border-radius 样式。

  2. 以这种方式设置 table 使得很难在每个单元格之间添加单元格间距(因为它添加了白色间隙)或添加框阴影围绕着对最后三个单元格进行分组的整个灰色框(使用上述方法,每个框阴影都需要应用于每个 <td>,这使得每个单元格显示为单独的 eg, whereas the desired look for the box-shadow for the group would be like this)。

有没有一种方法可以将 <td> 组合在一起,以便我可以将我的样式整体应用于组,而不是单独的 <td>?理想情况下,我可以做类似的事情:

<tr class="row">
  <td>1</td>
  <div class="row-group">
    <td>2</td>
    <td>3</td>
    <td>4</td>
  </div>
</tr>

然后我会将我的 border-radius: 10pxbackground-color: lightgray 以及 box-shadow 样式应用到 .row-group class。但是 HTML 规范不允许 <div>s 在 <tr>s 之内,所以上面的方法不起作用。我也尝试查看 <colgroup><col> 标签,但这些标签似乎对每列应用样式,并且对我对每行的一组单元格应用样式帮助不大。我唯一的另一个想法是使用子 table,但我想知道是否有更简单的方法可以让我“分组”并共同设置这些 <td> 的样式,也许我是遗漏了一些东西,可以用 <col>s?

来完成

张贴我的评论作为你告诉我的答案。

基本上我们将 :after 伪元素与您正在寻找的样式(圆形灰色框)一起使用,并将其定位为 absolute 在您的 TD's 下。它将占用除 first:child 宽度之外的所有行宽。

/* Styles I'm having issues with */
tbody tr {position:relative;}
tbody tr:after {
  content:'';
  display:block;
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:30px; /*First child width*/
  margin:auto;
  background-color: lightgray;
  border-radius:10px;
}
td {position:relative; z-index:1}
/* Base styles for table to make it look decent */
table {
  margin: 0 auto;
  font-size: 20px;
  border-collapse: separate;
  border-spacing: 0 1em; 
}
table td {
  padding: 10px;
}
<table>
  <thead>
    <th>A</th>
    <th>B</th>
    <th>C</th>
    <th>D</th>
  </thead>
  <tbody>
    <tr class="row">
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr class="row">
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
    </tr>
  </tbody>
</table>

已编辑:相同的代码段,但添加了一个 jquery 脚本,以防您的 first-child 具有动态宽度:

$(document).ready(function(){
    var tdWidth = $("td:first-child").outerWidth();
  $( "<style>tbody tr:after { left: " + tdWidth + "px; }</style>" ).appendTo( "head" )
});
/* Styles I'm having issues with */
tbody tr {position:relative;}
tbody tr:after {
  content:'';
  display:block;
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  margin:auto;
  background-color: lightgray;
  border-radius:10px;
}
td {position:relative; z-index:1}
/* Base styles for table to make it look decent */
table {
  margin: 0 auto;
  font-size: 20px;
  border-collapse: separate;
  border-spacing: 0 1em; 
}
table td {
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
  <thead>
    <th>A</th>
    <th>B</th>
    <th>C</th>
    <th>D</th>
  </thead>
  <tbody>
    <tr class="row">
      <td>1111111</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr class="row">
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
    </tr>
  </tbody>
</table>