Check out a free preview of the full CSS In-Depth, v2 course:
The "Structural Selectors" Lesson is part of the full, CSS In-Depth, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Structural Selectors target elements based on relationship to other DOM nodes. We take a deeper dive into understanding first-child, last-child, only-child, and only-of-type.

Get Unlimited Access Now

Transcript from the "Structural Selectors" Lesson

[00:00:01]
>> Estelle Weyl: Okay, so then we have structural selectors. As you saw, I just said, li nth of type two, which caught the second list item. So let's see how you can actually do that. So an HTML page is built a certain way, it has a certain structure. There's the root element, which in HTML is the HTML element.

[00:00:26] But in XML, it might be the XML element. And in a shadow DOM element, it might be something else.
>> Estelle Weyl: You can have empty or blank. You can have nth-child, nth-last-child, first-child, last-child, only-child, nth-of-type, nth-last-of-type, first-of-type, last-of-type, only-of-type. So these structural selectors target elements based on their relationships to other elements within the document object model.

[00:00:55] When you update the page with JavaScript, or if someone's typing and you have a WYSIWYG or something, I don't know exactly how that would happen. Generally, it's people who are using JavaScript, it will update automatically if they add a paragraph. So far, I've been able to edit all of these features.

[00:01:17] I don't know what the class is on anything, but I know it's the fifth list item. Like you saw, I knew it was the second list item, might as well talk about it in a second. So I'm going to explain this by example. And I'm going to start with first, last, and only, of the of types.

[00:01:35] Because a lot of people don't understand this and it's really hard to explain. So, I'm gonna open up this in a new window, and we're gonna just play along. So everything is light blue, and it is underlined. Let's make this a little bit darker.
>> Estelle Weyl: Saturation lightness, make this 80.

[00:02:06] Nope, wrong way, a 10.
>> Estelle Weyl: I have no clue what I just did, let's reload the page. Well, okay, so that’s a prettier color. So,
>> Estelle Weyl: If I do first-of-type, everything just turned blue. Can anyone tell me why they think that everything just turned blue?
>> Speaker 2: The absence of a selector defaults to select everything?

[00:02:43]
>> Estelle Weyl: I selected the first of everything, and the first of everything is the body.
>> Estelle Weyl: Right, if I did first-child,
>> Estelle Weyl: The body is not the first-child.
>> Estelle Weyl: I have no clue why it covered everything.
>> Estelle Weyl: It shouldn't have covered everything.
>> Estelle Weyl: Last-child?
>> Estelle Weyl: Okay, body :last-child. Cuz there is a space there, so basically every last-child.

[00:03:30] So body is never the last. Yeah, there is a mistake in my HTML, because the body is the last-child. It should be of the HTML element. So there's a typo in here. I'm just gonna put body, and I'm gonna put a space, and I'm gonna do div:first-child. So that div is the first-child of its parent.

[00:03:59]
>> Estelle Weyl: Right?
>> Estelle Weyl: If I do just body, space, first-child. It's the first-child of every div, right? So it's basically saying within each element, if there's a child, match it. If I do last-child, it matches the last-child. So it's the last paragraph or the last h1, it doesn't matter.

[00:04:29] If I do last-of-type, why was this H1 highlighted? Because within its div, it is the last h1 of its type.
>> Estelle Weyl: So this is the last h1, this is the last h2, and this is the last paragraph within that div. And this matches because it's the last h1 and because it's the last div.

[00:05:02] So it's the last div in the,
>> Estelle Weyl: If I did last-child, so that's the difference between type and child. Type is actually any element, and child means any element. Type is a specific element, like paragraph or whatever. So there could be more than one last-of-types within a div.

[00:05:28] But last-child, it doesn't matter if it's a div or a paragraph or an h3, it's the last-child. The thing is these do not match classes. So if I do, li .foo last-child,
>> Estelle Weyl: Or foo last-child, if the last element does not have the class of foo, it will not match.

[00:05:55] If I do foo last-of-type, it will be any element that has the class of foo that is the last of its type. So basically, it has to be the last of its type that also has a class of foo. It's not, has a class of foo, then the last one, right?

[00:06:10] Does that make sense to people? It's a little confusing. No, it does not make sense. Unfortunately, I don't have, it's basically the last-child and the last-of-type, or the first-child, or when it's an of-type, it is matching the type, not the class. Then it matches the class. So if it's not the last-child, it doesn't matter what its class is.

[00:06:38] It's not gonna go up and say. So if I do .foo last-child, it has to be a child that also has to be the last child of its parent that also has a class of foo.
>> Estelle Weyl: So you can't,
>> Estelle Weyl: Paragraph foo last-of-type, will find the last paragraph.

[00:07:11] If it has the class of foo, it will match. If it doesn't have the class of foo, it won't match. But it won't go up and say this is the last paragraph that has a class of foo. That's not how it matches it. Does that make sense now?

[00:07:23] Okay.
>> Estelle Weyl: So,
>> Estelle Weyl: Only-of-type, so let's find out what is the only-of-type. Now if I did this, it matches the body. Because the body is the only of its type in this document. So we're gonna add body, put a space in. And so it matches this H1, but it doesn't match any of the paragraphs, because there's three paragraphs.

[00:07:54] It matches this H1, but it doesn't match either of these this h2's, because there's two h2's. So it's only-of-type, it's when there's only one of that type.
>> Estelle Weyl: So if you did p.foo only-of-type, there would be, it would only match a paragraph that has a class of foo, if it is the only paragraph within that parent.

[00:08:22] And it's based on the parent, it is not based on the grandparent. So it's not like, and the count restarts the next time, for every parent. You close out a div, it starts counting fresh again. So only-of-type, and then let's do only-child. So I could get rid of this body here, because the body should not be the only-child.

[00:08:47] But maybe, I don't know, okay. But since there's a typo somewhere in my thing, I'm gonna go this way. This is the only one where it only has one child. So an element that only has one child is the only thing it would match. If I did h,

[00:09:09]
>> Estelle Weyl: Okay, so this one only has one H1, right?
>> Estelle Weyl: If I do h1, it doesn't match this, because it's not the only child. But it is the only-of-type. It is the only h1 of that type. Generally making sense? Not 100%, but close enough? Just realize that when you hit a bug, that's what happening, right?

[00:09:32] So you get used to it after a while. And you might get used to it by the time we're done with this section, okay?