Search code examples
reactjswebpackpostcsscss-modules

Global Utility Classes with PostCSS / CSS Modules


Using CSS Modules, how can I apply a global utility class to multiple elements without duplicating the style declaration?

For example, here is a React component without CSS Modules. The relevant line is the div with two classes: widget and clearfix...

/* components/widget.jsx */

class Widget extends Component {
  render() {
    return (
      <div className="widget clearfix">
        <div className="widget-alpha">Alpha</div>
        <div className="widget-beta">Beta</div>
      </div>
    );
  }
}

.clearfix is a global utility class that I want to apply to many elements throughout my app:

/* util/clearfix.scss */

.clearfix {
  &:before, &:after { content: " "; display: table; }
  &:after { clear: both; }
}

I've seen various ways of importing .clearfix into a CSS Module, but in each case the style declarations are redefined for each occurrence where the class is applied. Here's one example:

/* widget.scss */

.widget {
  // other styles
  composes: clearfix from '../util/clearfix.scss';
}

Solution

  • Through trial and error, I found that you can declare :global in the selector where the utility class is employed (not where it's defined):

    .widget {
    
      // other styles
    
      :global {
        composes: clearfix;
      }
    }
    

    To avoid messy and repetitive import and from statements, I used an index.scss file to import the utility files and then import that in any partial where a utility class is needed.