@projectwallace/css-analyzer
Version:
The best CSS analyzer out there. Check design tokens, complexity, specificity, performance and more.
1,048 lines (1,047 loc) • 30.9 kB
TypeScript
/**
* @typedef Options
* @property {boolean} useLocations Use Locations (`{ 'item': [{ line, column, offset, length }] }`) instead of a regular count per occurrence (`{ 'item': 3 }`)
*/
/**
* Analyze CSS
* @param {string} css
* @param {Options} options
*/
export function analyze(css: string, options?: Options): {
stylesheet: {
sourceLinesOfCode: number;
linesOfCode: number;
size: number;
complexity: number;
comments: {
total: number;
size: number;
};
embeddedContent: {
size: {
total: number;
ratio: number;
};
types: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: {
[k: string]: {
size: number;
count: number;
} & ({
uniqueWithLocations?: undefined;
} | {
uniqueWithLocations: {
offset: number;
line: number;
column: number;
length: number;
}[];
});
};
};
};
};
atrules: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
fontface: {
total: number;
totalUnique: number;
unique: Record<string, string>[];
uniquenessRatio: number;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]> | undefined;
} | {
uniqueWithLocations?: undefined;
});
import: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
media: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
browserhacks: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
features: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
};
charset: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
supports: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
browserhacks: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
};
keyframes: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
prefixed: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
};
};
container: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
names: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
};
layer: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
property: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
complexity: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
};
nesting: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & ({
items: number[];
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})));
};
rules: {
total: number;
empty: {
total: number;
ratio: number;
};
sizes: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & ({
items: number[];
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})));
nesting: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & ({
items: number[];
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})));
selectors: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & ({
items: number[];
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})));
declarations: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & ({
items: number[];
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})));
};
selectors: {
total: number;
totalUnique: number;
uniquenessRatio: number;
specificity: {
/** @type Specificity */
min: Specificity;
/** @type Specificity */
max: Specificity;
/** @type Specificity */
sum: Specificity;
/** @type Specificity */
mean: Specificity;
/** @type Specificity */
mode: Specificity;
/** @type Specificity */
items: Specificity;
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
}));
complexity: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & (({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
items: number[];
});
nesting: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & ({
items: number[];
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})));
id: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
};
pseudoClasses: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
accessibility: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
};
keyframes: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
prefixed: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
};
combinators: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
};
declarations: {
total: number;
totalUnique: number;
uniquenessRatio: number;
importants: {
total: number;
ratio: number;
inKeyframes: {
total: number;
ratio: number;
};
};
complexity: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
};
nesting: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
} & ({
items: number[];
} & ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})));
};
properties: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
prefixed: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
};
custom: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
importants: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
};
};
browserhacks: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
ratio: number;
};
complexity: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
};
};
values: {
colors: (({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
itemsPerContext: {
[k: string]: {
total: number;
totalUnique: number;
unique: Record<string, number>;
uniquenessRatio: number;
};
};
}) & {
formats: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
};
gradients: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
fontFamilies: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
fontSizes: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
lineHeights: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
zindexes: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
textShadows: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
boxShadows: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
borderRadiuses: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
itemsPerContext: {
[k: string]: {
total: number;
totalUnique: number;
unique: Record<string, number>;
uniquenessRatio: number;
};
};
};
animations: {
durations: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
timingFunctions: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
};
prefixes: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
browserhacks: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
units: ({
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
})) & {
itemsPerContext: {
[k: string]: {
total: number;
totalUnique: number;
unique: Record<string, number>;
uniquenessRatio: number;
};
};
};
complexity: {
min: number | undefined;
max: number | undefined;
mean: number;
mode: number;
range: number;
sum: number;
};
keywords: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
resets: {
total: number;
totalUnique: number;
uniquenessRatio: number;
unique: Record<string, number>;
} & ({
uniqueWithLocations: Record<string, {
line: number;
column: number;
offset: number;
length: number;
}[]>;
} | {
uniqueWithLocations?: undefined;
});
};
__meta__: {
parseTime: number;
analyzeTime: number;
total: number;
};
};
/**
* Compare specificity A to Specificity B
* @param {Specificity} a - Specificity A
* @param {Specificity} b - Specificity B
* @returns {number} sortIndex - 0 when a==b, 1 when a<b, -1 when a>b
*/
export function compareSpecificity(a: Specificity, b: Specificity): number;
export { isHack as isPropertyHack } from './properties/property-utils.js';
export { isValuePrefixed } from './values/vendor-prefix.js';
export { hasVendorPrefix } from './vendor-prefix.js';
export type Options = {
/**
* Use Locations (`{ 'item': [{ line, column, offset, length }] }`) instead of a regular count per occurrence (`{ 'item': 3 }`)
*/
useLocations: boolean;
};
export type Specificity = [number, number, number];
export { getComplexity as selectorComplexity, isPrefixed as isSelectorPrefixed, isAccessibility as isAccessibilitySelector } from './selectors/utils.js';
export { isSupportsBrowserhack, isMediaBrowserhack } from './atrules/atrules.js';