Minify selectors with PostCSS.
npx @tessl/cli install tessl/npm-postcss-minify-selectors@7.0.0PostCSS Minify Selectors is a PostCSS plugin that optimizes CSS selectors by removing unnecessary parts, normalizing whitespace, and applying various minification rules. It helps reduce CSS bundle sizes by cleaning up selector syntax while maintaining functionality.
npm install postcss-minify-selectorsconst postcssMinifySelectors = require("postcss-minify-selectors");For ESM:
import postcssMinifySelectors from "postcss-minify-selectors";const postcss = require("postcss");
const postcssMinifySelectors = require("postcss-minify-selectors");
// Basic usage with default options
const result = await postcss([
postcssMinifySelectors()
]).process(css, { from: undefined });
// With custom options
const result = await postcss([
postcssMinifySelectors({ sort: false })
]).process(css, { from: undefined });Input CSS:
h1 + p, h2, h3, h2{color:blue}
*#id, *.class, *[href]{background:red}
::before, ::after{content:""}
:nth-child(1), :nth-child(2n+1){font-weight:bold}
[ class= "test" ], [title="*.js"]{border:1px solid red}Output CSS:
h1+p,h2,h3{color:blue}
#id,.class,[href]{background:red}
:before,:after{content:""}
:first-child,:nth-child(odd){font-weight:bold}
[class=test],[title="*.js"]{border:1px solid red}Creates a PostCSS plugin instance with optional configuration.
/**
* Creates a PostCSS plugin for minifying selectors
* @param {Options} opts - Optional configuration object
* @returns {Plugin} PostCSS plugin instance
*/
function postcssMinifySelectors(opts?: Options): Plugin;Parameters:
opts (optional): Configuration options objectReturns:
postcssPlugin property and OnceExit methodConfiguration options for controlling selector minification behavior.
interface Options {
/** Whether to sort selectors alphabetically (default: true) */
sort?: boolean;
}Properties:
sort (optional): Boolean flag to enable/disable selector sorting. Default: trueThe plugin function includes PostCSS compatibility indicators.
/** Indicates PostCSS plugin compatibility */
postcssMinifySelectors.postcss: true;The plugin applies the following optimizations:
Removes qualified universal selectors where they are redundant:
*#id → #id*.class → .class*[href] → [href]*:not(.green) → :not(.green)Normalizes whitespace around selectors and combinators:
h1, h2, h3 → h1,h2,h3h1 + p → h1+ph1 p → h1 pOptimizes attribute selectors by:
Quote removal and normalization:
[class="woop_woop_woop"] → [class=woop_woop_woop][class*=" icon-"] (spaces), [data-attr~="key1=1"] (equals signs)[title=""] and single hyphens: [title="-"]Space and formatting normalization:
[ color= "blue" ] → [color=blue][class="woop \\ woop woop"] → [class="woop woop woop"]=, ~=, |=, ^=, $=, *=Case-insensitive flag handling:
[color="blue" i ] → [color=blue i]Attribute name trimming:
Optimizes pseudo-selectors by:
nth-child/nth-of-type conversions:
nth-child(1) → :first-childnth-last-child(1) → :last-childnth-of-type(1) → :first-of-typenth-last-of-type(1) → :last-of-typeeven → 2n in nth-child expressions2n+1 → odd in nth-child expressions:NTH-CHILD(1) → :first-child:nth-last-of-type(2n + 2) → :nth-last-of-type(2n+2)Double-colon to single-colon conversion for backward compatibility:
::before → :before::after → :after::first-letter → :first-letter::first-line → :first-line::BEFORE → :BEFORE:not() pseudo-class optimizations:
:not(.article, .comments) → :not(.article,.comments):not(h2, h3, h4, h5, h5, h6) → :not(h2,h3,h4,h5,h6):not( *[href="foo"] ) → :not([href=foo])Optimizes keyframe selectors:
from → 0%100% → to (when used alone)FROM → 0%entry 100% (won't convert to entry to)Removes duplicate selectors within the same rule.
When enabled (default), sorts selectors alphabetically for consistency.
The plugin includes comprehensive safety measures to ensure optimizations don't break functionality:
String boundary preservation:
Comment handling:
/*comment*/*/*comment*/Framework compatibility:
--my-toolbar-theme:{color:blue};.\\31 0\\+[foo|bar], [*|att], [|att]½Context-aware optimization:
[glob="/**/*.js"] (preserved)[class=" *.js "]Mixin compatibility:
: (likely custom mixins)const postcss = require("postcss");
const postcssMinifySelectors = require("postcss-minify-selectors");
const result = await postcss([
postcssMinifySelectors({ sort: false })
]).process(css, { from: undefined });// postcss.config.js
module.exports = {
plugins: [
require("postcss-minify-selectors")({
sort: true
})
]
};This plugin is part of the cssnano preset but can be used independently:
const postcss = require("postcss");
const postcssMinifySelectors = require("postcss-minify-selectors");
const result = await postcss([
postcssMinifySelectors(),
// other plugins...
]).process(css, { from: undefined });interface Options {
/** Whether to sort selectors alphabetically (default: true) */
sort?: boolean;
}
interface Plugin {
/** PostCSS plugin identifier */
postcssPlugin: string;
/** Main processing method called once after all rules are processed */
OnceExit(css: Root): void;
}
interface Root {
/** Walk through all rules in the CSS */
walkRules(callback: (rule: Rule) => void): void;
}
interface Rule {
/** The selector string */
selector: string;
/** Raw selector information */
raws: {
selector?: {
value: string;
raw: string;
};
};
}The plugin relies on these external packages:
postcss-selector-parser: For parsing and manipulating CSS selectorscssesc: For CSS string escaping utilities