Search code examples
sassgatsbycss-modules

CSS modules with Sass and Gatsby


How can Sass be used with CSS modules in Gatsby on conditional classes?

I have tried the following:

menu.js

import menuStyles from './menu.module.scss';
import classNames from 'classnames';

const Menu = ({ open }) => {
  return (
    <nav className={classNames(menuStyles.menu, { isOpen: open })}>
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
      </ul>
    </nav>
  );
};

menu.module.scss:

.menu {
  background: green;

  &.isOpen {
    background: blue;
  }
}

An onClick event updates the open prop, and I can see the isOpen class being added and removed as expected. The problem is that the CSS isn't applied to it: the background remains green. Looking in the Chrome Network tab I can see that the styles are applied to the class menu-module--isOpen--DyE73 and not just isOpen:

.menu-module--menu--2cKbx {
  background: green;
}
.menu-module--menu--2cKbx.menu-module--isOpen--DyE73 {
  background: blue;
}

When not using CSS modules (import './menu.scss'; and <nav className={classNames('menu', { isOpen: open })}>), the styles are applied properly in both cases.

How can Sass be used with CSS modules to style the conditional isOpen class?


Solution

  • The following will work:

    <nav className={classNames(menuStyles.menu, { [menuStyles.isOpen]: open })}>
    

    The difference is that I replaced isOpen with [menuStyles.isOpen] (the square brackets representing computed property names).

    Just like menu, the CSS rule isOpen also gets a dynamic, locally scoped name so you need to make sure to import its name from the CSS module to.