Reputation: 1391
I'm trying to "group" a set of cells/<td>
elements within a row/<tr>
in a <table>
so that I can apply styles to them. The below code achieves what I somewhat want to do, but it has some limitations:
/* 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>
The above achives the visual effect I want (minus a box-shadow surrounding the grey box for each group), where the last 3 cells of each row are grouped. But it has a few issues:
This solution of stylying the last three cells involves me having to change the style of each <td>
, which means that styling is tedious (eg: I have to style the border radius for each corner, and can't specify just one simple border-radius
style for the group).
Stylying the table in this way makes it hard to do things like add cell-spacing between each cell (as it adds a white gap), or to add a box-shadow that surrounds the entire grey box that groups the last three cells (with the above approach, each box-shadow would need to be applied to each <td>
, which makes each cell appear as seperate, eg, whereas the desired look for the box-shadow for the group would be like this).
Is there a way that I can group <td>
s together so that I can apply my styles hollistically to the group, and not to the individual <td>
s? Ideally, I would be able to do something like:
<tr class="row">
<td>1</td>
<div class="row-group">
<td>2</td>
<td>3</td>
<td>4</td>
</div>
</tr>
And then I would apply my border-radius: 10px
and background-color: lightgray
and box-shadow
stylying to the .row-group
class. But the HTML spec doesn't allow <div>
s within <tr>
s and so the above doesn't work. I have also tried looking into <colgroup>
and <col>
tags, but these seem to apply styles per-column, and don't help me much with applying styles to a group of cells per-row. My only other thought is to use a sub-table, but I'm wondering if there is an easier way that will allow my to "group" and styles these <td>
s collectively, maybe I'm missing something and it can be done with <col>
s?
Upvotes: 1
Views: 1258
Reputation: 9012
Posting my comment as an answer as You told me.
Basically we use the :after
pseudoelement with the styles You are looking for (rounded grey box) and position it as absolute
under your TD's
. It will take all row width except the first:child
width.
/* 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>
Edited: same snippet but adding a jquery
script in case your first-child
has a dynamic width:
$(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>
Upvotes: 1