DEV Community

loading...
Cover image for Using CSS Modules in GatsbyJS

Using CSS Modules in GatsbyJS

Sean Welsh Brown
Full-Stack Software Engineer; using a background in Acting and Voice-Over to pursue a lifelong love of software and technology from an arts and humanities perspective.
・4 min read

I had the pleasure of learning and experimenting with Gatsby over the past week while working on my development portfolio site (seanwelshbrown.com), and there were a ton of things that really clicked for me about it.

Alt Text

Gatsby is a framework built on top of React for building static websites with fast performance and solid SEO, and it has a fantastic tutorial and documentation on its official website.

Something that really stuck out to me during the tutorial was a focus on using CSS modules for styling, something I was unfamiliar with. Styling is incredibly important to front-end design, and something I've always really enjoyed, but my experience using it in previous projects had always been to have a giant global stylesheet that all my HTML elements, class names and IDs existed in. Effective, but hard to keep organized.

A CSS Module differs from a global stylesheet in one significant way, as stated by the CSS module documentation:

A CSS Module is a CSS file in which all class names and animation names are scoped locally by default

What this means is that instead of needing to make sure that every single element in a project has a totally unique class name (which can become disorganized and hard to keep track of, especially when multiple elements might benefit from different styles but the same descriptive class name), a single page or component in a project can have its own dedicated set of class names that are scoped just to that page or component.

This might not make sense immediately, so let's look at it with an example! Thankfully Gatsby works out of the box with CSS modules, so its an excellent way to learn.


In my portfolio site, I have a list of projects on my "projects" page that are made up of simple HTML tags:

  • <div>
  • <p>
  • <a>
  • <ul>
  • <li>

I need these to be styled a certain way, and I could do some inline styling to get them to look the way I want, but that would clog up my .js file since I'd be repeating the same tags and styles over and over again.

I could also make a global stylesheet and put the styling in there, but that wouldn't make much sense since I only need these styles on this one particular page.

This is where a CSS module comes into play!

First off, we look at the name of the page or component that we want to add a stylesheet to. In this case it's "projects.js", so in the same folder of the project we create a file with the same name, but with an extension of ".module.css", like so:

Alt Text

This is how we specify which part of your website the module will be applying to.

Now, within that page or component, we're going to import that stylesheet as a JavaScript object at the top of the page:

Alt Text

What this has done is allowed us to write any classnames and CSS in the module the way we would a normal stylesheet, but we'll call it in our code by referencing the class name as a key.

So instead of having a global stylesheet with:

.project-description {

}

And it being called in our JSX like:

<div className="project-description"></div>

We would use the same class name in our module (only change it to camelCase, for convention) like so:

.projectDescription {

}

And call use it with our imported module in our JSX like this:

<div className={styles.projectDescription}></div>

Easy! You'll notice that if you try to use this class name in any other part of your project that it won't work; this is because the module where it's written is scoped locally to just the locations in your project where it's being imported. Starting to see the potential benefits for keeping your code clean and organized?

If you wanted to use the same class name of "projectDescription" on another page or component but with different styling, a new CSS module would allow you to use the class name again without breaking the styling on the other page. Pretty awesome!


CAVEAT

One thing to be aware of when using CSS modules is to stick with just class names and nested elements. If you attempt to style all of the <p> tags on a page for example, like so:

p {
  font-size: 20px;
}

You would be unpleasantly surprised to find that ALL of the <p> tags on every page of your site are now 20px. Oops!

If you want to keep the local scope of the module but still cover all of a certain type of tag, I'd recommend nesting them. For instance, for my projects page I knew that I wanted every paragraph of a project's description to have a certain style, so I did the following:

Alt Text

I named a <div> with the class name of "projectDescription", and then specified that all <p> tags under it would have a certain style. This works perfectly when used in my JSX like so:

Alt Text

This way I don't have to worry about putting a unique class name on every single <p> tag, while also having control over how only the tags that I want styled will look!

If you're curious, this is what my final CSS module for the page looks like:

Alt Text

Clean, simple and easy to read.


That's a short primer on using CSS Modules in a Gatsby project. Not too complicated at all, and fantastic for keeping your project and code lightweight and organized. Hope you enjoyed reading, and happy developing!

Discussion (0)