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.
All AST nodes have these properties:
The node type as a string. See Node Types for all possible values.
Position information for the node in the source code:
{
start: { line: number; column: number };
end: { line: number; column: number };
source?: string;
}Reference to the parent node in the AST.
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
]
}
}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"
}
]
}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"
}A CSS comment.
Properties:
comment: The comment text (without/*and*/)
Example:
{
"type": "comment",
"comment": " This is a comment "
}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
]
}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"
}
]
}
]
}A keyframe within a @keyframes rule.
Properties:
values: Array of keyframe selectors (e.g.,["from"],["to"],["50%"])declarations: Array of declarations and comments
An @import rule.
Properties:
import: The import string (URL or media query)
Example:
{
"type": "import",
"import": "url('styles.css')"
}A @charset rule.
Properties:
charset: The character encoding
Example:
{
"type": "charset",
"charset": "utf-8"
}A @namespace rule.
Properties:
namespace: The namespace declaration
Example:
{
"type": "namespace",
"namespace": "url(http://www.w3.org/1999/xhtml)"
}A @supports rule.
Properties:
supports: The supports conditionrules: Array of rules within the supports block
Example:
{
"type": "supports",
"supports": "(display: grid)",
"rules": [
// ... nested rules
]
}A @document rule.
Properties:
document: The document conditionvendor(optional): Vendor prefixrules: Array of rules within the document block
A @page rule.
Properties:
selectors: Array of page selectorsdeclarations: Array of declarations and comments
A @font-face rule.
Properties:
declarations: Array of font declarations and comments
A :host rule.
Properties:
rules: Array of rules within the host block
A @container rule.
Properties:
container: The container queryrules: Array of rules within the container block
A @layer rule.
Properties:
layer: The layer namerules(optional): Array of rules within the layer block
A @custom-media rule.
Properties:
name: The custom media query namemedia: The media query definition
A @starting-style rule.
Properties:
rules: Array of rules within the starting-style block
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
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}`);
}
});
}
});// 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);
}
});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 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