Here are four 2x2 tables, each having a single cell with a dark border. I'd like the dark border to stand out but unfortunately the adjoining light borders cover parts of the dark one in somewhat random ways. Is there a way to force a given cell's border not to be covered by adjoining ones?
I thought of using z-index
, but unfortunately it doesn't work.
table {
border-collapse: collapse;
margin:auto;
}
td {
padding: 10px;
}
td.dark {
border: 8px solid black;
}
td.light {
border: 8px solid lightgrey;
}
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>
<br>
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>
<br>
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>
<br>
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>
CodePudding user response:
See if this helps:
According to CSS
guidelines this is a defined behavior of border-collapse
.
If collapsing borders have the same style and width, but differ in color, then from most to least preferred: cell, row, row group, column, column group, table.
If come from same type of element, such as two rows then color is taken from borders that are the topmost and the leftmost.
table {
margin: auto;
}
td {
padding: 10px;
}
td.dark {
border: 8px solid black;
}
td.light {
border: 8px solid lightgrey;
}
<table>
<tr>
<td > a </td>
<td >b</td>
</tr>
<tr>
<td > a </td>
<td >b</td>
</tr>
</table>
<br>
<table>
<tr>
<td > a </td>
<td >b</td>
</tr>
<tr>
<td > a </td>
<td >b</td>
</tr>
</table>
<br>
<table>
<tr>
<td > a </td>
<td >b</td>
</tr>
<tr>
<td > a </td>
<td >b</td>
</tr>
</table>
<br>
<table>
<tr>
<td > a </td>
<td >b</td>
</tr>
<tr>
<td > a </td>
<td >b</td>
</tr>
</table>
OR you can have your own <td>
styling for each row <td>
element.
CodePudding user response:
The border-collapse mechanism gets in the way with this. The easiest solution is use absolute postioned ::before
or ::after
with either a border
or a box-shadow
to create the border.
The snippet shows both solutions with ::after
.
Beware:
- Because of the
border-collapse
, class.dark
will still need aborder
, but its color is irrelevant as it will be overlayed with our custom border - Either
::before
or::after
will overlay the content of the table cell making it hard (but not impossible) for the user to select the content.
snippet
body { display: flex; flex-flow: row wrap; gap: 2rem; justify-content: center }
table { border-collapse: collapse; margin:auto }
td { padding: 10px }
/* still need .dark border to trigger border collapse */
td.dark { border: 8px solid black } /* color is irrelevant */
td.light { border: 8px solid lightgrey }
/* Solutions */
/* ::before/::after will overlay the table cell, this may be unwanted behavior */
td:is(.s1,.s2)::after { background-color: CornSilk } /* to show overlay of ::after */
/* Just disable this rule, remove it or use 'transparent' as color value */
:is(.s1,.s2).dark { position: relative } /* new stacking context */
:is(.s1,.s2).dark::after { position: absolute; content: '' } /* relative to .dark */
/* Solution 1, using 'border' */
td.dark.s1::after {
inset: -8px; /* shorthand for top: -8px; right: -8px; bottom: -8px; left: -8px; */
border: 8px solid black
}
/* Solution 2, using 'box-shadow' */
td.dark.s2::after {
inset: 0; /* shorthand for top: 0; right: 0; bottom: 0; left: 0; */
box-shadow: 0 0 0 8px black
}
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>
<table>
<tr> <td > a </td> <td >b</td> </tr>
<tr> <td > a </td> <td >b</td> </tr>
</table>