Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 1,000,000+ packages pre-installed, including @fpipita/babel-plugin-css-tag-postcss with all npm packages installed. Try it out:

require("@babel/core/package.json"); // @babel/core is a peer dependency. require("postcss/package.json"); // postcss is a peer dependency. var babelPluginCssTagPostcss = require("@fpipita/babel-plugin-css-tag-postcss")

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

@fpipita/babel-plugin-css-tag-postcss v2.0.0

Process your css tagged templates with PostCSS.

babel-plugin-css-tag-postcss Travis build

If you build production apps and make use of the css tag function to style your LitElement-like webcomponents, this simple Babel plugin will come very handy as it will let you transform your css tagged templates by doing things like adding vendor prefixes, minification and all of the other stuff that can be achieved through PostCSS plugins.

For example, given the following:

// input.js
import { LitElement, css, html } from "lit-element";

const sm_min = 600;

export class MyFoo extends LitElement {
  static get styles() {
    return css`
      @media (min-width: ${sm_min}px) {
        ::placeholder {
          color: red;
        }
      }
    `;
  }

  render() {
    return html`<input type="text" placeholder="Write something" />`;
  }
}

and assuming your .postcssrc.json (or any of the other config formats supported by the postcss-load-config package) contains:

{
  "plugins": {
    "autoprefixer": {
      "overrideBrowserslist": ["edge 17, firefox 19, chrome 56"]
    }
  }
}

the plugin will output:

// output.js
import { LitElement, css, html } from "lit-element";

const sm_min = 600;

export class MyFoo extends LitElement {
  static get styles() {
    return css`
      @media (min-width: ${sm_min}px) {
        ::-webkit-input-placeholder {
          color: gray;
        }
        ::-moz-placeholder {
          color: gray;
        }
        ::-ms-input-placeholder {
          color: gray;
        }
        ::placeholder {
          color: gray;
        }
      }
    `;
  }

  render() {
    return html`<input type="text" placeholder="Write something" />`;
  }
}

Installation

$ npm install --save-dev @fpipita/babel-plugin-css-tag-postcss

You also need to have @babel/core and postcss packages installed and properly configured for your build process.

Usage

In your babel configuration, simply add:

{
  "plugins": [
    [
      "@fpipita/babel-plugin-css-tag-postcss",
      {
        "tag": "css"
      }
    ]
  ]
}

You can optionally specify the tag option, which is basically the name of the css tag function you use to define the css tagged templates in your code. It defaults to css so in most cases you can just forget about it.

The plugin will read and reuse your existing PostCSS configuration which can be expressed in any of the formats supported by the postcss-load-config package.

Template literals with embedded expressions

Despite it is best to avoid embedded expressions and make use of css custom variables to make styles that can be configured at runtime (read here why), there are cases where you can't use css custom variables just because the css cascading model doesn't apply, like within the media query list part of a @media CSS at-rule.

When the plugin encounters an embedded expression, it keeps it in place:

// input.js
css`
  @media (min-width: ${sm_min}px) {
    ::placeholder {
      color: gray;
    }
  }
`;

// output.js
css`
  @media (min-width: ${sm_min}px) {
    ::-webkit-input-placeholder {
      color: gray;
    }
    ::-moz-placeholder {
      color: gray;
    }
    ::-ms-input-placeholder {
      color: gray;
    }
    ::placeholder {
      color: gray;
    }
  }
`;

The next example is only shown with the purpose of explaining how the plugin behaves when an expression is encountered within a css rule which is expanded by PostCSS:

// input.js
css`
  @media (min-width: 600px) {
    ::placeholder {
      // don't do this, use css custom variables e.g. color: var(--my-foo-placeholder-color)
      color: ${gray};
    }
  }
`;

// output.js
css`
  @media (min-width: 600px) {
    ::-webkit-input-placeholder {
      color: ${gray};
    }
    ::-moz-placeholder {
      color: ${gray};
    }
    ::-ms-input-placeholder {
      color: ${gray};
    }
    ::placeholder {
      color: ${gray};
    }
  }
`;

Known limitations

Due to the sync nature of Babel plugins, only sync PostCSS plugins are supported.

RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free