import { parse } from '@adobe/css-tools' ;
// Basic CSS parsing
const css = `
body {
font-size: 12px;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
` ;
const ast = parse ( css ) ;
console . log ( ast ) ;
import { parse , stringify } from '@adobe/css-tools' ;
const css = 'body { font-size: 12px; color: #333; }' ;
const ast = parse ( css ) ;
// Convert back to CSS
const output = stringify ( ast ) ;
console . log ( output ) ; // "body { font-size: 12px; color: #333; }"
import { parse } from '@adobe/css-tools' ;
const css = 'body { color: red; }' ;
const ast = parse ( css , { source : 'styles.css' } ) ;
// Position information is available
const rule = ast . stylesheet . rules [ 0 ] ;
console . log ( rule . position ?. source ) ; // "styles.css"
console . log ( rule . position ?. start ) ; // { line: 1, column: 1 }
console . log ( rule . position ?. end ) ; // { line: 1, column: 20 }
import { parse } from '@adobe/css-tools' ;
const malformedCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
` ;
// Parse with silent error handling
const result = parse ( malformedCss , { silent : true } ) ;
// Check for parsing errors
if ( result . stylesheet . parsingErrors ) {
console . log ( 'Parsing errors:' , result . stylesheet . parsingErrors . length ) ;
result . stylesheet . parsingErrors . forEach ( error => {
console . log ( `Error at line ${ error . line } : ${ error . message } ` ) ;
} ) ;
}
// Valid rules are still parsed
console . log ( 'Valid rules:' , result . stylesheet . rules . length ) ;
import { parse } from '@adobe/css-tools' ;
const css = `
.header {
background: #f0f0f0;
padding: 20px;
border-bottom: 1px solid #ccc;
}
` ;
const ast = parse ( css ) ;
const rule = ast . stylesheet . rules [ 0 ] ;
console . log ( rule . type ) ; // "rule"
console . log ( rule . selectors ) ; // [".header"]
console . log ( rule . declarations . length ) ; // 3
rule . declarations . forEach ( decl => {
console . log ( `${ decl . property } : ${ decl . value } ` ) ;
} ) ;
// Output:
// background: #f0f0f0
// padding: 20px
// border-bottom: 1px solid #ccc
import { parse } from '@adobe/css-tools' ;
const css = `
@media screen and (max-width: 768px) {
.container {
padding: 10px;
}
.sidebar {
display: none;
}
}
` ;
const ast = parse ( css ) ;
const mediaRule = ast . stylesheet . rules [ 0 ] ;
console . log ( mediaRule . type ) ; // "media"
console . log ( mediaRule . media ) ; // "screen and (max-width: 768px)"
console . log ( mediaRule . rules . length ) ; // 2
import { parse } from '@adobe/css-tools' ;
const css = `
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
` ;
const ast = parse ( css ) ;
const keyframesRule = ast . stylesheet . rules [ 0 ] ;
console . log ( keyframesRule . type ) ; // "keyframes"
console . log ( keyframesRule . name ) ; // "fadeIn"
console . log ( keyframesRule . keyframes . length ) ; // 2
keyframesRule . keyframes . forEach ( keyframe => {
console . log ( `Keyframe: ${ keyframe . values . join ( ', ' ) } ` ) ;
keyframe . declarations . forEach ( decl => {
console . log ( ` ${ decl . property } : ${ decl . value } ` ) ;
} ) ;
} ) ;
Comments
import { parse } from '@adobe/css-tools' ;
const css = `
/* Header styles */
.header {
background: red; /* Fallback color */
}
/* Footer styles */
.footer {
background: blue;
}
` ;
const ast = parse ( css ) ;
ast . stylesheet . rules . forEach ( rule => {
if ( rule . type === 'comment' ) {
console . log ( `Comment: ${ rule . comment } ` ) ;
} else if ( rule . type === 'rule' ) {
console . log ( `Rule: ${ rule . selectors . join ( ', ' ) } ` ) ;
rule . declarations . forEach ( decl => {
if ( decl . type === 'comment' ) {
console . log ( ` Comment: ${ decl . comment } ` ) ;
} else {
console . log ( ` ${ decl . property } : ${ decl . value } ` ) ;
}
} ) ;
}
} ) ;
import { parse , stringify } from '@adobe/css-tools' ;
const css = `
body {
font-size: 12px;
color: #333;
margin: 0;
padding: 0;
}
` ;
const ast = parse ( css ) ;
// Compressed output
const compressed = stringify ( ast , { compress : true } ) ;
console . log ( compressed ) ;
// Output: "body{font-size:12px;color:#333;margin:0;padding:0}"
import { parse , stringify } from '@adobe/css-tools' ;
const css = 'body { font-size: 12px; color: #333; }' ;
const ast = parse ( css ) ;
// Custom indentation
const formatted = stringify ( ast , { indent : ' ' } ) ;
console . log ( formatted ) ;
// Output:
// body {
// font-size: 12px;
// color: #333;
// }
Nested Rules and At-Rules
import { parse , stringify } from '@adobe/css-tools' ;
const complexCss = `
@import url('https://fonts.googleapis.com/css2?family=Roboto');
@charset "UTF-8";
@media print {
body {
font-size: 12pt;
}
}
@supports (display: grid) {
.grid {
display: grid;
}
}
@keyframes slideIn {
0% { transform: translateX(-100%); }
100% { transform: translateX(0); }
}
@font-face {
font-family: 'CustomFont';
src: url('custom-font.woff2') format('woff2');
}
` ;
const ast = parse ( complexCss ) ;
ast . stylesheet . rules . forEach ( rule => {
switch ( rule . type ) {
case 'import' :
console . log ( `Import: ${ rule . import } ` ) ;
break ;
case 'charset' :
console . log ( `Charset: ${ rule . charset } ` ) ;
break ;
case 'media' :
console . log ( `Media query: ${ rule . media } ` ) ;
break ;
case 'supports' :
console . log ( `Supports: ${ rule . supports } ` ) ;
break ;
case 'keyframes' :
console . log ( `Keyframes: ${ rule . name } ` ) ;
break ;
case 'font-face' :
console . log ( 'Font-face rule' ) ;
break ;
}
} ) ;
import { parse , stringify } from '@adobe/css-tools' ;
const css = `
.button {
background: blue;
color: white;
padding: 10px;
}
` ;
const ast = parse ( css ) ;
const rule = ast . stylesheet . rules [ 0 ] ;
// Add a new declaration
rule . declarations . push ( {
type : 'declaration' ,
property : 'border-radius' ,
value : '5px'
} ) ;
// Modify existing declaration
const backgroundDecl = rule . declarations . find ( d => d . property === 'background' ) ;
if ( backgroundDecl ) {
backgroundDecl . value = 'red' ;
}
// Add a new selector
rule . selectors . push ( '.btn' ) ;
const modifiedCss = stringify ( ast ) ;
console . log ( modifiedCss ) ;
import { parse , CssParseError } from '@adobe/css-tools' ;
try {
const ast = parse ( 'body { color: red; } { invalid }' ) ;
} catch ( error ) {
if ( error instanceof CssParseError ) {
console . log ( `Parse error at line ${ error . line } , column ${ error . column } :` ) ;
console . log ( error . message ) ;
console . log ( `Source: ${ error . filename } ` ) ;
}
}
Working with Silent Errors
import { parse } from '@adobe/css-tools' ;
const problematicCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
.another { border: 1px solid; } /* Missing closing brace */
` ;
const result = parse ( problematicCss , {
silent : true ,
source : 'problematic.css'
} ) ;
// Process valid rules
const validRules = result . stylesheet . rules . filter ( rule => rule . type === 'rule' ) ;
console . log ( `Found ${ validRules . length } valid rules` ) ;
// Log errors for debugging
if ( result . stylesheet . parsingErrors ) {
result . stylesheet . parsingErrors . forEach ( error => {
console . log ( `Error: ${ error . message } at line ${ error . line } ` ) ;
} ) ;
}
import { parse , stringify } from '@adobe/css-tools' ;
function minifyCSS ( css ) {
const ast = parse ( css ) ;
return stringify ( ast , { compress : true } ) ;
}
const css = `
body {
font-size: 12px;
color: #333;
margin: 0;
padding: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
` ;
const minified = minifyCSS ( css ) ;
console . log ( minified ) ;
// Output: "body{font-size:12px;color:#333;margin:0;padding:0}.container{max-width:1200px;margin:0 auto}"
import { parse } from '@adobe/css-tools' ;
function validateCSS ( css , filename = 'unknown' ) {
try {
const ast = parse ( css , { source : filename } ) ;
return {
valid : true ,
rules : ast . stylesheet . rules . length ,
errors : [ ]
} ;
} catch ( error ) {
return {
valid : false ,
rules : 0 ,
errors : [ {
message : error . message ,
line : error . line ,
column : error . column ,
source : error . filename
} ]
} ;
}
}
const result = validateCSS ( 'body { color: red; } { invalid }' , 'test.css' ) ;
console . log ( result ) ;