Skip to content

tomasz-sodzawiczny/postcss-modules-extend-rule

Repository files navigation

postcss-modules-extend-rule CSS Modules Logo

License: MIT NPM version Build Status

PostCSS plugin for using @extend at-rule with CSS Modules.

.myClass {
  @extend .someClass from 'module';
}

Motivation

CSS Modules suggests using composes syntax for composition. It works by modifying the exported class name rather than changing the underlying CSS itself. This implementation detail causes one major issue: composes cannot work with @media queries.

CSS Extend Rule implemented by PostCSS Extend Rule package proposes a reliable solution for this problem - but within a single CSS file only.

This plugin suggests and implements an extended syntax for the @extend rule allowing for use with classes defined in other CSS modules:

.layout {
  @extend .margin-large from './margins.css';
}

@media (max-width: 240px) {
  .layout {
    @extend .margin-small from './margins.css';
  }
}

This package is using PostCSS Extend Rule plugin internally - only adding the from 'module' syntax which it processes to work with CSS Modules.

Installation

yarn add --dev postcss-modules-extend-rule

Note that you don't have to install and run the postcss-extend-rule separately - all it's behaviors are included in this plugin.

Usage

This package consists of two PostCSS plugins. To use it, your setup must allow both pre-bundling and post-bundling PostCSS processing. First, before the CSS Modules bundling, all modules must be transformed with postcss-modules-extend-rule/pre plugin. Then, the final bundle must be processed with postcss-modules-extend-rule/post.

const { pre, post } = require('postcss-modules-extend-rule');
// or
const pre = require('postcss-modules-extend-rule/pre'); // use me before bundling happens
const post = require('postcss-modules-extend-rule/post'); // use me on the final CSS bundle

With webpack

Pre-bundling and post-bundling processing can be implemented in webpack environment by combining PostCSS Loader and PostCSSAssetsPlugin:

// in CSS loader chain
{
  loader: 'postcss-loader',
  options: {
    plugins: [require('postcss-modules-extend-rule/pre')]
  }
}
// in plugins
new PostCSSAssetsPlugin({
  test: /\.css$/,
  plugins: [require('postcss-modules-extend-rule/post')],
});

Example working setup can be fun in our test webpack.config.js.

Options

This package supports all options from PostCSS Extend Rule. Both pre and post plugins accept the same set of options.

postcssModuleExtends.pre({ onFunctionalSelector: 'warn' });

Caveats

Functional selectors

Functional selectors (e.g. %foo) are not supported yet. Contributions are very welcome!

License

MIT