2.3 Combining :has and :not
In this lesson, you will learn how to make the
:not selectors even more powerful by combining them.
1.Welcome2 lessons, 06:09
2.Level 4 Selectors6 lessons, 40:47
3.Styling Tables2 lessons, 12:56
4.Layout Options3 lessons, 24:50
5.Other Options5 lessons, 45:31
6.Conclusion1 lesson, 02:42
2.3 Combining :has and :not
Hello and welcome back to the CSS of the future. In this lesson you're going to learn about what I like to call relational negation. Which basically just means that we're going to combine the relational, or has pseudo-class, and the negation. Or not pseudo-class. So we're going to look at has nots and not has. And there is a difference. The order definitely matters when you're going to combine these two elements. So, if you look in your project files folder in the selectors folder, you'll find a file called hasnot-start.html. That's the file we're going to start with in this lesson. And if we look at this file in Chrome we see a few different sections here. We have an H1 at the top and then we have a couple of sections, one with a heading tag. One with three different levels of heading tags and then one with just a paragraph. So let's take a look at the html itself in the hasnotstart.html file. And here we can see those sections. So again, our first section has an H3 in it. Our second section has an H3, H4 and an H5. And then our third section just has a paragraph. So let's say that we wanted to start off by selecting all sections that don't have any heading tags in it whatsoever. Now when you hear that, if you haven't had much expirenence with this idea yet, then you might be tempted to do something like this, section:not and then inside parentheses put a list of h tags here. So h1 all the way through h6. But if you think about it this isn't gonna work. Remember this not pseudoclass or negation pseudoclass is not looking at child elements or child sectors. Instead it's looking at this selector right here. So we could put something like this, not.active. And this would say we're looking for a section that does not have the class active applied to it. But with the h1 through h6 tags here, this isn't going to work because these h1 through h6 tags, those heading tags are actually children of those sections. And the negation pseudoclass here does not consider or does not take into account child elements of the main selector. The negation pseudo class is looking at the selector itself and making sure it doesn't meet certain criteria. The has selector on the other hand does look at the child elements. So this particular idea isn't gonna work, but we're looking for sections that do not have any heading tags. So one thing we can do inside the parenthesis here is we can use the has pseudo-selector, or pseudo-class. So, if we put h1 through h6 inside parentheses again, and then use them inside the has pseudo-class, then you can take this part separately and think about what this is saying. We're looking for a element that has one of these as its children or any of these as its children. So any element that has any headings in it at all this particular portion of the selector is going to select. And if we have that inside the nut, then we're going to make sure that our section does not have any of those items inside it. So once we do that, we can change our background color or set any styles we want for that. So set background color to red, for example. So any section that does not have any of these elements in it is gonna have a red background color. The problem is, once again, if we save this. Let's go to File, Save As and we'll save this as hasnot.html. And then we'll jump into Chrome. And I'll just get rid of the hyphen start, and hit Enter. The problem is, if we close this, that our paragraph section down here is not selected. Because that particular selector, or combination of selectors is not yet supported. However, we do have a little jquery that can simulate that for us. If we scroll back up to the top, we can see this first section here, and if I just comment out line 12 here, we can see something that looks very similar. Section not has and then a list of heading tags, and then we're setting the CSS background color to red. So this will achieve the same effect that we're going for here. But this is achieving it in j query. And you can see we're linking to j query up here near the top. So if I were to save that, and refresh our page then we can see what it looks like. It's selecting the only item that does not have any heading tags as children. Good start. Well let's see what happens if we flip those around and do a has not. This is gonna look a little bit different. This is gonna achieve some different results. So the way this would look is we would say, section:has(), and then inside parentheses here we would use the :not(). And I'm going to put the same list of elements here, h1 through h6. Now, you might be tempted to say that this would achieve the same result. But if you really think about what this is doing, you can see that it is not. So again the has pseudo class is looking for children. So, we're looking for a section that has a certain type of child. So it's looking for a section that has a child, that has at least one child that does not match any of these elements. In other words, we're looking for a section that has at least one element in it that is not a heading tag. And let's set that background color to red as well. So we'll save that and this again is not gonna work if we comment out this line of j query here, save our file, and refresh. It's not working. But we have another piece of j query down here on line 15, where if we un-comment that and save it and refresh, we can see that the top and bottom are both highlighted. So again the items being selected here are sections that contain at least one element that is not a heading tag. And those are the items that are being selected. So the bottom is being selected and the top is being selected. But you might be asking what is in this top one that's not a heading tag. Well if we jump back into our code and look at our h1 our section here, our first section, you'll see it has a Div in it. So it has at least one element that's not a heading tag. If we were to get rid of this to the point where we only had a heading tag in here, then it no longer matches that criteria. There's no longer an element in here that's not a heading tag, so if we save that, and refresh. That first one has gone away, and, again, the difference is we're looking for only one or at least one item or element that is not a heading tag. And, as it stands right now, the only section here that contains an item that's not a heading tag is this bottom one. Now, if we go to that bottom one and add a heading tag, it's still gonna work. So if we add an h3 tag here, let's just say heading. Save that and refresh. It still works because it still contains at least one item, this paragraph for example, that is not a heading tag. So, as you can see, the order definitely matters. It matters, it's going to matter, I should say, in the CSS selector. Just like it currently matters in the j query selector. So the order of the not has and the has not definitely has a difference and I've added some comments to the code to help you understand what the difference is between those two. But basically this first one Is basically looking for any section that doesn't have any heading tags in it at all. The second one, it doesn't really care if your sections have a heading in it, but it's looking for a section that has at least one item that's not a heading tag. And that's the difference between not has, and has not. Thank you for watching, and I'll see you in the next lesson.