CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lightningcss

A CSS parser, transformer, and minifier written in Rust with Node.js bindings

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

style-attributes.mddocs/

Style Attribute Processing

Transform inline CSS style attributes with minification and dependency analysis for HTML processing, enabling CSS optimization directly within HTML documents.

Capabilities

Transform Style Attribute Function

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() dependencies

HTML Integration Examples

Common 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');

Error Recovery in Style Attributes

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 properties

Style Attribute Visitor Pattern

Apply 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

docs

bundling.md

index.md

rust-api.md

style-attributes.md

targets.md

transformation.md

visitors.md

tile.json