babel-plugin-css-in-comments

Style your React components with simplicity using css inside your comments. Styles get transformed into css modules and are automatically imported. The className attribute is also transformed to add some utilities and prevent intensive use of styles.<name>.

Installation

If you don’t have a React app nearby with easy access to the babel configuration, consider using the quick start guide.

Install the plugin:

npm i -D babel-plugin-css-in-comments

And add it to the .babelrc file:

{
  "plugins": ["babel-plugin-css-in-comments"]
}

How to use

Comments

Comments can be used at the global scope of a file. Start your comments with css for scoped styles and css global for global styles. It’s best to place scoped styles under their component and global styles at the end of the file.

Example:

const Logo = () => (
  <a href='/' className='logo .active'>
    Logo
  </a>
);
/*css
.logo {
  font-size: 2rem;
  font-weight: bold;
  font-family: 'Montserrat', sans-serif;
}
*/

export default Logo;
/*css global
a {
  text-decoration: none;
  color: inherit;
}
.active {
  opacity: 1;
}
*/

className attribute

Use scoped and global class names within the className attribute, along with conditionals to reduce the need to combine class names with " ".

Example:

const Logo = ({ active }) => (
  <a href='/' className='logo .dark active?'>
    Logo
  </a>
);

// transformed
const Logo = ({ active }) => (
  <a
    href='/'
    className={styles.logo + ' dark' + (active ? ' ' + styles.active : '')}
  >
    Logo
  </a>
);

What happened here?

  • logo get transformed into styles.logo because it’s a scoped class name.
  • .dark is a global class name because it starts with ., the dot is removed and the class name isn’t transformed.
  • active? is a conditional which depend on the active prop of the component.

Conditionals

Simple conditionals can be used to write less code.

Example:

With test only:

<span className='hidden?' />
<span className='.hidden?' />
// transformed
<span className={hidden ? styles.hidden : ''} />
<span className={hidden ? 'hidden' : ''} />

With consequent:

<span className='active?dark' />
<span className='active?.dark' />
// transformed
<span className={active ? styles.dark : ''} />
<span className={active ? 'dark' : ''} />

With consequent and alternate:

<span className='active?primary:secondary' />
<span className='active?.active:.hidden' />
// transformed
<span className={active ? styles.primary : styles.secondary} />
<span className={active ? 'active' : 'hidden'} />

Logical expressions

Logical expressions can also be used.
They are converted into conditionals.

Example:

<span className='dark|light' />
<span className='.active|.hidden' />
// transformed
<span className={dark ? styles.dark : styles.light} />
<span className={active ? 'active' : 'hidden' />

Quick Start

This example use create-next-app since the babel configuration is easier to access.

git clone https://github.com/Charly1620/css-in-comments-example.git
cd ./css-in-comments-example
npm install
npm run dev

As you can see, it looks just like the default template but with styles contained into their own components and less styles.<name>.

If you want to use sass, you can install it and set the cssExt option to scss or sass.

Play around and see if this fit your needs. Also check out the how to use section to learn more.

Options

cssDir string
  • Directory where styles are created.
  • Default: ./styles
cssExt string
  • Extension of css files.
  • Default: css
useCSS boolean
  • Create css files.
  • Default: true
useImportDeclaration boolean
  • Add import declaration at top of files that use css comments.
  • Default: true
transpileWithoutCSS boolean
  • Transpile className attribute even if no css comments in the file.
  • Default: false

License

Licensed under the MIT License, Copyright © 2021-present Charly Albin.

See LICENSE.md for more information.

GitHub

https://github.com/Charly1620/babel-plugin-css-in-comments