PostCSS plugin that removes empty CSS rules, declarations, selectors, and at-rules to optimize CSS output.
npx @tessl/cli install tessl/npm-postcss-discard-empty@7.0.0PostCSS Discard Empty is a PostCSS plugin that optimizes CSS by removing empty CSS constructs that do not affect the output. It automatically detects and discards empty rules, declarations without values, null selectors, and at-rules without content, helping reduce CSS bundle sizes while preserving functional styling.
npm install postcss-discard-emptyconst discardEmpty = require('postcss-discard-empty');For TypeScript/ESM:
import discardEmpty from 'postcss-discard-empty';CommonJS with destructuring:
const { default: discardEmpty } = require('postcss-discard-empty');const postcss = require('postcss');
const discardEmpty = require('postcss-discard-empty');
const css = `
@font-face;
h1 {}
{color:blue}
h2 {color:}
h3 {color:red}
`;
postcss([discardEmpty()])
.process(css, { from: undefined })
.then(result => {
console.log(result.css);
// Output: h3 {color:red}
});PostCSS Discard Empty follows the standard PostCSS plugin architecture:
OnceExit hook for processing CSS after all transformationsCreates a PostCSS plugin instance for removing empty CSS constructs.
/**
* Creates a PostCSS plugin that removes empty CSS rules, declarations, and at-rules
* @returns PostCSS plugin instance
*/
function pluginCreator(): import('postcss').Plugin;The plugin creator function has no parameters and returns a PostCSS plugin that:
--)@layer rules)Usage Examples:
const postcss = require('postcss');
const discardEmpty = require('postcss-discard-empty');
// Use in PostCSS processing pipeline
const processor = postcss([discardEmpty()]);
// Process CSS with empty constructs
const result = await processor.process(`
@font-face; /* Empty at-rule - will be removed */
h1 {} /* Empty rule - will be removed */
{color:blue} /* Null selector - will be removed */
h2 {color:} /* Empty declaration - will be removed */
h3 {--custom:} /* Empty custom property - preserved */
h4 {color:red} /* Valid rule - preserved */
`, { from: undefined });
console.log(result.css);
// Output: h3 {--custom:} h4 {color:red}PostCSS compatibility flag indicating this is a PostCSS plugin.
/**
* PostCSS plugin compatibility flag
*/
pluginCreator.postcss: true;This flag is required by PostCSS to identify the function as a valid plugin creator.
The plugin processes CSS constructs in the following order:
@font-face; or @media {} with no content--)@layer at-rules as they serve a functional purpose in CSS cascade layersEach removed CSS construct generates a removal message with:
interface RemovalMessage {
type: 'removal';
plugin: 'postcss-discard-empty';
node: import('postcss').AnyNode;
}These messages can be accessed through the PostCSS result object for debugging or logging purposes.
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-discard-empty')(),
],
},
},
},
],
},
],
},
};// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
css: {
postcss: {
plugins: [
require('postcss-discard-empty')(),
],
},
},
});// postcss.config.js
module.exports = {
plugins: [
require('postcss-discard-empty')(),
// other plugins...
],
};/**
* Main plugin creator function export
*/
declare function pluginCreator(): import('postcss').Plugin;
declare namespace pluginCreator {
/**
* PostCSS compatibility flag
*/
let postcss: true;
}
/**
* Plugin instance returned by the creator
*/
interface Plugin extends import('postcss').Plugin {
postcssPlugin: 'postcss-discard-empty';
OnceExit(css: import('postcss').Root, helpers: { result: import('postcss').Result }): void;
}
export = pluginCreator;