JSPM

@xero/postcss-nest

1.0.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q13023F
  • License CC0-1.0

PostCss plugin for Property-level factoring, block-level merging, and nesting of pseudo-classes/elements producing beautiful, modern, minimal, maintainable, DRY CSS

Package Exports

  • @xero/postcss-nest

Readme

postcss-nest PostCSS Logo

"the opposite of every other css nesting plugin!"

npm version

A DRY CSS optimizer and advanced nesting plugin for PostCSS.

  • Aggressively merges and refactors shared declarations
  • Nests pseudo-classes/elements with & only when required
  • Groups sibling selectors by shared property
  • Recurses for @media queries and deep nesting.
  • Produces beautiful, modern, minimal, maintainable, CSS/SCSS/SASS output.

Install

With npm:

npm install postcss-nest --save-dev

With bun:

bun add postcss-nest

Usage

Add postcss-nest to your PostCSS plugins:

const postcss = require('postcss')
const postcssNest = require('postcss-nest')

postcss([
  postcssNest(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */)

With postcss.config.js

module.exports = {
  plugins: [
    require('postcss-nest')({
      // options (all default to true)
      nestDescendants: true,
      collapseNestedSiblings: true,
      factorCommonProps: true,
      nestPseudos: true
    })
  ]
}

TypeScript Usage

TypeScript type definitions are included!

import postcss from "postcss";
import postcssNest, { PostcssNestOptions } from "postcss-nest";

const options: PostcssNestOptions = {
  nestDescendants: true,
  collapseNestedSiblings: true,
  factorCommonProps: true,
  nestPseudos: true
};

postcss([postcssNest(options)]).process(cssString).then(result => {
  console.log(result.css);
});

What does it do?

  • Nests descendant selectors: Turns .foo .bar { ... } into .foo { .bar { ... } }.
  • Aggressively merges siblings: Turns duplicated or partially-duplicated sibling selectors into grouped selectors and factors out shared properties.
  • Nests pseudo-classes/elements: Turns a:hover { ... } into a { &:hover { ... } }.
  • Ultra-DRY output: Only unique, unshared styles remain in their original selectors.

Plugin Options

All options default to true. You can disable any pass if desired:

Option Default Description
nestDescendants true Enable nesting of descendant selectors
collapseNestedSiblings true Enable block-level sibling merging
factorCommonProps true Enable aggressive property-level factoring
nestPseudos true Enable nesting of pseudo-classes/elements with &

Example:

postcssNest({
  nestDescendants: false,
  nestPseudos: true
})

Examples

1. Aggressive Property Factoring

Input:

#title {
  font-size: 1.34em;
  background: #444;
}
#quote {
  font-size: 1.34em;
  background: #000;
}

Output:

#title, #quote {
  font-size: 1.34em;
}
#title { background: #444; }
#quote { background: #000; }

2. Pseudo Nesting

Input:

a {
  color: #060;
}
a:hover,
a:focus {
  color: #0f0;
}

Output:

a {
  color: #060;
  &:hover, &:focus {
    color: #0f0;
  }
}

3. Descendant Nesting

Input:

.foo .bar {
  color: red;
}

Output:

.foo {
  .bar {
    color: red;
  }
}

4. Media Queries & Deep Merging

Input:

@media (max-width: 900px) {
  body { font-size: 14px; }
  aside {
    font-size 14px;
    max-width: 350px;
  }
}

Output:

@media (max-width: 900px) {
  body, aside { font-size: 14px; }
  aside { max-width: 350px; }
}

5. Using Options

Input with plugin options:

postcssNest({ nestPseudos: false })
a { color: #0f0; }
a:hover, a:focus { color: #0f0; }

Output:

a { color: #0f0; }
a:hover, a:focus { color: #0f0; }

6. TypeScript Example

Input:

import postcss from "postcss";
import postcssNest, { PostcssNestOptions } from "postcss-nest";

const css = `
.foo .bar {
  color: red;
}
a:hover, a:focus {
  color: blue;
}
`;

const options: PostcssNestOptions = {
  nestDescendants: true,
  nestPseudos: true
};

postcss([postcssNest(options)])
  .process(css)
  .then(result => {
    console.log(result.css);
  });

Output:

.foo {
  .bar {
    color: red;
  }
}
a {
  &:hover, &:focus {
    color: blue;
  }
}

License

CC0 1.0 Universal (Public Domain Dedication) You can use this for any purpose, commercial or non-commercial, with or without attribution.