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:
typeThe 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.
stylesheetThe 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 when silent option is usedExample:
{
"type": "stylesheet",
"stylesheet": {
"rules": [
// ... other nodes
]
}
}
ruleA CSS rule with selectors and declarations.
Properties:
selectors: Array of CSS selectors as stringsdeclarations: Array of declarations and commentsExample:
{
"type": "rule",
"selectors": ["body", "html"],
"declarations": [
{
"type": "declaration",
"property": "color",
"value": "red"
}
]
}
declarationA CSS property declaration.
Properties:
property: The CSS property namevalue: The CSS property value as a stringExample:
{
"type": "declaration",
"property": "background-color",
"value": "#ffffff"
}
commentA CSS comment.
Properties:
comment: The comment text (without /* and */)Example:
{
"type": "comment",
"comment": " This is a comment "
}
mediaA @media rule.
Properties:
media: The media query stringrules: Array of rules within the media blockExample:
{
"type": "media",
"media": "screen and (max-width: 768px)",
"rules": [
// ... nested rules
]
}
keyframesA @keyframes rule.
Properties:
name: The keyframes namevendor (optional): Vendor prefix (e.g., "-webkit-")keyframes: Array of keyframe rules and commentsExample:
{
"type": "keyframes",
"name": "fade",
"keyframes": [
{
"type": "keyframe",
"values": ["from"],
"declarations": [
{
"type": "declaration",
"property": "opacity",
"value": "0"
}
]
}
]
}
keyframeA keyframe within a @keyframes rule.
Properties:
values: Array of keyframe selectors (e.g., ["from"], ["to"], ["50%"])declarations: Array of declarations and commentsimportAn @import rule.
Properties:
import: The import string (URL or media query)Example:
{
"type": "import",
"import": "url('styles.css')"
}
charsetA @charset rule.
Properties:
charset: The character encodingExample:
{
"type": "charset",
"charset": "utf-8"
}
namespaceA @namespace rule.
Properties:
namespace: The namespace declarationExample:
{
"type": "namespace",
"namespace": "url(http://www.w3.org/1999/xhtml)"
}
supportsA @supports rule.
Properties:
supports: The supports conditionrules: Array of rules within the supports blockExample:
{
"type": "supports",
"supports": "(display: grid)",
"rules": [
// ... nested rules
]
}
documentA @document rule.
Properties:
document: The document conditionvendor (optional): Vendor prefixrules: Array of rules within the document blockpageA @page rule.
Properties:
selectors: Array of page selectorsdeclarations: Array of declarations and commentsfont-faceA @font-face rule.
Properties:
declarations: Array of font declarations and commentshostA :host rule.
Properties:
rules: Array of rules within the host blockcontainerA @container rule.
Properties:
container: The container queryrules: Array of rules within the container blocklayerA @layer rule.
Properties:
layer: The layer namerules (optional): Array of rules within the layer blockcustom-mediaA @custom-media rule.
Properties:
name: The custom media query namemedia: The media query definitionstarting-styleA @starting-style rule.
Properties:
rules: Array of rules within the starting-style blockThe AST nodes are organized in the following hierarchy:
CssStylesheetAST - Root nodeCssAtRuleAST - Union of all at-rule and rule nodesCssAllNodesAST - Union of all possible node typesimport { 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.line and start.column: Beginning of the nodeend.line and end.column: End of the nodesource: Source file path (if provided during parsing)This is useful for: