Skip to content

justincy/css-modules-and-variables-nextjs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CSS Modules and CSS Variables with Next.js

Next.js recently announced built-in support for CSS modules and global stylesheets. CSS modules provide us with an alternative to component specific styling offered by CSS-in-JS libraries. CSS-in-JS libraries also offer us tools constraint-based component design, but we can get the same functionality with a feature built-in to modern browsers: CSS variables. Here we explore how these new features of Next.js render CSS-in-JS libraries unnecessary.

CSS Modules

CSS Modules provide us with scoped CSS. This allows us to declare simple class names without worrying about collisions. We can even use the same class name in multiple files.

Let's use the example from the Next.js announcement. We want to have an error class for our Button component. First, we create components/Button.module.css:

/*
You do not need to worry about .error {} colliding with any other `.css` or
`.module.css` files!
*/
.error {
  color: white;
  background-color: red;
}

Then we import that file into components/Button.js:

import styles from "./Button.module.css";

export function Button() {
  return (
    <button
      type="button"
      // Note how the "error" class is accessed as a property on the imported
      // `styles` object.
      className={styles.error}
    >
      Destroy
    </button>
  );
}

The .error styles declared in Button.module.css will now be applied to the Button component. Of course, you likely don't want all your buttons to have the error styles. This repo shows an example of how you can support different style variants. Take a look at the Button component file and it's CSS file.

CSS Variables

CSS variables (more properly known as custom properties) allows us to define values which can be reused anywhere in the document that is in scope (browser support is fantastic if you don't need to support IE). If we want a value to be available everywhere, we can use the recently announced support for global CSS in Next.js and declare it on the html element:

html {
  --error-color: red;
  --light-text-color: white;
}

To have that file loaded onto to the page we just need to import it into a custom _app.js file:

import "../styles.css";

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

Then we can reference those values anywhere we want to use them, such as on our button. We can modify our Button CSS module like this:

.error {
  color: var(--light-text-color);
  background-color: var(--error-color);
}

That's fun but not necessary for just one component. It's more useful when scaled up to an entire website. Using CSS variables we can define all values used by our theme: fonts, spacing, colors, radii, shadows, and more. Then we can reference them from our components instead of duplicating values all over our CSS.

You can see a larger set of variables in the styles.css file of this repo.

This example repo is deployed at https://css-modules-and-variables-nextjs.now.sh/

Conclusion

We don't need Theme UI, Emotion, or Styled Components. Everything we need is now baked into Next.js and the browser.

This solution was inspired by an article on the Trabe blog.

About

You don't need a CSS-in-JS library with Next.js anymore. We have everything we need with CSS Modules and CSS variables

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published