CSSTree: CSS AST Parser, Walker, Generator, and Lexer

3.2.1 · active · verified Wed Apr 22

CSSTree is a comprehensive toolkit for processing CSS, providing a fast and detailed parser to transform CSS source into an Abstract Syntax Tree (AST), a walker for efficient AST traversal, a generator to serialize AST back into CSS, and a lexer for syntax validation and matching based on W3C specifications and browser implementations. The current stable version is 3.2.1, with frequent patch and minor releases indicating active development. It stands out for its performance (benchmarked as one of the fastest), spec compliance, detailed AST format with adjustable parsing levels, and inherent error tolerance by wrapping malformed content in `Raw` nodes instead of discarding it. It also leverages `mdn/data` for robust syntax validation, making it suitable for complex CSS analysis and source-to-source transformations.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates parsing CSS into an AST, traversing the AST to inspect nodes (e.g., declarations), modifying the AST, and then generating the modified CSS string. It also shows error handling during parsing.

import { parse, generate, walk } from 'css-tree';

const cssInput = `
  .container {
    display: flex;
    gap: 10px; /* New in CSS, handled by CSSTree */
    background: linear-gradient(to right, #f00, #00f);
    @container (min-width: 400px) {
      .item {
        font-size: 1.2em;
      }
    }
  }
  @media (max-width: 600px) {
    .container { flex-direction: column; }
  }
`;

try {
  const ast = parse(cssInput, { 
    positions: true, // Include source location info
    onParseError: (error, fallbackNode) => {
      console.warn(`Parsing error at ${error.line}:${error.column}: ${error.message}`);
      // Optionally, return fallbackNode or throw to stop parsing
    }
  });

  console.log('Original AST (partial):', ast.children.first.type, ast.children.first.loc);

  // Example: Walk the AST to find all `Declaration` nodes and log their properties
  let declarationCount = 0;
  walk(ast, {
    visit: 'Declaration',
    enter: (node) => {
      declarationCount++;
      console.log(`  Declaration: ${node.property}: ${generate(node.value)}`);
    }
  });
  console.log(`Total declarations found: ${declarationCount}`);

  // Modify the AST, e.g., change `gap` to `margin` for demonstration
  walk(ast, {
    visit: 'Declaration',
    enter: (node) => {
      if (node.property === 'gap') {
        node.property = 'margin'; // Simple AST modification
      }
    }
  });

  const modifiedCss = generate(ast);
  console.log('\nModified CSS:\n', modifiedCss);

} catch (error) {
  console.error('An unexpected error occurred:', error);
}

view raw JSON →