'What is the need for ::after when trying to highlight a table column in CSS?
So for highlighting rows in a table, we only need tr:hover and you have to set a background-color that has has an opacity of less than 1 to appear as if it's a highlight.
But for highlighting columns, why is there a need for ::after or ::before and the content part in this CSS? This code is currently working fine but I just want to understand what they're for.
table {
border: 1px solid black;
border-collapse: collapse; /*no borders*/
width: 75%;
margin-left: auto;
margin-right: auto;
font-family: "Gill Sans", sans-serif;
z-index: 1; /*table is over the highlight*/
overflow: hidden; /*cuts off the column highlight as to not overflow*/
}
tr:hover { /*highlights rows*/
background-color: rgba(195, 164, 255, 0.25);
z-index: -1;
}
td:hover::after { /*highlights columns*/
background-color: rgba(195, 164, 255, 0.25);
content: "";
height: 10000px;
left: 0;
position: absolute;
top: -5000px;
width: 100%;
z-index: -1;
}
Here's the HTML:
<body>
<h2>Timetable</h2>
<table>
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<tr>
<th>0900-1000</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Jesse</td>
</tr>
<tr>
<th>1000-1100</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Kaidan</td>
</tr>
</table>
</body>
Solution 1:[1]
::after and ::before are pseudo-elements. A pseudo-element is used to style specified parts of an element, and they're especified, as a rule, with double colons ::; this distinguishes pseudo-classes (with single colon :) from pseudo-elements (since CSS3).
Pseudo-classes let you apply a style to an element not only in relation to the content of the document tree, but also in relation to external factors like hover.
::before and ::after create a pseudo-element that is the first or the last child of the selected element, respectively. That means, that this pseudo-elements are contained by the element and thus don't apply to replaced elements.
The property content replaces an element with a generated value. For example, content could be an icon:
.test::after {
content: "?";
}
<div class='test'></div>
Or the quotes of a text:
.test::before {
content: open-quote;
color: lime;
}
.test::after {
content: close-quote;
color: blue;
}
<div class='test'>This is a quoted text with pseudo-elements</div>
Or even a linear gradient:
.test::after {
content: linear-gradient(#e66465, #9198e5);
}
<div class='test'></div>
When creating one of this after/before pseudo-elements, It's necessary to add the content property. So that's why you will sometimes see content: "". Look at this ::before with no content property:
.test::before {
width: 40px;
height: 40px;
background-color: red;
position: fixed;
}
<div class='test'></div>
Well, you probably didn't see anything. Now the same code, with content: "" property:
.test::before {
content: "";
width: 40px;
height: 40px;
background-color: red;
position: fixed;
}
<div class='test'></div>
Regarding to your question, there's no need to add ::after or ::before to highlight the columns. What you're doing in your ::after element is creating a very big "container" when user hovers over a td, so you're "highlighting" the entire page, not only the columns.
You could do:
Highlight al the td when on hover over tr:
table {
border: 1px solid black;
border-collapse: collapse;
/*no borders*/
width: 75%;
margin-left: auto;
margin-right: auto;
font-family: "Gill Sans", sans-serif;
z-index: 1;
/*table is over the highlight*/
overflow: hidden;
/*cuts off the column highlight as to not overflow*/
}
tr:hover {
/*highlights rows*/
background-color: rgba(195, 164, 255, 0.25);
z-index: -1;
}
tr:hover>td {
/*highlights columns*/
background-color: rgba(195, 164, 255, 0.9);
}
<table>
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<tr>
<th>0900-1000</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Jesse</td>
</tr>
<tr>
<th>1000-1100</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Kaidan</td>
</tr>
</table>
Highlight only the td when on hover:
table {
border: 1px solid black;
border-collapse: collapse;
/*no borders*/
width: 75%;
margin-left: auto;
margin-right: auto;
font-family: "Gill Sans", sans-serif;
z-index: 1;
/*table is over the highlight*/
overflow: hidden;
/*cuts off the column highlight as to not overflow*/
}
tr:hover {
/*highlights rows*/
background-color: rgba(195, 164, 255, 0.25);
z-index: -1;
}
td:hover {
/*highlights columns*/
background-color: rgba(195, 164, 255, 0.9);
}
<table>
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<tr>
<th>0900-1000</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Jesse</td>
</tr>
<tr>
<th>1000-1100</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Kaidan</td>
</tr>
</table>
If you want to do this whith pseudo-elements, this is what you should do:
Highlight al the td when on hover over tr with pseudo-elements:
table {
border: 1px solid black;
border-collapse: collapse;
/*no borders*/
width: 75%;
margin-left: auto;
margin-right: auto;
font-family: "Gill Sans", sans-serif;
z-index: 1;
/*table is over the highlight*/
overflow: hidden;
/*cuts off the column highlight as to not overflow*/
}
tr:hover {
/*highlights rows*/
background-color: rgba(195, 164, 255, 0.25);
z-index: -1;
}
tr:hover>td {
position:relative;
}
tr:hover>td::before {
/*highlights columns*/
background-color: rgba(195, 164, 255, 0.9);
content: "";
position:absolute;
top:0px;
left:0px;
width: 100%;
height: 100%;
z-index: -1;
}
<table>
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<tr>
<th>0900-1000</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Jesse</td>
</tr>
<tr>
<th>1000-1100</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Kaidan</td>
</tr>
</table>
Highlight only the td when on hover with pseudo-elements:
table {
border: 1px solid black;
border-collapse: collapse;
/*no borders*/
width: 75%;
margin-left: auto;
margin-right: auto;
font-family: "Gill Sans", sans-serif;
z-index: 1;
/*table is over the highlight*/
overflow: hidden;
/*cuts off the column highlight as to not overflow*/
}
tr:hover {
/*highlights rows*/
background-color: rgba(195, 164, 255, 0.25);
z-index: -1;
}
tr:hover>td {
position: relative;
}
td:hover::before {
/*highlights columns*/
background-color: rgba(195, 164, 255, 0.9);
content: "";
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: -1;
}
<table>
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<tr>
<th>0900-1000</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Jesse</td>
</tr>
<tr>
<th>1000-1100</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Kaidan</td>
</tr>
</table>
In both examples with pseudo-elements, notice the index: -1, so it's placed underneath. Also you need to add a position: relative to the td. ::before or ::after are position: absolute, so when top,left,right, or bottom of the pseudo-element, it is placed relatively to the td container and doesn't get off the "flow" of the container. See this example without position: relative on the td, where the pseudo-element is positioned to the top of the page and is actually the full width and height (similar to your code):
table {
border: 1px solid black;
border-collapse: collapse;
/*no borders*/
width: 75%;
margin-left: auto;
margin-right: auto;
font-family: "Gill Sans", sans-serif;
z-index: 1;
/*table is over the highlight*/
overflow: hidden;
/*cuts off the column highlight as to not overflow*/
}
tr:hover {
/*highlights rows*/
background-color: rgba(195, 164, 255, 0.25);
z-index: -1;
}
tr:hover>td::before {
/*highlights columns*/
background-color: rgba(195, 164, 255, 0.9);
content: "";
position:absolute;
top:0px;
left:0px;
width: 100%;
height: 100%;
z-index: -1;
}
<table>
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<tr>
<th>0900-1000</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Jesse</td>
</tr>
<tr>
<th>1000-1100</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Jia</td>
<td>Kaidan</td>
</tr>
</table>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
