Can anyone tell me why the second row of my table doesn't get a grey background?
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.phone td {background:blue; color:white;}
.phone:first-of-type td {background:grey;}
</style>
</head>
<body>
<table>
<tbody>
<tr class="email"><td>Row</td></tr>
<tr class="phone"><td>Row</td></tr>
<tr class="phone"><td>Row</td></tr>
</tbody>
</table>
</body>
</html>
:not() The :not() CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class. /* Selects any element that is NOT a paragraph */ :not(p) { color: blue; }
The :nth-of-type selector allows you select one or more elements based on their source order, according to a formula. It is defined in the CSS Selectors Level 3 spec as a “structural pseudo-class”, meaning it is used to style content based on its relationship with parent and sibling elements.
Adjacent Sibling Selector (+) The adjacent sibling selector is used to select an element that is directly after another specific element. Sibling elements must have the same parent element, and "adjacent" means "immediately following".
The first-of-type
selectors work on the tags or elements and not on the classes or ids. So in your case the below selector would style the <td>
children of the first element of every type which also happens to have the class='phone'
.
.phone:first-of-type td {background:grey;}
In your code none of the elements which are the first of it's type have the class='phone'
. The first tr
has class='email'
.
If your first tr
had the class='phone'
then the style would get applied as seen in the below snippet.
.phone td {
background: blue;
color: white;
}
.phone:first-of-type td {
background: grey;
}
<table>
<tr class="email"> <!-- will not be styled because it doesn't have phone class-->
<td>Row</td>
</tr>
<tr class="phone"> <!-- will not be styled either because it is not first tr -->
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
</table>
<table>
<tr class="phone"> <!-- will be styled because it is first tr and has phone class-->
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
</table>
For your case, you can try the below CSS. This sets the background
of all td
whose parent has the class='phone'
to grey and then overrides it for all its siblings to blue.
You can use either the adjacent sibling selector or the general sibling selector depending on your choice. General Sibling selector is the best.
Note that the adjacent sibling selector won't work complex cases where you have elements with other classes in between elements with
class='phone'
.
.phone td {background:grey; color:white;}
.phone ~ .phone td { background: blue;}
.phone td {
background: grey;
color: white;
}
.phone ~ .phone td {
background: blue;
}
/* Adding below just to show the difference between the two selectors */
.phone + .phone td {
color: gold;
}
<table>
<tr class="email">
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
<tr class="email">
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
</table>
<hr>
<table>
<tr class="phone">
<td>Row</td>
</tr>
<tr class="email">
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
<tr class="phone">
<td>Row</td>
</tr>
</table>
:first-of-type
looks for elements (in the siblings list), not complex selectors. Here, neither of your .phone
elements are the first sibling -- .email
is.
As far as i know, there is no way to do this in pure CSS without changing your HTML layout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With