- I hope that everyone had a great time going through the challenge on writing efficient selectors, and that I didn't confuse you too much. Now I'm gonna go through my finished files, and show you how I completed the steps, and as I do, compare your styles to mine, and how my approach to writing efficient selectors might be a little different from yours. And again, there's nothing really wrong with that, unless your approach leads to less efficient selectors. Okay, so currently in the browser I'm looking at the efficient.htm, which is still found in the 07_04 directory, only the files I'm gonna be working with now, are found in the Finished FIles subdirectory.
Now the only visual difference between the styles that I wrote and the styles that we had before, is each one of these sections now has a little order that separates each one of them, which is nice, except for the last one. And my quote now has quotation marks around it, which makes it look like a little bit nicer of a quote. But everything else really had to deal with making the selectors a little bit more efficient, so there's no real visual change to any other areas of my page. Now I'm gonna go into my code editor here, and what I wanna do is just go through each of the steps, and I'm just gonna show you, and talk a little bit, about how I approached that particular problem.
Now the first was to find overly repetitious styles, and to group them when possible. Now if I go back to the original CSS file, this is the starting CSS file, I notice that I have all these heading styles, h1, h2, h3, h4, h5, h6, and then I have paragraph selector. And they're all basically doing the same thing. Setting a font size, setting a color, and most of them are repetitious. So if I go into my finished file, and scroll down, you can see that those headings, I grouped them together, and eliminated some of the selectors that I didn't need.
So that's gonna be less overall code, which is gonna be quicker to parse, and more efficient overall. The second thing was I wanted to use inheritance to set a default font stack to Verdana, Geneva, and sans serif, and then set the default size of the font to 100% of the user agent's. And I wanted that to propagate down, so that I didn't have to set it in each of the individual elements. The quickest and easiest way to do that is with the body tag, and that's exactly what I did. You'll notice that in the body selector I set font-family to that particular stack, and I set font-size to 100.
When you do that, it's gonna inherit into every other element on the page. So all we have to do in this instance is, if that's not what we want, we simply have to override it with individual selectors, which is a lot more efficient than having to set this for every element on the page. Our next step was the border that separates the sections inside the main article. Now I mentioned the fact that you'd really have to understand the structure of the code, in order to write the two selectors that we need.
Now, I'm just gonna, for a second here, go back into the HTML, and show you, that for each one of these, they were in a section, and at the very end of the section there was always a figure. Now, the tricky thing here is that some of the sections had two figures in them, and some only had one. So if you wrote a selector that basically said that, hey, after a figure, apply a border, well that wasn't really gonna work because some of them have two figures and some of them have one. So let me slip back over to the CSS, and I'll show you how I did it.
So right around line 86 here, my first selector is figure:last-of-type, so what that does for me, is it says, hey, when you find a figure, and it's the last of its type within its parent, I want you to apply a border. And that's gonna ignore those first figures, and only apply it after the last one. It's also gonna work for the sections that only have one figure in it as well, because it is gonna be the last figure inside that section, even though it's the only figure. So that selector works really well.
the tricky part was making sure that you didn't have a border after the very last one. That could have been a little bit more tricky. So what I did there was, I targeted the last section in the article, by using last-of-type, and then targeted the last figure in that section by using figure:last-of-type. Now this selector is not one of the more efficient selectors that I've ever written. Section:last-of-type, and then a space, and then figure:last-of-type. That's really specific, and that's not a very efficient selector at all in terms of performance.
But remember what we talked about earlier, performance isn't the only driving factor. In this case, it meets the need of exactly what I want, and it allows me to do that without modifying the semantics of the page, meaning, applying a class to that last figure. A lot of people would have done it that way, just went ahead and applied a class to the last one that says "no border" or something like that. And that would take off the border. The problem with that is if you're using some type of automation software, like a content management system to generate the page, there might be no way for you to manually apply that class, which could make that a lot more difficult.
This selector, while not terribly efficient in terms of performance, is incredibly efficient in terms of structure. Now the next step was to modularize the selectors for the article and the aside, so that the selectors aren't tied to specific structures, and can be reused on other pages. Now if I go into the starting CSS, and scroll down, you can see that I have a lot of selectors that are prefaced by article, or down towards the bottom, by aside. And I really didn't want them tied to that particular structure because while this page is using an article and an aside for the two columns, what if another page is using a section and an article, or a div and an aside, that sort of thing.
So by going into the html, I can see that my initial article has a class of summary, and the aside has a class of resources. And by using those class attributes I can abstract the styles away from that particular structure. So going back into my finish styles, if I scroll down through this, I can see that anywhere where I have to absolutely reference the summary itself, I do that using class, and the same thing for resources, and when I'm identifying content inside the resources as well.
So that is not dependent upon the structure, it's just using the classes, and it sort of abstracts it away from that. Now I also wanted to place quotation marks around the quoted text. I mentioned in the challenge exercise there that we'd be using generated content, and even sort of told you how these hex values were gonna be used. To see how those turned out I'm gonna scroll down to find our blockquote styling, and I've added two rules below that. And I'm targeting the span, now if some of you guys targeted the class, that's fine. And the class actually might be a little bit more efficient in terms of pattern matching by the browser.
But you'll notice I'm doing before, and then for the content, I'm placing in the hex value, and I'm using after, and for the content, I'm placing in the hex value. I didn't do any other styling, if you wanted to, that's fine. But I let them inherit the styling of the rest of the quotes, so they would really fit well with it. And then finally, the last thing I wanted you to do, was find any unnecessarily long selectors, and then shorten them so that they're not tied to specific depths, and are resolved a little bit faster. Just to jog your memory, going back to the original starter styles, if I scroll down through this, you can see that starting right after the link styling, I have selectors that are sort of unnecessarily long.
article figure pre, article figure pre.wrong, article figure pre.correct, it is targeting those elements, and it's being very specific, but it's also a lot slower in terms of browser performance, because it's having to match each of these elements. Where I really don't need that level of specificity. So if I go into the finished file, and I scroll down into those styles after my link styling, you can see, that I've dramatically shortened them. In this case, I'm just styling the pre.
I'm using the classes wrong and correct. In the cases where I do have a descendant selector, it's only two levels deep. I really try whenever I write my descendant selectors, to stay two levels deep and not go three. Sometimes for specificity's purposes, you sort of have to go three deep, but if you go any more than that, really start looking at how that selector is written, and maybe think of alternate ways to write it. Because you've really become very inefficient. So if I scroll down and through my selectors, I can see that any time I'm using descendant selectors, I'm really only about two levels deep.
So that was one of the ways that I went through, and made the styles a lot more efficient. Now if your styles are dramatically different from mine, take some time to think about why our approaches are so different. Now in some cases, your personal preferences are gonna play a role in that, while in others, you might want to use a specific approach that's dictated by the type of site that you're currently working on. Your styles don't have to match mine. What really matters is that you've written efficient styles that follow a clear strategy.
- Targeting classes and IDs
- Working with group selectors
- Targeting element attributes
- String matching
- Targeting links with pseudo-class selectors
- Targeting child elements and empty elements
- Targeting parent, child, and sibling elements
- Matching patterns
- Writing efficient selectors