Blog

Blog · RSS

What does the CSS health score on a paid audit measure?

· WebVitalist

WebVitalist computes a CSS health score on a paid audit from the CSS it can read off the fetched page. This note is dated October 23, 2026 and states that rule as the audit implements it. The free scan does not collect stylesheets and does not compute this score.

What is read

The audit uses the HTML from the fetch and resolves links against the final URL after redirects. It takes non-empty style blocks from that HTML, in document order, and then linked stylesheets, in document order, up to 6. The collected text is capped at 400,000 characters. Each linked file is read up to the lesser of 200,000 characters and the room left in that cap. A style block is cut to the room left as well. Once the cap is full, later stylesheets are not fetched.

A link is a stylesheet when its rel, compared case-insensitively as separate words, includes stylesheet, and the element does not have a disabled attribute. The address must normalize to http or https. A hash is removed. Query keys that start with utm_, fbclid, gclid, or mc_ are removed, and a later link that normalizes to the same URL is dropped. mailto, tel, javascript, data, and blob addresses are dropped. A preload that is not a stylesheet is dropped.

Each linked file is fetched with an 8 second timeout and may follow up to 5 redirects. A host the audit is not allowed to fetch, including a loopback address, is skipped, and the CSS already collected is still graded. A response outside 200–299 is skipped. A content type of text/html, application/json, application/xml, application/javascript, or text/javascript is skipped. A body that starts with a doctype or an html tag is skipped. An empty body is skipped. A fetch that fails is skipped. @import rules inside the CSS are not downloaded.

The number

The collected text, style blocks first and then stylesheets, joined by newlines, is graded in three areas: performance, maintainability, and complexity. The published score is those three grades added, divided by 3, and rounded to the nearest integer. A stylesheet whose only rule is a { color: red; } scores 100. A document that contains @import scores lower, and that rule is recorded under the violation id Imports.

A measured result stores the line “Performance P, maintainability M, complexity C. Not part of the overall score.” The report prints “Score N/100.” in front of that line, then a table of the three area scores. It then says how many characters were read, how many linked stylesheets were included, and how many style blocks were found. The style-block count is the number of non-empty style elements in the HTML, including any that were cut by the cap. The stylesheet count is the number of files actually included. The same paragraph states that JavaScript-injected CSS is not included, that @import is not downloaded, and that this score is not part of the overall score.

Violations with a penalty of 0 or less are dropped. The rest are ordered by higher penalty, then by label, and at most 8 are stored. The report lists each one as the label, the area, and the penalty. The labels for the ids the grader can return are:

  • Imports: @import rules, which delay CSS
  • EmptyRules: Empty rules
  • SelectorDuplications: Duplicated selectors
  • DeclarationDuplications: Duplicated declarations
  • CssSize: Stylesheet size
  • TooMuchComments: Comment volume
  • TooMuchEmbeddedContent: Embedded content such as base64
  • AverageSelectorsPerRule: Selectors per rule
  • MaxSelectorsPerRule: A rule with many selectors
  • MoreThanMostCommonSelectorsPerRule: Rules with more selectors than the typical rule
  • IdSelectorRatio: ID selectors
  • ImportantRatio: !important
  • AverageDeclarationsPerRule: Declarations per rule
  • MaxDeclarationsPerRule: A rule with many declarations
  • MoreThanMostCommonDeclarationsPerRule: Rules with more declarations than typical
  • AverageSelectorComplexity: Selector complexity
  • MaxSelectorComplexity: A very complex selector
  • MoreThanMostCommonSelectorComplexity: Selectors more complex than typical
  • MoreThanMostCommonSelectorSpecificity: Specificity higher than typical
  • SourceLinesOfCode: Lines of CSS

What it does not change

The overall score is a weighted mean of the category scores that exist on that audit. The weights are technical 0.2, security 0.15, performance 0.2, accessibility 0.15, content 0.25, ux 0.2, and functional 0.2. A missing category is left out and the remaining weights are renormalized. CSS health is not one of those categories, so it cannot move the overall score. The performance area inside CSS health is not the Lighthouse Performance score.

When no style block or stylesheet can be read, the score is absent and the report says: “No stylesheet or style block was available from the server-rendered page. CSS injected by JavaScript is not included.” Markup that appears only after client-side rendering is not in the fetch, so it is not in this score. If collecting the CSS throws, the report omits the CSS health section.