This is an article triggered by a CSS selector. Honestly, I never thought I’d write an article about CSS selectors.

Just to be clear, this article is a review of the basics, nothing new or dark. If you already know the basics of CSS by heart, just Ctrl + W. If, like me, you’ve forgotten the basics, try reading on.

This is how it happened……

It was a dark and windy night, my colleagues and I happily added the shift, while playing pesticide in grief and anger. When the enemy hou yi shutdown the gap, I spent 20 seconds to tap a line of code, waiting for the page hot update, check the effect, perfect! Everything is fine!

But goose, just when I was about to be resurrected, the list also rolled to the end, oh my god!! There was a problem with the last Item style, but it was too late to be resurrected…… Later you can write a blog called “on the enemy fighting wild and our fighting wild”.

Although it only took me a minute to solve the problem in a different way, it took me almost an hour to fully understand the original problem.

Let me repeat the question for you:

Code that worked well before

<div class="list"> <div class="item"> I am the first item</div> <div class="item"> I am the second item</div> <div class="item"> I am the third item</div> <div class="item"> I am the fourth item</div> <div class="item"> I am the fifth item</div> </div>Copy the code
   .list {
                padding: 15px;
                background-color: #eee;
        }
        .item {
                margin-bottom: 15px;
                border-radius: 4px;
                background-color: #fff;
        }
        .item:last-child {
                margin-bottom: 50px;
        }Copy the code

Problematic code

<div class="list"> <div class="item"> I am the first item</div> <div class="item"> I am the second item</div> <div class="item"> I am the third item</div> <div class="item"> I am the fourth item</div> <div class="item"> I am the fifth item</div> <div class="dialog">...... </div> </div>Copy the code
   .list {
                padding: 15px;
                background-color: #eee;
        }
        .item {
                margin-bottom: 15px;
                border-radius: 4px;
                background-color: #fff;
        }
        .item:last-child {
                margin-bottom: 50px;
        }Copy the code

See what the problem is? If you see a problem at a glance and know exactly why, then congratulations, CSS is pretty solid. If you see a problem but aren’t sure why or haven’t found a problem at all, congratulations too, at least on reading this article.

:last-child

Common usage: element:last-child

Matches the last element child in the parent element and its child element.

Note: The element must be the last child of all elements under its parent to be valid.

Example:

<div class="list"> <div class="item"> I am the first item</div> <div class="item"> I am the second item</div> <div class="item"> I am the third item</div> <div class="box"> <div class="item"> Intersperse one box item</div> <div class="item"> Intersperse two boxes item</div> <div </div> <div class="item"> I am the fourth item</div> <div class="item"> I am the last item, </div> <div class="haha"> I am the last child </div> </div>Copy the code
   .list {
                padding: 15px;
                background-color: #eee;
        }
        .item {
                margin-bottom: 15px;
                border-radius: 4px;
                background-color: green;
        }
        .item:last-child {
                background-color: red;
        }
        .box {
                margin-left: 50px;
        }
        .haha {
                background-color: yellow;
        }Copy the code

The :first-child selector is used the same way

:last-of-type

Common usage: element:last-of-type

Matches the last element child under element’s parent and in its parent’s child.

Note: An element here only needs to be the last of all elements under its parent.

So if you look at this, you might think the following code:

<div class="list"> <div class="item"> I am the first item</div> <div class="item"> I am the second item</div> <div class="item"> I am the third item</div> <div class="box"> <div class="item"> Intersperse one box item</div> <div class="item"> Intersperse two boxes item</div> <div </div> <div class="item"> I am the fourth item</div> <div class="item"> I am the last item, </div> <div class="haha"> I am the last child </div> </div>Copy the code
   .list {
                padding: 15px;
                background-color: #eee;
        }
        .item {
                margin-bottom: 15px;
                border-radius: 4px;
                background-color: green;
        }
        .list .item:last-of-type {
                background-color: red;
        }
        .box {
                margin-left: 50px;
        }
        .haha {
                background-color: yellow;
        }Copy the code

The result would be this:

Big mistake!

The result is this:

Let’s change the div tag above class=”item” to a P tag, so the result is

Why change the tag type when you have the same HTML structure and CSS style?

I found two sentences in the specification document:

Pseudo-classes are allowed in all sequences of simple selectors contained in a selector. Pseudo-classes 
are allowed anywhere in sequences of simple selectors, after the leading type selector or universal 
selector (possibly omitted).
Copy the code
:first-of-type pseudo-class
Same as :nth-of-type(1). The :first-of-type pseudo-class represents an element that is the first sibling of its type.
Copy the code

It roughly means:

In a selector, all contain [simple selectors] (https://drafts.csswg.org/selectors-3/#simple-selectors) allows both the sequence of pseudo class. In a simple selector sequence, pseudo-classes can be placed anywhere, after the main type selector or (possibly omitted) after the wildcard selector.Copy the code
:first-of-type pseudo-class is equivalent to :nth-of-type(1). The :first-of-type pseudo-class represents the first sibling element of its type.Copy the code

I don’t know what you are, but I am, okay

The expression and understanding of words is really not an easy task, so I can only summarize it roughly, which means:

A pseudo-class such as :last-of-type can be followed by any simple selector, but in addition to matching the simple selector, it must also match the element type of the simple selector, namely the element label.Copy the code

Talk is cheap, show you the code:

<div class="list"> <p class="item"> I am the first P tag. Item </p> <p class="item"> I am the second P tag. Item </p> <p class="item"> I am the third P tag .item</p> <div class="box"> <p class="item"> Intersperse a box with p tags. Item </p> <p class="item"> Intersperse two boxes with P tags Item </p> </div> <p class="item"> I am the fourth p tag. Item </p> <p class="item"> I am the last P tag. Item </p> <div Class ="item"> I'm the last.item, but not the last div element </div> <div class="haha"> I'm the last div element </div> </div>Copy the code
   .list {
                padding: 15px;
                background-color: #eee;
        }
        .item {
                margin-bottom: 15px;
                border-radius: 4px;
                background-color: green;
        }
        .list .item:last-of-type {
                background-color: red;
        }
        .box {
                margin-left: 50px;
        }
        .haha {
                background-color: yellow;
        }Copy the code

conclusion

After writing this one, even I am a little dizzy, so you still have to take a look at the code, one by one, and then have a good experience.