Fixing CSS Validation Errors
A CSS validation error means the browser met something in your stylesheet that it could not understand, and threw it away without telling anyone. Sometimes that is a single colour on a single button. Sometimes a missing brace near the top of a file quietly disables half the site on mobile.
This guide explains how browsers recover from bad CSS, so you can predict how much a given error breaks, then works through each common type of error with the corrected code, and shows how to separate genuine mistakes from warnings about modern CSS the validator has not caught up with.
What the browser does with bad CSS
CSS parsers are built to keep going. The specification defines exactly how a browser recovers from each kind of mistake, and the recovery is always to discard something and carry on. How much gets discarded depends on where the mistake is:
| Mistake | What the browser throws away | How far the damage spreads |
|---|---|---|
Invalid value, e.g. padding: 10px 20 | That one declaration | Small: other declarations in the rule still apply |
Unknown property, e.g. colour: #333 | That one declaration | Small |
| Missing semicolon between two declarations | Both declarations, read as one invalid value | Small but confusing: the line that looks fine also fails |
One bad selector in a list, e.g. .a, .b:hovr | The whole rule, for every selector in the list | Medium: .a loses its styles too |
// comment before a rule | The next rule, because the slashes become part of its selector | Medium |
| Missing closing brace | Everything after it may be treated as part of the unclosed block | Large: can disable the rest of the file or one media query's worth of rules |
| Unclosed string or comment | Everything up to the next matching quote or */ | Large |
None of these produce a console error. The only way to see them is to validate the file, lint it, or notice that something on the page looks wrong and inspect it. That is why validation errors often survive for years: the page looks almost right, and the rule that failed was for a state nobody tested, such as a focus outline or a narrow screen.
Finding the errors
Validate what the browser receives
Run the CSS Checker on your pages. It validates the CSS against W3C standards alongside its other checks, so you see validation errors in the context of the stylesheets each page loads. For a single file, the W3C CSS Validation Service accepts a URL, an upload or pasted CSS, and has options for the CSS profile and for how vendor-prefixed properties are reported.
Validate the served output as well as your source files. A preprocessor, minifier or plugin can introduce errors that are not in the file you edit, and an error in the source may already have been removed by the build.
Use the browser's Styles pane
In Chrome, Edge or Firefox, inspect the element that looks wrong. Declarations the browser rejected are shown crossed out with a warning icon; hover the icon to see whether the problem is an invalid value or an unknown property name. This is the quickest way to confirm that an error you found actually affects a visible element.
Lint the source
Stylelint reads your source CSS, SCSS or Less and reports errors with the file and line. A minimal setup:
npm install --save-dev stylelint stylelint-config-standard
echo '{ "extends": "stylelint-config-standard" }' > .stylelintrc.json
npx stylelint "src/**/*.css"
Rules such as property-no-unknown, selector-pseudo-class-no-unknown, unit-no-unknown,
color-no-invalid-hex, no-invalid-double-slash-comments and declaration-block-no-duplicate-properties
catch most of the errors in this guide before they ever reach the browser.
The fix, step by step
Step 1
Validate the stylesheets you actually serve
Run the CSS Checker on your key templates and note each stylesheet with errors, then validate those files individually in the W3C CSS Validation Service using their live URLs. Work from the served files rather than your source, because the build can add or remove errors. Sort the results by file and line number, and note which errors come from your own code and which from a theme, plugin or third-party widget you cannot edit directly.
Step 2
Fix structural errors first
Start
with parse errors: missing or extra closing braces, unclosed strings, unclosed comments and //
line comments. These can cascade, so one fix often clears dozens of later errors that were never real.
Use your editor's bracket matching to find the unclosed block, correct it, and validate again before
going further. Replace // comments with /* */, which is the only comment syntax
plain CSS supports.
Step 3
Correct invalid values and units
Go
through each "value error". Add the missing unit to lengths such as margin: 10, which must
be 10px or another unit unless the value is zero. Fix colours with the wrong number of hex
digits, keywords that do not exist for that property, and missing semicolons that merge two declarations.
Replace curly quotes pasted from a word processor with straight ones in font names and content
values.
Step 4
Fix misspelt properties, pseudo-classes and at-rules
Correct typos such as colour, text-allign, :hove
and @medai. Pay most attention to misspelt pseudo-classes in selector lists, because a single
unknown one discards the whole rule for every selector in that list. Where a rule deliberately combines
a newer pseudo-class with older ones, split it into separate rules or wrap the list in :is(),
which is forgiving and simply ignores selectors it does not understand.
Step 5
Remove old browser hacks
Delete
hacks written for Internet Explorer, which is no longer supported by Microsoft: star and underscore property
hacks such as *zoom: 1 and _height: 1px, filter: progid:... declarations,
expression() values and conditional comment stylesheets. They produce validation errors
and do nothing in current browsers. If you still need different behaviour in older browsers, use @supports
feature queries, which are valid CSS and explain their intent clearly.
Step 6
Triage the remaining warnings
For each remaining message, decide whether it is a real mistake or valid modern CSS the validator does not yet recognise. Check the property or selector in the specification or on Can I Use and test it in current browsers. Vendor-prefixed properties are reported by design, since prefixes are not part of the standard. Record deliberate exceptions in a short comment so the next person does not waste time on them.
Step 7
Add a linter so errors cannot return
Add Stylelint with a standard configuration to your project and run it in your editor, in a pre-commit hook and in your build or CI, so a typo is caught before it is deployed. Add rules to your configuration for the specific errors you just fixed. Then run the CSS Checker again after each release, and after theme or plugin updates, which can bring new errors in from code you do not write.
Common errors with corrected code
These examples come from a fictional site, Oakfield Dental, and show the error as written and the corrected version.
/* Before */
.hero {
padding: 24 16px; /* unitless non-zero length */
colour: #1d3557; /* British spelling is not a CSS property */
background: #f1faee
border-radius: 8px; /* missing semicolon on the line above */
}
// Primary buttons /* not a CSS comment */
.btn, .btn:hovr { color: #fff; } /* one bad pseudo-class drops both */
@media (max-width: 40em) {
.nav { display: none; /* missing closing brace for this rule */
}
.footer { font-family: “Inter”, sans-serif; } /* curly quotes */
/* After */
.hero {
padding: 24px 16px;
color: #1d3557;
background: #f1faee;
border-radius: 8px;
}
/* Primary buttons */
.btn { color: #fff; }
.btn:hover { color: #fff; }
@media (max-width: 40em) {
.nav { display: none; }
}
.footer { font-family: "Inter", sans-serif; }
Errors from preprocessors
- Sass division. In current Dart Sass, a slash is no longer treated as division in
most cases. Code such as
$gap / 2is flagged by the compiler, and the output may contain a literal slash that is invalid for that property. Usemath.div()orcalc(). - Unescaped interpolation. Building a selector or value from variables can leave empty strings or stray characters. Validate the compiled CSS, not just the Sass.
- Nested media queries in Less or Sass. These compile correctly, but an unclosed brace in a nested block can produce output where large parts of the file end up inside one media query.
When the validator is wrong
The W3C validator is a helpful tool but not the final word. It checks your CSS against the specifications
it knows, and new features can reach browsers before the validator recognises them. Features that have
been reported as unknown at various times include container queries, cascade layers, native nesting,
:has(), colour functions such as color-mix() and light-dark(),
and newer units. Support improves over time, so re-test before assuming a message is a false alarm.
To decide quickly:
- Look up the feature on MDN or Can I Use and check that it is supported in the browsers your visitors use.
- Confirm in the browser's Styles pane that the declaration is not crossed out.
- If both are fine, the message is validator lag. Leave the code alone, and add a comment if it will confuse the next person to validate the file.
Custom properties are another source of confusion. The validator cannot know what a variable will
contain, so a value such as margin: var(--space) is accepted even if --space
holds something invalid. Those errors only show up in the browser, as a declaration that falls back to
its initial or inherited value.
Platform notes
WordPress
Errors often come from the Additional CSS box in the Customizer or from page builder custom CSS fields, which do little or no checking. Copy the contents into a validator before and after editing. Errors in a plugin's stylesheet should be reported to its developer; overriding them from a child theme only hides the symptom. See the WordPress CSS guide.
Shopify
Theme editor Custom CSS fields reject some input when you save, but an error in an asset file will
only show on the storefront. Validate custom.css and any edited theme assets. See the Shopify
CSS guide.
Build pipelines
Add Stylelint to the same place you run tests. Some minifiers repair or drop invalid declarations silently, which hides the problem in production but leaves it in your source, so lint before the minifier runs.
Stopping validation errors coming back
- Enable CSS validation in your code editor; most editors underline unknown properties and unclosed braces as you type.
- Run Stylelint in a pre-commit hook and in CI, with the configuration checked into the project.
- Treat CSS pasted from tutorials, AI tools or word processors as untested; paste it through a validator first.
- After fixing errors, check browser-prefix coverage and specificity conflicts, since both often surface once rules start applying again.
- Re-run the CSS Checker after each theme, plugin or app update.
1. Does CSS have to validate for my site to rank?
No. Google and other search engines do not use CSS validator results as a ranking factor, and plenty of well-ranked sites have validation warnings. Validation matters because every error means a style the browser discarded, which can break layouts, hide content or make buttons unreadable on some screens. Those problems affect visitors and can affect how usable the page is. Fix errors for the people using the site, and do not worry about warnings for valid modern CSS.
2. Why does one small error break so much of my page?
Because of how browsers recover. An invalid value only loses one declaration, but a missing closing brace can make the browser treat every rule after it as part of the unclosed block, and a single unknown pseudo-class in a selector list discards the whole rule for every selector in the list. So a one-character mistake near the top of a stylesheet, or inside a media query, can disable styles far away from where the typo is. Fix structural errors first.
3. What is the difference between a CSS error and a warning?
An error means the validator found something it considers invalid, such as an unknown property, a value of the wrong type or a parse error. Browsers will usually discard it too. A warning points out something valid but questionable, such as a vendor-prefixed property, a colour set without a background colour, or a duplicate declaration. Errors deserve fixing. Warnings deserve a look, but many are harmless or deliberate and can be left with a short comment explaining why.
4. Why does the validator flag CSS that works in my browser?
The validator checks against the specifications it knows, and new CSS features can ship in browsers before the validator adds support for them. Features such as nesting, container queries, cascade layers and new colour functions have all been reported as unknown at times. If the property works in current browsers, is documented on MDN, and is not crossed out in your browser's Styles pane, the message is validator lag. Leave the code alone and add a comment.
5. Should I remove vendor prefixes to pass validation?
Not automatically. Vendor prefixes are deliberately non-standard, so the validator reports them, but some are still needed for certain browsers. The better approach is to write standard, unprefixed CSS and let Autoprefixer add prefixes at build time based on a browserslist setting that matches your audience. Then remove hand-written prefixes that are no longer needed. The W3C validator has an option that changes how vendor extensions are reported, which reduces noise while you work.
6. Can I validate CSS inside a WordPress or Shopify theme?
Yes. Validate the stylesheet URLs the live site loads, which you can find in the page source or the Network panel of your browser's developer tools, or run the CSS Checker on the page. For CSS entered in the WordPress Customizer or the Shopify theme editor, copy it into the validator directly. Report errors in plugin, app or theme files to their developers, because your edits to those files are usually overwritten by the next update.
7. How do I stop CSS errors being deployed again?
Add a linter such as Stylelint with a standard configuration and run it automatically: in your editor as you type, in a pre-commit hook, and in your build or continuous integration. Add rules for the specific mistakes you have already fixed, such as unknown properties, invalid hex colours and double-slash comments. Then run the CSS Checker after each release and after theme or plugin updates, since those bring in code you did not write yourself.
The CSS Checker validates your CSS against W3C standards and also flags render-blocking and unused rules, specificity issues, prefix gaps and stylesheet size, so you can fix the errors that matter first.
Open CSS Checker Fixes โ