Check out a free preview of the full Professional CSS: Build a Website from Scratch course
The "Tips for Scaling a Codebase" Lesson is part of the full, Professional CSS: Build a Website from Scratch course featured in this preview video. Here's what you'd learn in this lesson:
Kevin discusses the need to plan for new additions to the project and to create reusable components whenever possible. Kevin talks about the use of custom properties and cascade layers to help with organization. He also mentions the importance of refactoring and making changes to improve code structure.
Transcript from the "Tips for Scaling a Codebase" Lesson
[00:00:00]
>> Kevin Powell: Now that we've got to this point, I wanna talk a little bit about this idea of staying organized as a project is growing. Because we went from having sort of talked a lot early on about reusable things, utility classes, reusable layouts. And then getting into the components, like our cards and other things.
[00:00:16]
And then we got to the second page, and then it's like, okay, well, now we need these more custom things, so let's add this title in there for the bento grid, and then we need our mushroom guide. And we start getting these more custom things that come in.
[00:00:27]
And this is always what happens as a project grows. And so it's really important as this is happening, that when these things are being added to the project you're thinking a little bit about how you're going to approach creating them and doing them instead of just jumping in.
[00:00:41]
Just like we did early on when we got that big picture view and we were trying to work on that. When you get to things that are a little bit smaller, or a new thing that's been added to the project, you wanna take that same mentality or that same approach to what you're doing.
[00:00:53]
So planning it out before you dive in. And we could look at the Figma file, and just as an example when we got to this grid here, I could have just done the mushroom guide and made a very specific grid just for the mushroom guide. But I went, well, this grid is really a generic grid with cards in it.
[00:01:09]
So while I need that mushroom guide in there to do a little bit of the styling, it helped us change the titles and the spacing on those cards, I didn't wanna link that grid specifically to that one space on the website. I wanted to make something that was a little bit more generic and that I could use that way.
[00:01:25]
And so, then when I got to this bento grid, well, then I didn't really have a choice there because this is really a unique layout that's probably never gonna be repeated anywhere else. So then you think about it, you go, okay, I can use my generic cards, but I just need to make a layout that's very specific to this one use case.
[00:01:40]
And so, always looking at the bigger picture as these different things are coming in. And trying to create reusable things as much as possible, even if it's a new thing that's been added to your project. And as we've seen through it everything now, and I've been very heavy-handed in my use of custom properties.
[00:01:53]
I'd say there's never any harm in making something a custom property that's locally scoped. I'm a huge fan of locally scoped custom properties, I throw them on tons of stuff all the time. And it just makes it so that one thing that you've created suddenly is more reusable and more customizable if you throw it into different situations.
[00:02:09]
We've also been playing a little bit with cascade layers, so I think that using and leveraging those layers can just help with organization. Even just from a mental perspective of when you're coming in and looking through your CSS file. Of knowing, okay, I just have this reset at the top, and then I have this base layer and my layout things and my components.
[00:02:27]
And the ordering in there can get a little bit mixed up or you could potentially come in with sublayers, I'm gonna talk about that very soon. But just having this sort of mental organization of your different things can really go a long way. And it's one of those things that you're going to get better at the more you do it.
[00:02:41]
Cuz you're gonna throw something in one layer and then you realize it doesn't really make sense there. And the next time you do it, maybe you'll put it somewhere else so you refactor it, you put it somewhere else, and there's no harm in that. There's no harm in having more layers or less layers, or just having one layer and then having your other code down here.
[00:02:56]
Cuz I could have a whole bunch of layered stuff at the top and then subgeneral stuff at the bottom. If I have lots of layers, I probably wouldn't wanna do that. But if I just have a reset at the top and then I have my other code at the bottom, I think something like that could work out well too.
[00:03:09]
With all of that, I think it's also really important to recognize that refactoring is okay. We saw really small examples of that when I changed the card from being display grid to display flex because I ran into a situation where I said, you know what? This actually makes more sense, and it's not gonna break anything that I've already done.
[00:03:25]
So don't be scared about changing the way something's working. Or if you come into something such as, if you made these cards in a very specific way and they worked in that one way and it was fine. But then you got to these cards and you realized, they're actually really similar.
[00:03:40]
Maybe I need to make a change to that other thing instead of just layering more and more CSS on stuff, that can be a really good idea. And one example that you could do in this project if you wanted to. We don't need to because we don't have other buttons to do, but you could definitely refactor the buttons to be something that's a little bit more customizable and reusable.
[00:03:59]
Just setting them up the same way we've done a few other things, where you set them up with custom properties with fallbacks. So you have a default that's just using the custom properties. And then you manipulate them a little bit for how you have them set up, and then you can make changes.
[00:04:13]
You have a brand version of your button. So however you're doing your modifier classes, whether it's with modifier classes, whether it's with the data attributes like I've been doing. You can then just set the button-background, the button-background-hover, the text. And you can do all of this, and this is really awesome to do when you have things like hover states and other things.
[00:04:32]
Cuz you just go on the parent selector, and you can redefine all these different things without having to then select the hover state again or then select this other version of it again. One selector just to make all of these different changes that are happening. One thing with this is sometimes people don't like having the fallbacks the way we've set them up here.
[00:04:48]
Just because if you looked at this at first glance, you can't tell me what the color is, you have to think about it a little bit. So for these types of components, the other thing you could do instead is do it this way. Where you're just saying the color is button-text, the background is button-background, the border radius is button-border-radius.
[00:05:09]
And then you have all these custom properties just at the top, and it makes it a lot more readable and quick, very quickly you know exactly what's going on. And then, again, you have this settings down here, but this is what's controlling everything through that component. And it makes it very easy to overwrite and make changes to it.
[00:05:26]
The one drawback of doing something this way is, because these custom properties are being defined on the button itself, on the parent, you can't make any changes to it. Because the parent, you declare something and then it's getting defined here. And I just bring that up because we took advantage of that a little bit in our components, like here, where I had the mushroom guide, where the parent was redeclaring some custom properties, and I was able to set them there.
[00:05:53]
So you have to think a little bit about, does this button gonna be something that's self encapsulated? And I'm only gonna be changing the styles of it through a modifier class or something like that? Or do I want it to be something where I can change a style up higher and that's gonna bleed through into these subcomponents or these things that are nested inside of there?
[00:06:12]
So it is a little bit of a give and take. You can definitely mix and match a little bit, so buttons could be something where, no, I don't want those to be changed by the parent. I only want the button to control what the button looks, but the titles of the cards, I think it makes sense to have that extra level.
[00:06:27]
I wish I could say that this is the right way to do it, this is the wrong way to do it, it's project to project, it's personal preference a little bit. And it's one of those things that I really just encourage you to experiment with, play with, and have some fun with it, to be honest.
[00:06:39]
And to see how it works while you're using it and trying out different ways to do it as you're writing your CSS to find these things that you feel work for you, but using custom properties as much as possible. Locally scoped ones, I find has been a complete game changer for me.
[00:06:53]
And it just makes life so much easier to have these more robust components, or these more robust, I keep calling them components cuz it's a button or something like that. It's not the component in the JS framework sense, but these more robust elements and classes and everything, they are more reusable along the way.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops