A lib for generating Style Sheets with JavaScript.
npx @tessl/cli install tessl/npm-jss@10.10.0JSS is a comprehensive CSS-in-JS library that enables developers to write styles using JavaScript objects and generate optimized CSS stylesheets at runtime. It provides a powerful plugin architecture with numerous plugins for features like nested selectors, camel case property names, vendor prefixing, default units, and more. The library supports both server-side rendering and client-side style injection, offers TypeScript support, and is designed for high performance with features like style caching and efficient DOM updates.
npm install jssimport jss, { create, SheetsRegistry } from "jss";For CommonJS:
const jss = require("jss").default;
const { create, SheetsRegistry } = require("jss");import jss from "jss";
// Create a stylesheet
const styles = {
myButton: {
color: 'green',
'&:hover': {
background: 'red'
}
}
};
const sheet = jss.createStyleSheet(styles);
sheet.attach();
// Access generated class names
console.log(sheet.classes.myButton); // "myButton-0-1-2"
// Use in HTML
document.getElementById('button').className = sheet.classes.myButton;JSS is built around several key components:
Jss class)Core JSS instance creation and configuration for setting up the CSS-in-JS environment.
function create(options?: Partial<JssOptions>): Jss;
interface Jss {
createStyleSheet<Name extends string | number | symbol>(
styles: Partial<Styles<Name, any, undefined>>,
options?: StyleSheetFactoryOptions
): StyleSheet<Name>;
removeStyleSheet(sheet: StyleSheet): this;
setup(options?: Partial<JssOptions>): this;
use(...plugins: Plugin[]): this;
createRule(style: JssStyle, options?: RuleFactoryOptions): Rule;
createRule<Name extends string>(name: Name, style: JssStyle, options?: RuleFactoryOptions): Rule;
}StyleSheet lifecycle management including creation, rule manipulation, and DOM attachment.
interface StyleSheet<RuleName extends string | number | symbol = string | number | symbol> {
classes: Classes<RuleName>;
keyframes: Keyframes<string>;
attach(): this;
detach(): this;
addRule(style: JssStyle, options?: Partial<RuleOptions>): Rule;
addRule(name: RuleName, style: JssStyle, options?: Partial<RuleOptions>): Rule | null;
addRules(styles: Partial<Styles<RuleName, any, undefined>>, options?: Partial<RuleOptions>): Rule[];
getRule(nameOrSelector: RuleName | string): Rule;
deleteRule(name: RuleName): boolean;
update(name: string, data: object, options?: UpdateOptions): this;
update(data: object, options?: UpdateOptions): this;
toString(options?: ToCssOptions): string;
}Global and scoped stylesheet management for organizing multiple stylesheets in applications.
class SheetsRegistry {
readonly index: number;
add<RuleName extends string | number | symbol>(sheet: StyleSheet<RuleName>): void;
reset(): void;
remove<RuleName extends string | number | symbol>(sheet: StyleSheet<RuleName>): void;
toString(options?: ToCssOptions): string;
}
class SheetsManager {
readonly size: number;
get(key: object): StyleSheet | null;
add(key: object, sheet: StyleSheet): void;
manage(key: object): StyleSheet | null;
unmanage(key: object): void;
}
class RuleList {
add(name: string, decl: JssStyle, options?: RuleOptions): Rule | null;
get(nameOrSelector: string): Rule;
remove(rule: Rule): void;
indexOf(rule: Rule): number;
update(name: string, data: {}): void;
update(data: {}): void;
toString(options?: ToCssOptions): string;
}Helper functions for CSS value conversion, dynamic style extraction, and rule creation.
function toCssValue(value: JssValue): string;
function getDynamicStyles(styles: Styles): Styles | null;
function createRule<D>(name: string, decl: JssStyle, options: RuleOptions): Rule;
function createGenerateId(options?: CreateGenerateIdOptions): GenerateId;
const hasCSSTOMSupport: boolean;// Base CSS property types from csstype package dependency
type CSSProperties<TValue = string | number> = import('csstype').Properties<TValue>;
type NormalCssProperties = CSSProperties<string | number>;
type NormalCssValues<K> = K extends keyof NormalCssProperties ? NormalCssProperties[K] : JssValue;
// Function type for dynamic styles
type Func<P, T, R> = T extends undefined ? (data: P) => R : (data: P & {theme: T}) => R;
// Observable interface for reactive values
interface MinimalObservable<T> {
subscribe(nextOrObserver: ((value: T) => void) | {next: (value: T) => void}): {
unsubscribe: () => void
}
}
type JssStyle<Props = any, Theme = undefined> = {
[K in keyof NormalCssProperties]:
| NormalCssValues<K>
| JssStyle<Props, Theme>
| Func<Props, Theme, NormalCssValues<K> | JssStyle<undefined, undefined> | undefined>
| MinimalObservable<NormalCssValues<K> | JssStyle | undefined>
} | {
[K: string]:
| JssValue
| JssStyle<Props, Theme>
| Func<Props, Theme, JssValue | JssStyle<undefined, undefined> | undefined>
| MinimalObservable<JssValue | JssStyle | undefined>
};
type Styles<
Name extends string | number | symbol = string,
Props = unknown,
Theme = undefined
> = Record<
Name,
| JssStyle<Props, Theme>
| Array<JssStyle<Props, Theme>>
| string
| Func<Props, Theme, JssStyle<undefined, undefined> | string | null | undefined>
| MinimalObservable<JssStyle | string | null | undefined>
>;
type Classes<Name extends string | number | symbol = string> = Record<Name, string>;
type JssValue = (string & {}) | (number & {}) | Array<string | number | Array<string | number> | '!important'> | null | false;
interface Plugin {
onCreateRule?(name: string, decl: JssStyle, options: RuleOptions): Rule;
onProcessRule?(rule: Rule, sheet?: StyleSheet): void;
onProcessStyle?(style: JssStyle, rule: Rule, sheet?: StyleSheet): JssStyle;
onProcessSheet?(sheet?: StyleSheet): void;
onChangeValue?(value: string, prop: string, rule: Rule): string | null | false;
onUpdate?(data: object, rule: Rule, sheet?: StyleSheet): void;
}
interface JssOptions {
createGenerateId: CreateGenerateId;
plugins: ReadonlyArray<Plugin>;
Renderer?: {new (): Renderer} | null;
insertionPoint: InsertionPoint;
id: CreateGenerateIdOptions;
}
// Additional supporting types
type CreateGenerateId = (options?: CreateGenerateIdOptions) => GenerateId;
type GenerateId = (rule: Rule, sheet?: StyleSheet<string>) => string;
type InsertionPoint = string | HTMLElement | Comment;
type Keyframes<Name extends string = string> = Record<Name, string>;
interface CreateGenerateIdOptions {
minify?: boolean;
}
interface RuleOptions {
selector?: string;
sheet?: StyleSheet;
index?: number;
parent?: ContainerRule | StyleSheet;
classes: Classes;
jss: Jss;
generateId: GenerateId;
Renderer: Renderer;
}
interface Rule {
type: string;
key: string;
isProcessed: boolean;
options: RuleOptions;
toString(options?: ToCssOptions): string;
}
interface ContainerRule extends Rule {
rules: RuleList;
}
interface StyleSheetFactoryOptions {
media?: string;
meta?: string;
index?: number;
link?: boolean;
element?: HTMLStyleElement;
generateId?: GenerateId;
classNamePrefix?: string;
}
interface UpdateOptions {
process?: boolean;
force?: boolean;
}
interface ToCssOptions {
indent?: number;
format?: boolean;
allowEmpty?: boolean;
}
interface Renderer {
setProperty(cssRule: HTMLElement | CSSStyleRule, prop: string, value: JssValue): boolean;
getPropertyValue(cssRule: HTMLElement | CSSStyleRule, prop: string): string;
removeProperty(cssRule: HTMLElement | CSSStyleRule, prop: string): void;
setSelector(cssRule: CSSStyleRule, selectorText: string): boolean;
attach(): void;
detach(): void;
deploy(sheet: StyleSheet): void;
insertRule(rule: Rule): false | CSSRule;
deleteRule(cssRule: CSSRule): boolean;
replaceRule(cssRule: CSSRule, rule: Rule): false | CSSRule;
indexOf(cssRule: CSSRule): number;
getRules(): CSSRuleList | void;
}