HTML validation and CSS validation feel like the same exercise and behave very differently. A browser meeting invalid HTML repairs it and carries on with a document tree you did not intend. A browser meeting an invalid CSS declaration simply throws that declaration away and applies the rest. The failure is contained, which makes CSS errors less dangerous and, oddly, harder to notice.
The rule is called error recovery and it works at three levels. An unknown property, or a value the property does not accept, kills that single declaration. A malformed selector kills the entire rule block it introduces. An unclosed brace swallows everything until the parser finds its footing again, sometimes several rules later.
.card {
colour: #333;
padding: 10px
margin: 20px;
}
Three problems in four lines. The British spelling is not a property, so it is discarded. The missing semicolon merges the next two lines into one nonsensical padding value, so both are discarded. Only the brace is fine. The visible result is a card with no colour, no padding and no margin, and nothing in the console to explain why.
.card {
color: #333;
padding: 10px;
margin: 20px;
}
A CSS validator produces a lot of output on a modern stylesheet, and most of it is noise. These are the ones that point at a real bug.
| Message | What it means | Action |
|---|---|---|
| Property X doesn't exist | A typo, or a property from another language | fix, the declaration is dead |
| Value Error: X is not a valid value | Wrong unit, missing unit, or a colour that is not a colour | fix |
| Parse Error | Usually a missing semicolon or brace | fix, it may be eating later rules |
| Unrecognized at rule | An at rule the checker does not know | check the spelling, then ignore if correct |
| Same colour for background and border | A style warning, not an error | your call |
Every prefixed property is flagged, because by definition it is not part of any specification. -webkit-appearance, -moz-osx-font-smoothing and their relatives are not mistakes, they are implementation specific extensions. The message is correct and useless at the same time.
The useful question is whether you still need them. Most of the prefixes copied from old tutorials have been unnecessary for years: gradients, transitions, transforms, border radius and flexbox all work unprefixed in every browser still in use. Deleting them shortens your stylesheet and removes most of the validator output in one go.
Variables are valid CSS, but the value of a custom property is deliberately unconstrained: it is stored as a token sequence and only interpreted when substituted. A checker cannot verify what it will become, so it either stays quiet or complains about something that is perfectly correct.
:root {
--brand: #186329;
--space: 12px;
}
.button {
background: var(--brand);
padding: var(--space);
}
A validator implements a snapshot of the specifications. Container queries, nesting, :has(), cascade layers and the newer colour functions may be reported as unknown simply because the checker has not caught up. Before changing anything, confirm the syntax against current browser support data rather than the validator.
If your stylesheet is generated by a preprocessor or a build step, validate the compiled file, not the source. A source file full of nesting, mixins and variables is not CSS and will produce a wall of meaningless errors. The compiled output is what browsers receive and what deserves checking.
The same applies to minified files: the validator handles them, but the line numbers it reports become useless. Keep a readable build around for checking, or use a source map.
A stylesheet referring to a class that no longer exists in the markup is silently dead. The reverse, markup carrying classes no stylesheet defines, is equally invisible. Neither is a validation error, and both are found the same way: by checking the markup and the styles together after a redesign.
This is where a site wide HTML check earns its place. If your pages are generated from templates, an error in one include file shows up on every page, and seeing the same message repeated across the whole list tells you immediately where to look. Our validator crawls the entire site and reports page by page.
The W3C runs a dedicated CSS checking service alongside the markup one, reachable from w3.org, and it accepts a URL, a file upload or pasted text. For day to day work a linter integrated into your editor catches the same mistakes as you type, which is considerably more pleasant than a report after the fact. Reference documentation for every property lives on MDN Web Docs.
For the markup side, see the common HTML errors page and the document structure guide.