Check out a free preview of the full Introduction to Next.js 13+, v3 course

The "CSS Modules" Lesson is part of the full, Introduction to Next.js 13+, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Scott demonstrates the process of creating CSS modules, which allow for encapsulating CSS styles to only affect the files where they are imported. In CSS modules, each rule becomes a property on the object when imported.


Transcript from the "CSS Modules" Lesson

>> So that's just CSS, you can do that any file that you want. You can make the CSS wherever you want. And speaking of making files wherever you want, one thing I didn't mention about the app folder that's there really is no right way on how to organize the files.

And I'll show you what I mean. I could, right now you see that they have the globals CSS here in the App folder. And you could do that, that's totally fine because again, as long as it's not a paste, there's specific names, right? There's page, there's layout, there's template.

Those are specific names that it's looking for to render a specific thing. So long as it's not one of those names, you're not gonna affect anything. But when it comes to folders, let's say I wanna group my CSS into a folder, I can make a new folder called CSS.

But does that mean I wanna route segment name CSS as well? So, what you can do is you can make it private by putting an underscore in front of it, and this will tell it next year. So all right, do not include this on the router. Don't even consider this as a segment, it's got an underscore in front of it.

Don't even think about it. So that's one way. That's a little sloppy, so maybe what you wanna do instead is not do that, and instead what you do is just take it out of the app folder and just put it on the root. And now you see it says it's just on a root.

That also works. You can do that too. So there really is no right or wrong way on how you wanna do it. It depends on what you wanna take on. And this is true with any file, or if you have some utility functions, you can put them in the app folder, not put an underscore in front of them and just don't include a page TSX in them.

That would work. You could put an underscore in front of it, or you can just put it on the root of your app. There's so many ways. There's not really a right way. There's really no convention. Okay, so that's standard CSS. The other way that we can add some CSS is CSS modules.

Anyone here knows what CSS modules are? Or wanna take a stab at it? No, nobody's used modules? You've probably used them before, you just don't even realize it. Basically, CSS modules are just like CSS. The only problem with traditional CSS, I mean, and it's in the name of this file, is that it's global.

So any CSS I make here is gonna affect everything on the site if it matches. Whereas modules, CSS modules, are like JavaScript modules, they're encapsulated. They won't affect anything else other than the file in which they're being imported into and where you use them. So you don't have to worry about coming up with unique global names in your CSS file to make sure you're not shadowing or overriding or colliding with other CSS rules.

It's contained. And how it looks is mostly similar to what regular CSS is. I mean, it's literally just regular CSS. But you have to think about how you use them. So I'll give you an example. So let's go to docs here. And I'll make a file and I'll call this style.module.css like this.

I'm just gonna bring it into this ID here. So I've styled up module.css, and then I'll make a style here. And I'll call it title like that. And I'll say font-size is 30 pixels, and then color is red, right? So I have title, and then what I can do in the page is I can just import that.

I can say import, I'll call it styles. So now, because it is a module I will get a variable here. So I do have to say import, give it a name, whatever name I want, from, and then I have to import it like that, style.module.css. And now styles is going to be an object in which I can add class names to.

And in this case, I can say styles.title. And I have title because that's the class name that I added here. So every rule that you add in a module file, a CSS module file, is a property for the object that you import. If I can find the font, there we go.

It's a property for the object in which you import. So now I have styles.title, right? So I can save that. Oops, Save that, Save this, okay. And, what was that? Was that the docs page? Yeah, that was the docs page. So now I can go to docs and you can see it changed here.

And just to show you how it masks and makes sure your CSS is conflict-free. If you look at the actual name of the class I added to it, it generates a unique class for it. That's how it does it. And that's why you have to use the variable names that it passes you on the object because it generates the class name for you.

So it's basically creating a unique class name for everything that you use, and that's how it keeps it safe. Whereas it's not you just have a shadow DOM, which is true encapsulation, something like Vue or Angular Reviews. It's just creating unique class names for you based off the CSS that you write.

So that's CSS modules. I would probably use CSS modules. If I was gonna write CSS files and they were not meant to be global, I would probably use CSS modules. If I'm like, I'm making a component lib. Well, in regular component lib, hopefully you don't have a CSS file that someone has to import.

I can't stand that. That is the worst thing to do is to make a component lib and then it's like, and now here's how you add the CSS for it. Just put the CSS in the components. Please stop doing that. That's so hard to configure, yes?
>> With CSS modules, can we have more than one class for an element?

>> Yeah, you can add as many classes you want because the module doesn't know where you're gonna add them. So I can just have another and I can say, color, or let's just say, what's a good thing for fonts, text-transform uppercase, right? I can do that. So I can say another, and then I can go here and also say, in this case I had to interpolate to add some spaces.

So I could say, styles.title, and then styles.another. And there you go, it's uppercase. So you can add as many as you want. And it'll all just be unique styles out of here, yeah?
>> What is the CSS module syntax to refer to a CSS declaration that isn't just a class, for instance, an id plus a class or something more complicated?

>> Yeah, you probably wouldn't do that. [LAUGH] Basically, yeah, cuz the whole purpose of the CSS module is that I have a style that I wanna add to a specific element, right? And so you don't really need to do those selectors. I mean, if you think about the logic behind it, it's like those selectors are for, I'm digging into a page that has some nested amount of HTML and I'm trying to select it and do a thing.

But if you think about how it would work in modules, or at least in components where you have JavaScript, you probably wouldn't need to do that. Because then you would just make another class and add it to that element itself. Cuz you know what element you wanna add it to, so you don't need to have CSS do the work to find element for you.

You're just be like, here's the element. Make a style for it, add it as a class name. Versus, hey CSS, go find something that is a child selector of this paragraph that also had. That's a lot of work. So yeah, probably wouldn't do that. But you can add pseudo selectors to it and it still works, right?

So you could still do title and do after, whatever, it still will attach to this title. And if you attach this to a class, it'll affect it. So you could still do that. CSS modules also has an alternative syntax. Cuz I think it works with post CSS, so you can do things like nesting classes and stuff like that.

Let me see if you have a good example. You can compose class names together like this, which is pretty cool. I also think it has a plugin system where you can do all different types of stuff. If you wanna reach back out to global, you can add this global directive here to reach back out to global.

At the end of the day, CSS modules was created a long time ago to solve a problem. But as you can see, this was updated six years ago. I think the community has probably moved on from CSS modules. I would even say probably moved on from just using CSS files in general, unless it's third-party like Teleway.

So yeah, it's a little outdated. I would say for the most part people probably still use SASS or something like that, or probably PostCSS with raw CSS and add in their own plugins that way if they're gonna use CSS. But I think the majority of people probably choose CSS in JavaScript, which is I think what most people will probably do.

Which brings me to my next point, which is CSS in JavaScript.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now