A CSS parser, transformer, and minifier written in Rust with Node.js bindings
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Transform inline CSS style attributes with minification and dependency analysis for HTML processing, enabling CSS optimization directly within HTML documents.
Processes inline CSS declaration lists such as HTML style attributes with transformation and minification.
/**
* Compiles a single CSS declaration list, such as an inline style attribute in HTML
* @param options - Style attribute transformation configuration
* @returns Transformation result with optimized declarations and dependencies
*/
function transformStyleAttribute(
options: TransformAttributeOptions
): TransformAttributeResult;
interface TransformAttributeOptions {
/** The filename in which the style attribute appeared. Used for error messages and dependencies. */
filename?: string;
/** The source code to transform. */
code: Uint8Array;
/** Whether to enable minification. */
minify?: boolean;
/** The browser targets for the generated code. */
targets?: Targets;
/**
* Whether to analyze `url()` dependencies.
* When enabled, `url()` dependencies are replaced with hashed placeholders
* that can be replaced with the final urls later (after bundling).
* Dependencies are returned as part of the result.
*/
analyzeDependencies?: boolean;
/**
* Whether to ignore invalid rules and declarations rather than erroring.
* When enabled, warnings are returned, and the invalid rule or declaration is
* omitted from the output code.
*/
errorRecovery?: boolean;
/**
* An AST visitor object. This allows custom transforms or analysis to be implemented in JavaScript.
* Multiple visitors can be composed into one using the `composeVisitors` function.
* For optimal performance, visitors should be as specific as possible about what types of values
* they care about so that JavaScript has to be called as little as possible.
*/
visitor?: Visitor<never>;
}
interface TransformAttributeResult {
/** The transformed code. */
code: Uint8Array;
/** `url()` dependencies, if enabled. */
dependencies: Dependency[] | void;
/** Warnings that occurred during compilation. */
warnings: Warning[];
}Usage Examples:
import { transformStyleAttribute } from "lightningcss";
// Basic style attribute transformation
const result = transformStyleAttribute({
code: new TextEncoder().encode("color: red; background-color: #ffffff; margin: 10px 20px 10px 20px"),
minify: true
});
console.log(new TextDecoder().decode(result.code));
// Output: "color:red;background:#fff;margin:10px 20px"
// Style attribute with browser targets
const modernResult = transformStyleAttribute({
filename: "component.html",
code: new TextEncoder().encode("display: flex; gap: 1rem; color: lab(50% 20 -30)"),
targets: {
chrome: 80 << 16,
firefox: 75 << 16
},
minify: true
});
// Style attribute with dependency analysis
const dependencyResult = transformStyleAttribute({
filename: "page.html",
code: new TextEncoder().encode(`
background-image: url('./assets/bg.jpg');
font-family: 'custom-font', sans-serif;
background-size: cover
`),
analyzeDependencies: true,
minify: true
});
console.log(dependencyResult.dependencies); // Contains url() dependenciesCommon patterns for integrating style attribute transformation with HTML processing.
Server-Side HTML Processing:
import { transformStyleAttribute } from "lightningcss";
import { parse } from "node-html-parser";
function processHtmlStyles(html: string, targets?: Targets): string {
const root = parse(html);
// Find all elements with style attributes
const styledElements = root.querySelectorAll('[style]');
styledElements.forEach(element => {
const styleAttr = element.getAttribute('style');
if (styleAttr) {
try {
const result = transformStyleAttribute({
filename: 'inline-styles.html',
code: new TextEncoder().encode(styleAttr),
targets,
minify: true,
errorRecovery: true
});
const transformedStyle = new TextDecoder().decode(result.code);
element.setAttribute('style', transformedStyle);
// Log any warnings
if (result.warnings.length > 0) {
console.warn(`Style attribute warnings in ${element.tagName}:`, result.warnings);
}
} catch (error) {
console.error('Failed to transform style attribute:', error);
}
}
});
return root.toString();
}
// Usage
const htmlInput = `
<div style="color: red; background-color: #ffffff; margin: 10px 20px 10px 20px;">
<p style="display: flex; gap: 1rem; color: lab(50% 20 -30);">Content</p>
</div>
`;
const optimizedHtml = processHtmlStyles(htmlInput, {
chrome: 90 << 16,
firefox: 88 << 16
});Build Tool Integration:
import { transformStyleAttribute } from "lightningcss";
class StyleAttributeProcessor {
constructor(private targets?: Targets) {}
async processFile(filePath: string): Promise<void> {
const html = await fs.readFile(filePath, 'utf8');
const processed = await this.processHtml(html, filePath);
await fs.writeFile(filePath, processed);
}
private async processHtml(html: string, filename: string): Promise<string> {
const styleRegex = /style="([^"]*)"/g;
return html.replace(styleRegex, (match, styleContent) => {
try {
const result = transformStyleAttribute({
filename,
code: new TextEncoder().encode(styleContent),
targets: this.targets,
minify: true,
errorRecovery: true
});
const optimized = new TextDecoder().decode(result.code);
return `style="${optimized}"`;
} catch (error) {
console.warn(`Failed to optimize style in ${filename}:`, error);
return match; // Return original on error
}
});
}
}
// Usage in build script
const processor = new StyleAttributeProcessor({
chrome: 90 << 16,
firefox: 88 << 16
});
await processor.processFile('dist/index.html');Handle invalid CSS in style attributes gracefully while preserving valid declarations.
const invalidStyleResult = transformStyleAttribute({
filename: "component.html",
code: new TextEncoder().encode(`
color: red;
invalid-property: bad-value;
background: blue;
another-invalid: ;
font-size: 16px
`),
errorRecovery: true,
minify: true
});
console.log(new TextDecoder().decode(invalidStyleResult.code));
// Output: valid declarations only, e.g., "color:red;background:blue;font-size:16px"
console.log(invalidStyleResult.warnings);
// Contains warnings about invalid propertiesApply custom transformations to style attribute CSS using the visitor pattern.
import { transformStyleAttribute, composeVisitors } from "lightningcss";
// Custom visitor to replace specific colors
const colorReplacementVisitor = {
Color(color) {
// Replace red with brand color
if (color.type === 'rgb' &&
color.r === 255 && color.g === 0 && color.b === 0) {
return {
type: 'rgb',
r: 42,
g: 96,
b: 153
};
}
return color;
}
};
const result = transformStyleAttribute({
code: new TextEncoder().encode("color: red; background: blue; border-color: red"),
visitor: colorReplacementVisitor,
minify: true
});
console.log(new TextDecoder().decode(result.code));
// Red colors are replaced with brand color