Skip to content

Instantly share code, notes, and snippets.

@krisbulman
Forked from psebborn/countCSSRules.js
Last active August 25, 2022 19:53
Show Gist options
  • Save krisbulman/0f5e27bba375b151515d to your computer and use it in GitHub Desktop.
Save krisbulman/0f5e27bba375b151515d to your computer and use it in GitHub Desktop.
Count the number of rules and selectors for CSS files on the page. Flags up the >4096 threshold that confuses IE. — This snippet has been modified to count more than just the first level of CSSStyleRule objects within CSSMediaRule.
function countCSSRules() {
var results = '',
log = '';
if (!document.styleSheets) {
return;
}
for (var i = 0; i < document.styleSheets.length; i++) {
countSheet(document.styleSheets[i]);
}
function countSheet(sheet) {
var count = 0;
if (sheet && sheet.cssRules) {
for (var j = 0, l = sheet.cssRules.length; j < l; j++) {
if (!sheet.cssRules[j].selectorText) {
if (sheet.cssRules[j].cssRules) {
for (var m = 0, n = sheet.cssRules[j].cssRules.length; m < n; m++) {
if(sheet.cssRules[j].cssRules[m].selectorText) {
count += sheet.cssRules[j].cssRules[m].selectorText.split(',').length;
}
}
}
}
else {
count += sheet.cssRules[j].selectorText.split(',').length;
}
}
log += '\nFile: ' + (sheet.href ? sheet.href : 'inline <style> tag');
log += '\nRules: ' + sheet.cssRules.length;
log += '\nSelectors: ' + count;
log += '\n--------------------------';
if (count >= 4096) {
results += '\n********************************\nWARNING:\n There are ' + count + ' CSS rules in the stylesheet ' + sheet.href + ' - IE will ignore the last ' + (count - 4096) + ' rules!\n';
}
}
}
console.log(log);
console.log(results);
};
countCSSRules();
@dkeeghan
Copy link

Suggest wrapping a check around line 17:

if(sheet.cssRules[j].cssRules[m].selectorText) {
    count += sheet.cssRules[j].cssRules[m].selectorText.split(',').length;
}

This avoids any "TypeError: Cannot read property 'split' of undefined" errors.

Updated code:

function countCSSRules() {
    var results = '',
        log = '';
    if (!document.styleSheets) {
        return;
    }
    for (var i = 0; i < document.styleSheets.length; i++) {
        countSheet(document.styleSheets[i]);
    }
    function countSheet(sheet) {
        var count = 0;
        if (sheet && sheet.cssRules) {
            for (var j = 0, l = sheet.cssRules.length; j < l; j++) {
                if (!sheet.cssRules[j].selectorText) {
                    if (sheet.cssRules[j].cssRules) {
                        for (var m = 0, n = sheet.cssRules[j].cssRules.length; m < n; m++) {
                            if(sheet.cssRules[j].cssRules[m].selectorText) {
                                count += sheet.cssRules[j].cssRules[m].selectorText.split(',').length;
                            }
                        }
                    }
                }
                else {
                    count += sheet.cssRules[j].selectorText.split(',').length;
                }
            }

            log += '\nFile: ' + (sheet.href ? sheet.href : 'inline <style> tag');
            log += '\nRules: ' + sheet.cssRules.length;
            log += '\nSelectors: ' + count;
            log += '\n--------------------------';
            if (count >= 4096) {
                results += '\n********************************\nWARNING:\n There are ' + count + ' CSS rules in the stylesheet ' + sheet.href + ' - IE will ignore the last ' + (count - 4096) + ' rules!\n';
            }
        }
    }
    console.log(log);
    console.log(results);
};
countCSSRules();

@krisbulman
Copy link
Author

Nice, thanks! (updated gist)

@chibicode
Copy link

For anyone looking for a Grunt script: (see maxSelectors)
https://github.com/phamann/grunt-css-metrics

@krisbulman
Copy link
Author

Above grunt module is no longer maintained. phamann/grunt-css-metrics#10

@bkiener
Copy link

bkiener commented Oct 27, 2018

It ignores the import rule. In case one needs to known the total count of rules including the imported rules, here the modified script:

(function countCSSRules() {
    var log = '',
		listOfImportRules = [],
		totalRules = 0,
		totalSelectors = 0;
    if (!document.styleSheets) {
        return;
    }
    for (var i = 0; i < document.styleSheets.length; i++) {
        countSheet(document.styleSheets[i]);
    }
    function countSheet(sheet) {
        var count = 0;
        if (sheet && sheet.cssRules) {
            for (var j = 0, l = sheet.cssRules.length; j < l; j++) {
				
				if(sheet.cssRules[j] instanceof CSSImportRule) {
					listOfImportRules.push(sheet.cssRules[j].styleSheet);
				} else if (!sheet.cssRules[j].selectorText) {
                    if (sheet.cssRules[j].cssRules) {
                        for (var m = 0, n = sheet.cssRules[j].cssRules.length; m < n; m++) {
                            if(sheet.cssRules[j].cssRules[m].selectorText) {
                                count += sheet.cssRules[j].cssRules[m].selectorText.split(',').length;
                            }
                        }
                    }
                }
                else {
                    count += sheet.cssRules[j].selectorText.split(',').length;
                }
            }

            log += '\nFile: ' + (sheet.href ? sheet.href : 'inline <style> tag');
            log += '\nRules: ' + sheet.cssRules.length;
            log += '\nSelectors: ' + count;
            log += '\n--------------------------';
			totalRules += sheet.cssRules.length;
			totalSelectors += count;
        }
		
		if(listOfImportRules.length > 0) {
	        countSheet(listOfImportRules.shift());
		}
		
    }
    console.log(log);
    console.log("Total Rules: "+ totalRules + "  Total Selectors: " + totalSelectors);
})();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment