Nine years on, and this is still giving people a headache!
This method works from IE11+ and all other major browsers without having to create an empty row just for a border:
table {
width: 100%;
border-collapse: collapse;
position: relative; /* Required #1 */
}
td {
height: 60px;
text-align: center;
background: #EEE;
border: 1px solid #CCC;
}
tr:nth-child(even) td {
background: #DDD;
}
td:nth-child(1) {
padding: 0; /* Required #2 */
width: 30%;
}
/* Required #3 */
td:nth-child(1)::after {
display: block;
content: ' ';
width: 100%;
margin-bottom: -1px;
position: absolute;
border-bottom: 2px dashed;
}
td:nth-child(2) {
width: 50%;
}
td:nth-child(3) {
width: 20%;
}
/* Required #4 */
span {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}
<table>
<tr>
<td><span>Row 1, Cell 1</span></td>
<td>Row 1, Cell 2</td>
<td>Row 1, Cell 3</td>
</tr>
<tr>
<td><span>Row 2, Cell 1</span></td>
<td>Row 2, Cell 2</td>
<td>Row 2, Cell 3</td>
</tr>
<tr>
<td><span>Row 3, Cell 1</span></td>
<td>Row 3, Cell 2</td>
<td>Row 3, Cell 3</td>
</tr>
</table>
This works because the border is attached to a psuedo element with a position of absolute that takes its width from the table, rather than being bind purely to the cell.
There are four main areas to be aware of (commented in the CSS):
- The table has
position: relative
so the line adapts to that width; unfortunately you can't apply it on a table row.
- The first cell of each row should not have any padding, otherwise the line may not be flush with the bottom of the row; if you require padding, then this can be defined in #4.
- This creates the line itself; it's basically a pseudo element of
position: absolute
, with a width: 100%
to stretch across the table. I have also added a negative margin half the size of the border so it sits nicely in between the two rows. You may also notice that there are no top/left/right/bottom properties; this is so that the element remains where it was before the absolute positioning.
- This is the element inside the first cell of each row; the main thing is to add
height: 100%
so it forces the line created at #3 to be at the bottom of the row. After that is considered, you can style it however you like.
The standard border inside the td
is not required; I've included that to demonstrate where the cells are.