Refactoring the CSS Code to Use More Specific Selectors
In this lesson, we're going to perform some refactoring. If you've never heard of what refactoring is, what it essentially means is when you have code that can be improved.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
  • Complete the Exercise
Video locked
This video is viewable to users with a free Dev Camp account

Many times it revolves around making sure that you conform to best practices, and so that's what we're going to do here. We, for the most part, have been following along with all the best practices that you'd usually want to use, but there are a few little items that I purposefully left off.

The main reason for that is because it's really important in understanding how CSS works. I wanted to start off with more of a simple implementation, and then show you why you will want to become a little bit more specific.

Let's switch back to the code, and I'm going to close this off to the side. Now, do you see right here how we have some generic styles here? So, navigation-wrapper, that's pretty specific but left-column.

large

Let's imagine that you have a scenario where you want to use the name left-column later on, but you may want it on a different page. You may want to use it on the About page and you want to use this left-column and you may not want to use Flexbox. You may want to use CSS grid for it.

Well, with what we have right here, that would be a problem. We would have left-column and then either this set of styles would be applied for that other page or we would implement some other styles later on that would override these. Then that would cause an issue with the navbar.

What we're going to do is we're going to make our system a little bit more specific. We know that our left-column needs to have these styles when it's inside of the navigation-wrapper, so what we're going to do is we're going to use inheritance. We've shown how to do this right here on line 32.

We're essentially going to be doing the same thing. So here, I can say .navigation-wrapper and then we want to say .navigation-wrapper > .left-column. So inside of here, whenever you find a left-column we want you to apply these styles.

What this means is that if we ever want to use a left-column in some other part of the project, it's perfectly fine because it's not going to be nested inside of the navigation-wrapper. That's what we're doing there.

Same thing for this icon. We don't want to use a margin-right: 15px for every icon on the entire site. We simultaneously don't want to use a font-size, a 2em, across the board either.

We can look at the HTML here and so we can see that that icon here specifically is the icon that is inside of the left-column. That's where we want to apply those styles. We also have our little navigation-wrapper here.

large

Let's play around with this and see exactly how the inheritance works. If I say .navigation-wrapper > .icon, let's see if these same styles get applied, and we'll do the same thing here. So, say: navigation-wrapper, hit save, and let's see if that works.

styles.css

.navigation-wrapper > .icon {
    margin-right: 15px;
}

.navigation-wrapper > .icon i {
    font-size: 2em;
}

If I come here and hit refresh, you can see that those styles disappear.

large

So, why is that exactly? Well, it's because of how this little > symbol works. This does not work on a deeply nested level. Instead, what it says is you first need to become more specific. For the navigation-wrapper, if you want to grab this icon, it needs to know that chain of events.

It needs to know for the navigation-wrapper what other classes connect to icon. In this specific case, if you look at HTML, we have the navigation-wrapper, then we have the left-column, then we have the icon.

We have a couple different options. We could just do this. We could say .navigation-wrapper > .left-column > .icon, and then do the same thing here.

styles.css

.navigation-wrapper > .left-column > .icon {
    margin-right: 15px;
}

.navigation-wrapper > .left-column > .icon i {
    font-size: 2em;
}

Hit save, hit refresh, and now you can see that that is back to working.

large

In this specific scenario, it's up to you. If you're making a very large application, you do want to be specific like this. Imagine a scenario where you leave off the navigation-wrapper, so you just do it like this .left-column > .icon. This will still technically work for this one-use-case.

You can see nothing changes here, but the one issue is if you create a new left-column class and it has an icon class inside of it, then you might be overriding those values or these values might be overridden.

All of this goes back to the nature of CSS and its cascading kind of behavior. When in doubt, the best option is to be as specific as possible. Now when you start to get into more advanced techniques, so there is a skill set out there, it's a very cool tool called SCSS and it's usually, even though it sounds like SASS, it actually is usually spelled out like SCSS.

When you get into that you'll see that this process becomes much more intuitive, but we can't do it in this introductory course just because you need to learn the fundamentals before you start getting into the more advanced techniques.

It's very important to understand that CSS operates like this. This is an important thing to understand, especially if you're just learning how to build websites for the first time. So I'm happy with these. Let's keep on moving down.

Now this left-column right here, we could really apply the same exact technique here. I don't see any reason why not to. I could say .navigation-wrapper, .left-column, and then that's all going to work.

styles.css

.navigation-wrapper > .left-column > .contact-hours-wrapper {
    display: grid;
    grid-template-columns: 1fr;
    grid-gap: 10px;
}

.contact-hours-wrapper is going to be the same thing, except here, what I'm thinking, let's say that if I want to do navigation-wrapper and left-column just like that.

styles.css

.navigation-wrapper > .left-column > .contact-hours-wrapper {
    display: grid;
    grid-template-columns: 1fr;
    grid-gap: 10px;
}

.navigation-wrapper > .left-column >  .contact-hours-wrapper > .hours {
    font-family: 'Ubuntu Condensed', sans-serif;
}

Let's just verify that that is correct. Okay, yes, so contact-hours-wrapper. All that should be working fine. So nav-link, this is one that we're going to have to fix. If we had the nav-link anywhere else then this might start to get a little bit messy.

Now I'm not going to use the navigation-wrapper here. Instead, what I'm going to do is we're going to create a link class, another link class. The reason for this is because I want to show you how later on you can reuse some of this functionality.

That way you can use these links and have a lot of these styles built-in in the footer or in some other spot that doesn't have a navigation-wrapper. In this case, I'm going to create, just like I have that comment up there, I'm going to create a class called links-wrapper.

large

Now what I can do, because I'm pretty confident that links-wrapper is not going to be placed anywhere that I don't want these navigation links placed. What I can do is, for this nav-link, I can say:

styles.css

.links-wrapper > .nav-link a {
    font-family: 'Ubuntu Condensed', sans-serif;
    color: white;
}

Then we want to say everything inside of that is going to take in those same styles. For the address-wrapper, if we come here you can see that right now we have this entire thing as its own div, I think it would make sense to actually update that.

large

I think we should have some wrapper divs. This links-wrapper div should also be the center-column, and then we should have a right-column here. I think that way is best because, if you remember, we have a left-column on this side so let's perform the same task.

Let's say that we want this to be the center-column.

large

Then if we move down here to the closing div, and we want to close that off. Now let's also make sure we keep our indention just so it's nice and readable.

large

Now our center-column has our links-wrapper inside of it. Now, for the address-wrapper we're going to do the same thing. So here, we'll say this is going to be the right-column, let's indent this, and then close off that div.

large

Now if you hit save and go back. Now you can see that everything is still working. We have our right-column here, our center-column, and then our left-column. Now we can get a little bit more specific.

Right here we have our navigation-wrapper which has the font, then we have our links-wrapper here. For this one, I am going to just keep that the same because, like I said, I may want to use that in the footer or something when it's not in the center column.

For address-wrapper we definitely want this to become a little bit more specific. For this one we could say something like:

styles.css

.navigation-wrapper > .right-column > .address-wrapper {
    font-family: 'Ubuntu Condensed', sans-serif;
}

Hit save, come back, hit refresh, everything there's looking good. Lastly, here, we have our banner-image. Now the banner-image is going to be inside of the navigation-wrapper because I want these styles really only when I'm on the home page on that navbar.

So it's going to be .navigation-wrapper > .links-wrapper > .banner-image img. As I'm saying this, I think there's a better way of doing this. I think this should be the center-column, I'll explain why here in a second, so I'm going to say:

styles.css

.navigation-wrapper > .center-column > .banner-image img {
    font-family: 'Ubuntu Condensed', sans-serif;
}

If I come over here, you see how I have links-wrapper and I have that banner-image inside of it? I think that's actually a mistake because I like my code to be very descriptive. You should as well.

If I come to a class called links-wrapper my expectation is that it's only going to have links inside of it. So instead, let's take this banner-image and place it outside of that wrapper. Now we have a center-column that contains a logo and then all of the links just like that.

large

Let's hit save, and let's see if we broke anything. Nope, everything is still looking good.

large

What we've done here is, and sorry if this is a little tedious, but it is important to understand how CSS works. I am assuming that's the whole reason why you're taking the course and spending all the time going through here is being able to understand the exact process.

You're not always going to have a tutorial to follow. You're going to get to the point where you're going to have to build this kind of project out by yourself, and understanding the fundamentals behind it is absolutely critical.

What we've done here is we have refactored all of our styles so that we're very specific. If you're ever curious on a style not being applied. Say you think that you have built out your style, so they should be working, and then you see that it's not working. Well, that is where the devtools are really helpful and that's where they come into play.

Here you can see we have our div, our navigation-wrapper, and look how much easier this is to read. It's very clear that everything here is in the left-column, everything here's in the center, and everything here's on the right.

If I click on the center column and then click on one of these links. If I scroll down here, you can see that you can actually trace the entire lineage. All the way from the body to the navigation-wrapper to that div. Just like we're doing right here.

large

You can become even more specific. If you say that you apply a style or you add in a style and it's not working, well, the browser thankfully does not lie. You can see right here that you have a links-wrapper and it is grabbing using the > symbol.

It's grabbing the next item, which is the nav-link. Then it's grabbing the actual a tag inside of there. That's where we're getting the color and the font-family. You can also trace which values have been overridden through that.

That is the way that, whenever I have a style that isn't working right, I always go straight here to the browser tools to see exactly what is happening and what values are being set. Now we have code that's been refactored, it's now conforming to best practices, and hopefully, you have an even better understanding of how CSS works.