or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-css-declaration-sorter

PostCSS plugin and Node.js module that sorts CSS declarations automatically based on their property names.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/css-declaration-sorter@7.2.x

To install, run

npx @tessl/cli install tessl/npm-css-declaration-sorter@7.2.0

index.mddocs/

CSS Declaration Sorter

CSS Declaration Sorter is a Node.js module and PostCSS plugin that automatically sorts CSS, SCSS, or Less declarations based on their property names. It ensures consistent styling organization and can reduce distributed CSS gzipped size through thoughtful property ordering.

Package Information

  • Package Name: css-declaration-sorter
  • Package Type: npm
  • Language: JavaScript with TypeScript definitions
  • Installation: npm install postcss css-declaration-sorter
  • Peer Dependencies: PostCSS ^8.0.9 (required)
  • Node.js Support: ^14 || ^16 || >=18

Core Imports

ESM (ES Modules):

import { cssDeclarationSorter } from "css-declaration-sorter";
// or
import cssDeclarationSorter from "css-declaration-sorter";

CommonJS:

const cssDeclarationSorter = require("css-declaration-sorter");
// or
const { cssDeclarationSorter } = require("css-declaration-sorter");

Basic Usage

As PostCSS Plugin

import postcss from "postcss";
import { cssDeclarationSorter } from "css-declaration-sorter";

// Basic usage with default alphabetical sorting
const result = await postcss([cssDeclarationSorter()])
  .process(css, { from: undefined });

// With options
const result = await postcss([
  cssDeclarationSorter({
    order: 'smacss',
    keepOverrides: true
  })
]).process(css, { from: undefined });

Input/Output Example

Input CSS:

body {
  display: block;
  animation: none;
  color: #C55;
  border: 0;
}

Output CSS (alphabetical order):

body {
  animation: none;
  border: 0;
  color: #C55;
  display: block;
}

Architecture

CSS Declaration Sorter is built around several key components:

  • PostCSS Plugin Interface: Standard PostCSS plugin that hooks into the CSS processing pipeline
  • Built-in Sort Orders: Three predefined property orderings (alphabetical, SMACSS, Concentric CSS)
  • Custom Sort Support: Ability to provide custom comparison functions for property ordering
  • Override Prevention: Optional logic to prevent breaking CSS cascade rules with shorthand/longhand properties
  • Comment Preservation: Intelligent handling of CSS comments during the sorting process

Capabilities

Plugin Creation

Creates a PostCSS plugin instance that sorts CSS declarations.

/**
 * Creates a PostCSS plugin that sorts CSS declarations
 * @param options - Configuration options for sorting behavior
 * @returns PostCSS plugin object with postcssPlugin property and OnceExit method
 */
function cssDeclarationSorter(options?: {
  order?: SortOrder | SortFunction;
  keepOverrides?: boolean;
}): {
  postcssPlugin: 'css-declaration-sorter';
  OnceExit(root: Root): void | Promise<void>;
};

// Available as both named export and default export
export { cssDeclarationSorter };
export default cssDeclarationSorter;

Configuration Options

The plugin accepts an options object with the following properties:

interface PluginOptions {
  /**
   * Provide the name of one of the built-in sort orders or a comparison function
   * @default 'alphabetical'
   */
  order?: SortOrder | SortFunction;
  
  /**
   * Prevent breaking legacy CSS where shorthand declarations override longhand declarations
   * @default false
   */
  keepOverrides?: boolean;
}

type SortOrder = 'alphabetical' | 'concentric-css' | 'smacss';

/**
 * Custom comparison function for sorting CSS properties
 * @param propertyNameA - First property name to compare
 * @param propertyNameB - Second property name to compare
 * @returns -1, 0, or 1 indicating sort order
 */
type SortFunction = (propertyNameA: string, propertyNameB: string) => -1 | 0 | 1;

Built-in Sort Orders

The plugin provides three built-in sorting orders:

Alphabetical ('alphabetical'):

  • Default sorting method
  • Orders properties from A-Z alphabetically
  • Contains 405 modern CSS properties from MDN Browser Compatibility Data project

SMACSS ('smacss'):

  • Orders by importance and visual flow impact
  • Categories: Box → Border → Background → Text → Other
  • Approved by SMACSS methodology author

Concentric CSS ('concentric-css'):

  • Orders from outside-in visual impact
  • Follows Concentric CSS methodology
  • Categories: Positioning → Display & Box Model → Color & Typography

Custom Sort Functions

You can provide a custom comparison function for advanced sorting logic:

import { cssDeclarationSorter } from "css-declaration-sorter";

// Custom sort function example
const plugin = cssDeclarationSorter({
  order: (propA, propB) => {
    // Custom logic: prioritize display properties
    if (propA.startsWith('display')) return -1;
    if (propB.startsWith('display')) return 1;
    return propA.localeCompare(propB);
  }
});

Override Prevention

The keepOverrides option prevents breaking CSS cascade rules where shorthand properties should override longhand properties:

import { cssDeclarationSorter } from "css-declaration-sorter";

const plugin = cssDeclarationSorter({
  keepOverrides: true
});

// This preserves intentional override patterns:
// animation-name: fadeIn;
// animation: slideIn 1s ease; // This overrides animation-name

Error Handling

The plugin validates built-in order names and rejects with descriptive errors during processing:

// Invalid order will cause processing to reject
try {
  const result = await postcss([cssDeclarationSorter({ order: 'invalid-order' })])
    .process(css, { from: undefined });
} catch (error) {
  // Error message: "Invalid built-in order 'invalid-order' provided.
  // Available built-in orders are: alphabetical,concentric-css,smacss"
}

Available Built-in Orders

The plugin includes three built-in sorting orders as separate modules:

// Built-in order identifiers
const builtInOrders: readonly ['alphabetical', 'concentric-css', 'smacss'];

Internal Algorithm

The plugin uses an optimized bubble sort algorithm for in-place sorting of CSS declarations:

/**
 * Optimized bubble sort implementation for CSS node arrays
 * @param list - Array of PostCSS nodes to sort
 * @param comparator - Comparison function for sorting
 * @returns The sorted array (modified in-place)
 */
function bubbleSort<T>(list: T[], comparator: (a: T, b: T) => number): T[];

Shorthand Override Detection

When keepOverrides is enabled, the plugin uses shorthand data to prevent breaking CSS cascade rules:

/**
 * Shorthand property data mapping shorthand properties to their longhand equivalents
 * Used for override detection when keepOverrides is true
 */
interface ShorthandData {
  [shorthandProperty: string]: string[];
}

// Example entries from shorthandData:
// 'animation': ['animation-name', 'animation-duration', 'animation-timing-function', ...]
// 'border': ['border-top', 'border-right', 'border-bottom', 'border-left', ...]
// 'margin': ['margin-top', 'margin-right', 'margin-bottom', 'margin-left', ...]

PostCSS Integration

The plugin integrates with PostCSS through the standard plugin interface:

interface PostCSSPlugin {
  postcssPlugin: 'css-declaration-sorter';
  OnceExit(root: Root): void | Promise<void>;
  postcss: true; // Static property indicating PostCSS compatibility
}

Usage with PostCSS configuration:

// postcss.config.js
module.exports = {
  plugins: [
    require('css-declaration-sorter')({
      order: 'smacss'
    })
  ]
};

Usage with build tools:

// webpack.config.js with postcss-loader
module.exports = {
  module: {
    rules: [{
      test: /\.css$/,
      use: [
        'style-loader',
        'css-loader',
        {
          loader: 'postcss-loader',
          options: {
            postcssOptions: {
              plugins: [
                ['css-declaration-sorter', { order: 'alphabetical' }]
              ]
            }
          }
        }
      ]
    }]
  }
};

SCSS and Less Support

The plugin works with SCSS and Less when combined with appropriate PostCSS parsers:

import postcss from "postcss";
import postcssScss from "postcss-scss";
import { cssDeclarationSorter } from "css-declaration-sorter";

// SCSS support
const result = await postcss([cssDeclarationSorter()])
  .process(scssContent, {
    from: undefined,
    parser: postcssScss
  });

Performance Characteristics

  • Algorithm: Optimized bubble sort implementation for CSS declarations
  • Memory: In-place sorting with minimal memory overhead
  • Compatibility: Works with nested rules and CSS-in-JS patterns
  • Processing: Preserves comments and maintains CSS structure integrity
  • Comment Handling: Intelligently preserves and repositions CSS comments during sorting
  • Vendor Prefixes: Automatically handles vendor-prefixed properties (-webkit-, -moz-, etc.)

Comment Preservation

The plugin intelligently handles CSS comments during the sorting process:

/* Input */
.example {
  display: block;
  /* This comment stays with color */
  color: red;
  border: 1px solid black;
}

/* Output (alphabetical) */
.example {
  border: 1px solid black;
  /* This comment stays with color */
  color: red;
  display: block;
}

Vendor Prefix Handling

Vendor-prefixed properties are treated as their unprefixed equivalents for sorting:

/* Input */
.example {
  display: block;
  -webkit-transform: scale(1);
  transform: scale(1);
  color: red;
}

/* Output (alphabetical) */
.example {
  color: red;
  display: block;
  -webkit-transform: scale(1);
  transform: scale(1);
}

Type Definitions

Complete TypeScript definitions are provided for full type safety:

import type { PluginCreator, Root } from 'postcss';

// ESM type definitions (main.d.mts)
declare const cssDeclarationSorter: PluginCreator<{
  order?: SortOrder | SortFunction | undefined;
  keepOverrides?: boolean;
}>;

export { cssDeclarationSorter };
export default cssDeclarationSorter;

// CommonJS type definitions (main.d.cts)
// export = cssDeclarationSorter;

type SortOrder = 'alphabetical' | 'concentric-css' | 'smacss';

/**
 * Custom comparison function for sorting CSS properties
 * @param propertyNameA - First property name to compare
 * @param propertyNameB - Second property name to compare
 * @returns -1, 0, or 1 indicating sort order
 */
type SortFunction = (propertyNameA: string, propertyNameB: string) => -1 | 0 | 1;

interface PluginOptions {
  /**
   * Provide the name of one of the built-in sort orders or a comparison function
   * @default 'alphabetical'
   */
  order?: SortOrder | SortFunction;
  
  /**
   * Prevent breaking legacy CSS where shorthand declarations override longhand declarations
   * @default false
   */
  keepOverrides?: boolean;
}

Advanced Usage Examples

Multiple Sort Orders in Pipeline

import postcss from "postcss";
import { cssDeclarationSorter } from "css-declaration-sorter";

// Apply different sorting to different selectors
const processor = postcss([
  cssDeclarationSorter({ order: 'smacss' })
]);

const css = `
  .layout { position: relative; display: flex; margin: 10px; }
  .text { font-size: 16px; color: blue; line-height: 1.4; }
`;

const result = await processor.process(css, { from: undefined });

Integration with CSS Frameworks

// Works well with CSS frameworks and methodologies
const plugin = cssDeclarationSorter({
  order: 'concentric-css', // Matches BEM/OOCSS patterns
  keepOverrides: true      // Preserves framework override patterns
});

Build Process Integration

// gulpfile.js
import gulp from 'gulp';
import postcss from 'gulp-postcss';
import { cssDeclarationSorter } from 'css-declaration-sorter';

gulp.task('css', () => {
  return gulp.src('src/**/*.css')
    .pipe(postcss([
      cssDeclarationSorter({ order: 'alphabetical' })
    ]))
    .pipe(gulp.dest('dist/'));
});