Next generation utility-first CSS framework with on-demand generation and Tailwind compatibility.
—
WindiCSS provides a comprehensive style system with classes for representing CSS properties, styles, keyframes, and stylesheets. These classes enable programmatic CSS generation and manipulation with full control over selectors, properties, and metadata.
Represents individual CSS properties with name, value, comments, and importance.
/**
* Represents a CSS property with name, value, and metadata
*/
class Property {
/** CSS property name or array of names */
name: string | string[];
/** CSS property value */
value?: string;
/** Comment associated with the property */
comment?: string;
/** Whether the property should be marked as !important */
important: boolean;
/**
* Creates a new CSS property
* @param name - Property name(s)
* @param value - Property value
* @param comment - Optional comment
* @param important - Whether to mark as important
*/
constructor(
name: string | string[],
value?: string,
comment?: string,
important?: boolean
);
/**
* Converts property to CSS string
* @param minify - Whether to minify output
* @returns CSS property string
*/
build(minify?: boolean): string;
/**
* Creates property from CSS string
* @param css - CSS property string
* @returns Property instance or undefined
*/
static parse(css: string): Property | undefined;
/**
* Clones the property
* @returns New Property instance
*/
clone(): Property;
}Usage Examples:
import { Property } from "windicss/utils/style";
// Basic property
const bgColor = new Property('background-color', '#3b82f6');
console.log(bgColor.build()); // "background-color: #3b82f6;"
// Important property
const textColor = new Property('color', '#ffffff', undefined, true);
console.log(textColor.build()); // "color: #ffffff !important;"
// Property with comment
const margin = new Property('margin', '1rem', 'Standard spacing');
console.log(margin.build()); // "/* Standard spacing */ margin: 1rem;"
// Multiple property names
const borderStyle = new Property(['border-top-style', 'border-bottom-style'], 'solid');
console.log(borderStyle.build()); // "border-top-style: solid; border-bottom-style: solid;"
// Parse from CSS
const parsed = Property.parse('padding: 0.5rem 1rem');
console.log(parsed?.name); // "padding"
console.log(parsed?.value); // "0.5rem 1rem"Represents CSS rules with selectors, properties, and metadata for organizing styles.
/**
* Represents a CSS rule with selector, properties, and metadata
*/
class Style {
/** CSS selector */
selector: string;
/** Array of CSS properties */
property: Property[];
/** Array of child styles for nested rules */
children: Style[];
/** Array of at-rules (media queries, etc.) */
atRules?: string[];
/** Array of pseudo-classes */
pseudoClasses?: string[];
/** Array of pseudo-elements */
pseudoElements?: string[];
/** Parent selector wrapper */
parentSelector?: string;
/** Whether the entire rule is important */
important: boolean;
/** Metadata for organizing and processing */
meta: StyleMeta;
/**
* Creates a new CSS style rule
* @param selector - CSS selector
* @param property - Property or array of properties
* @param important - Whether to mark rule as important
*/
constructor(
selector?: string,
property?: Property | Property[],
important?: boolean
);
/**
* Extends this style with another style
* @param style - Style to extend with
* @returns New extended Style instance
*/
extend(style: Style): Style;
/**
* Clones the style
* @param selector - Optional new selector
* @returns New Style instance
*/
clone(selector?: string): Style;
/**
* Adds at-rule wrapper (media query, etc.)
* @param rule - At-rule string
* @returns This style instance for chaining
*/
atRule(rule: string): Style;
/**
* Adds pseudo-class
* @param pseudoClass - Pseudo-class name
* @returns This style instance for chaining
*/
pseudoClass(pseudoClass: string): Style;
/**
* Adds pseudo-element
* @param pseudoElement - Pseudo-element name
* @returns This style instance for chaining
*/
pseudoElement(pseudoElement: string): Style;
/**
* Wraps with parent selector
* @param parent - Parent selector
* @returns This style instance for chaining
*/
parent(parent: string): Style;
/**
* Wraps with child selector
* @param child - Child selector
* @returns This style instance for chaining
*/
child(child: string): Style;
/**
* Wraps selector with modifier function
* @param modifier - Function to modify selector
* @returns This style instance for chaining
*/
wrapSelector(modifier: (selector: string) => string): Style;
/**
* Updates metadata
* @param layer - CSS layer
* @param group - Group name
* @param order - Order for sorting
* @param count - Processing count
* @param important - Force important
* @param respectSelector - Respect existing selector
* @returns This style instance for chaining
*/
updateMeta(
layer: "base" | "components" | "utilities",
group: string,
order: number,
count: number,
important?: boolean,
respectSelector?: boolean
): Style;
/**
* Converts style to CSS string
* @param minify - Whether to minify output
* @param level - Indentation level
* @returns CSS rule string
*/
build(minify?: boolean, level?: number): string;
/**
* Generates styles from selector and style object
* @param selector - CSS selector
* @param styleObj - Style object with CSS properties
* @returns Array of Style instances
*/
static generate(selector: string, styleObj: any): Style[];
}
interface StyleMeta {
layer: "base" | "components" | "utilities";
group: string;
order: number;
count: number;
respectSelector?: boolean;
variants?: string[];
}Usage Examples:
import { Style, Property } from "windicss/utils/style";
// Basic style
const buttonStyle = new Style('.btn', [
new Property('padding', '0.5rem 1rem'),
new Property('border-radius', '0.375rem'),
new Property('font-weight', '500')
]);
console.log(buttonStyle.build());
// ".btn { padding: 0.5rem 1rem; border-radius: 0.375rem; font-weight: 500; }"
// Style with pseudo-class
const hoverStyle = new Style('.btn')
.pseudoClass('hover');
hoverStyle.property.push(new Property('background-color', '#2563eb'));
console.log(hoverStyle.build());
// ".btn:hover { background-color: #2563eb; }"
// Style with media query
const responsiveStyle = new Style('.container')
.atRule('@media (min-width: 768px)');
responsiveStyle.property.push(new Property('max-width', '1024px'));
// Generate styles from object
const generatedStyles = Style.generate('.card', {
backgroundColor: '#ffffff',
borderRadius: '0.5rem',
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
padding: '1.5rem'
});Represents CSS keyframe animations with support for animation properties.
/**
* Represents CSS keyframes for animations
*/
class Keyframes extends Style {
/**
* Creates CSS keyframes
* @param selector - Animation name
* @param property - Keyframe properties
* @param important - Whether to mark as important
*/
constructor(
selector?: string,
property?: Property | Property[],
important?: boolean
);
/**
* Generates keyframes from animation object
* @param name - Animation name
* @param animationObj - Object with keyframe percentages and properties
* @returns Keyframes instance
*/
static generate(name: string, animationObj: Record<string, any>): Keyframes;
/**
* Converts keyframes to CSS string
* @param minify - Whether to minify output
* @returns CSS keyframes string
*/
build(minify?: boolean): string;
}Usage Examples:
import { Keyframes, Property } from "windicss/utils/style";
// Basic keyframes
const fadeIn = new Keyframes('fadeIn');
fadeIn.children = [
new Style('0%', new Property('opacity', '0')),
new Style('100%', new Property('opacity', '1'))
];
console.log(fadeIn.build());
// "@keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } }"
// Generate from object
const slideIn = Keyframes.generate('slideIn', {
'0%': {
transform: 'translateX(-100%)',
opacity: '0'
},
'100%': {
transform: 'translateX(0)',
opacity: '1'
}
});Special container for grouping related styles with shared metadata.
/**
* Container for grouping related styles
*/
class Container extends Style {
/**
* Creates a style container
* @param selector - Container selector
* @param children - Child styles
*/
constructor(selector?: string, children?: Style[]);
/**
* Adds child style to container
* @param style - Style to add
* @returns This container for chaining
*/
addChild(style: Style): Container;
/**
* Converts container to CSS string
* @param minify - Whether to minify output
* @returns CSS string with all child styles
*/
build(minify?: boolean): string;
}Collection of styles with methods for organization, sorting, and CSS generation.
/**
* Collection of styles with organization and generation methods
*/
class StyleSheet {
/** Array of styles in the sheet */
children: Style[];
/** Whether to use CSS prefixer */
prefixer: boolean;
/**
* Creates a new stylesheet
* @param children - Initial styles
*/
constructor(children?: Style[]);
/**
* Adds style(s) to the sheet
* @param style - Style or array of styles to add
* @returns This stylesheet for chaining
*/
add(style: Style | Style[]): StyleSheet;
/**
* Sorts styles by their metadata order
* @returns This stylesheet for chaining
*/
sort(): StyleSheet;
/**
* Sorts styles using custom sorting function
* @param sortFn - Custom sorting function
* @returns This stylesheet for chaining
*/
sortby(sortFn: (a: Style, b: Style) => number): StyleSheet;
/**
* Combines duplicate styles with same selector
* @returns This stylesheet for chaining
*/
combine(): StyleSheet;
/**
* Extends this stylesheet with another
* @param styleSheet - StyleSheet to extend with
* @returns New extended StyleSheet
*/
extend(styleSheet: StyleSheet): StyleSheet;
/**
* Converts stylesheet to CSS string
* @param minify - Whether to minify output
* @returns Complete CSS string
*/
build(minify?: boolean): string;
/**
* Clones the stylesheet
* @returns New StyleSheet instance
*/
clone(): StyleSheet;
/**
* Gets styles by layer
* @param layer - Layer to filter by
* @returns Array of styles in the layer
*/
getLayer(layer: "base" | "components" | "utilities"): Style[];
}Usage Examples:
import { StyleSheet, Style, Property } from "windicss/utils/style";
// Create stylesheet
const sheet = new StyleSheet();
// Add individual styles
sheet.add(new Style('.btn', [
new Property('padding', '0.5rem 1rem'),
new Property('border-radius', '0.375rem')
]));
sheet.add(new Style('.btn-primary', [
new Property('background-color', '#3b82f6'),
new Property('color', '#ffffff')
]));
// Sort and combine
sheet.sort().combine();
// Generate CSS
console.log(sheet.build());
// Complete CSS output with all styles
// Add multiple styles at once
const additionalStyles = [
new Style('.card', new Property('background-color', '#ffffff')),
new Style('.shadow', new Property('box-shadow', '0 4px 6px -1px rgba(0, 0, 0, 0.1)'))
];
sheet.add(additionalStyles);
// Get styles by layer
const utilityStyles = sheet.getLayer('utilities');
const componentStyles = sheet.getLayer('components');Special property class for handling inline at-rules like media queries within properties.
/**
* Represents inline at-rules within properties
*/
class InlineAtRule extends Property {
/**
* Creates inline at-rule
* @param name - At-rule name
* @param value - At-rule value
* @param comment - Optional comment
* @param important - Whether to mark as important
*/
constructor(
name: string | string[],
value?: string,
comment?: string,
important?: boolean
);
/**
* Converts to CSS at-rule string
* @param minify - Whether to minify output
* @returns CSS at-rule string
*/
build(minify?: boolean): string;
}Usage Example:
import { InlineAtRule } from "windicss/utils/style";
const mediaRule = new InlineAtRule('@media', '(min-width: 768px)');
console.log(mediaRule.build()); // "@media (min-width: 768px)"Install with Tessl CLI
npx tessl i tessl/npm-windicss