6.3 KiB
Abstract Syntax Tree (AST)
Overview
The AST represents CSS as a tree structure where each node has a specific type and properties. All nodes share common properties and have type-specific properties.
Common Properties
All AST nodes have these properties:
type
The node type as a string. See Node Types for all possible values.
position (optional)
Position information for the node in the source code:
{
start: { line: number; column: number };
end: { line: number; column: number };
source?: string;
}
parent (optional)
Reference to the parent node in the AST.
Node Types
stylesheet
The root node representing an entire CSS document.
Properties:
stylesheet.source(optional): Source file pathstylesheet.rules: Array of top-level rulesstylesheet.parsingErrors(optional): Array of parse errors whensilentoption is used
Example:
{
"type": "stylesheet",
"stylesheet": {
"rules": [
// ... other nodes
]
}
}
rule
A CSS rule with selectors and declarations.
Properties:
selectors: Array of CSS selectors as stringsdeclarations: Array of declarations and comments
Example:
{
"type": "rule",
"selectors": ["body", "html"],
"declarations": [
{
"type": "declaration",
"property": "color",
"value": "red"
}
]
}
declaration
A CSS property declaration.
Properties:
property: The CSS property namevalue: The CSS property value as a string
Example:
{
"type": "declaration",
"property": "background-color",
"value": "#ffffff"
}
comment
A CSS comment.
Properties:
comment: The comment text (without/*and*/)
Example:
{
"type": "comment",
"comment": " This is a comment "
}
media
A @media rule.
Properties:
media: The media query stringrules: Array of rules within the media block
Example:
{
"type": "media",
"media": "screen and (max-width: 768px)",
"rules": [
// ... nested rules
]
}
keyframes
A @keyframes rule.
Properties:
name: The keyframes namevendor(optional): Vendor prefix (e.g., "-webkit-")keyframes: Array of keyframe rules and comments
Example:
{
"type": "keyframes",
"name": "fade",
"keyframes": [
{
"type": "keyframe",
"values": ["from"],
"declarations": [
{
"type": "declaration",
"property": "opacity",
"value": "0"
}
]
}
]
}
keyframe
A keyframe within a @keyframes rule.
Properties:
values: Array of keyframe selectors (e.g.,["from"],["to"],["50%"])declarations: Array of declarations and comments
import
An @import rule.
Properties:
import: The import string (URL or media query)
Example:
{
"type": "import",
"import": "url('styles.css')"
}
charset
A @charset rule.
Properties:
charset: The character encoding
Example:
{
"type": "charset",
"charset": "utf-8"
}
namespace
A @namespace rule.
Properties:
namespace: The namespace declaration
Example:
{
"type": "namespace",
"namespace": "url(http://www.w3.org/1999/xhtml)"
}
supports
A @supports rule.
Properties:
supports: The supports conditionrules: Array of rules within the supports block
Example:
{
"type": "supports",
"supports": "(display: grid)",
"rules": [
// ... nested rules
]
}
document
A @document rule.
Properties:
document: The document conditionvendor(optional): Vendor prefixrules: Array of rules within the document block
page
A @page rule.
Properties:
selectors: Array of page selectorsdeclarations: Array of declarations and comments
font-face
A @font-face rule.
Properties:
declarations: Array of font declarations and comments
host
A :host rule.
Properties:
rules: Array of rules within the host block
container
A @container rule.
Properties:
container: The container queryrules: Array of rules within the container block
layer
A @layer rule.
Properties:
layer: The layer namerules(optional): Array of rules within the layer block
custom-media
A @custom-media rule.
Properties:
name: The custom media query namemedia: The media query definition
starting-style
A @starting-style rule.
Properties:
rules: Array of rules within the starting-style block
Type Hierarchy
The AST nodes are organized in the following hierarchy:
CssStylesheetAST- Root nodeCssAtRuleAST- Union of all at-rule and rule nodesCssAllNodesAST- Union of all possible node types
Working with the AST
Traversing Nodes
import { parse, CssStylesheetAST } from '@adobe/css-tools';
const ast: CssStylesheetAST = parse('body { color: red; }');
// Access top-level rules
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'rule') {
console.log('Selectors:', rule.selectors);
rule.declarations.forEach(decl => {
if (decl.type === 'declaration') {
console.log(`${decl.property}: ${decl.value}`);
}
});
}
});
Modifying Nodes
// Add a new declaration
const newDecl = {
type: 'declaration' as const,
property: 'font-size',
value: '16px'
};
// Find a rule and add the declaration
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'rule' && rule.selectors.includes('body')) {
rule.declarations.push(newDecl);
}
});
Error Handling
When parsing with the silent option, errors are collected in the AST:
const ast = parse('invalid css {', { silent: true });
if (ast.stylesheet.parsingErrors) {
ast.stylesheet.parsingErrors.forEach(error => {
console.error('Parse error:', error.message);
});
}
Position Information
Position information is available on most nodes and includes:
start.lineandstart.column: Beginning of the nodeend.lineandend.column: End of the nodesource: Source file path (if provided during parsing)
This is useful for:
- Error reporting
- Source mapping
- Code analysis tools
- IDE integration