Skip to main content

CSS

Design helpers live under CSS pattern and CSS animations.

Parse resultParsed

Valid syntax

Valid CSS syntax (css-tree parse).

Free CSS Validator - Syntax Parse with css-tree, Not a Layout Engine

Parse CSS in the browser with css-tree. The default body { color: red; } is valid. css-tree recovers from many truncated blocks instead of throwing. Styles are never injected into this page.

What a CSS Validator Can and Cannot Claim

A CSS validator on this page is a grammar check. css-tree reads a stylesheet into an abstract syntax tree. If the library can build a tree, you see a pass. css-tree recovers from many truncated blocks instead of throwing; empty input is rejected. That is a useful gate before you commit a file or paste a snippet into a design system. It is not a screenshot of Chrome, not a specificity calculator, and not the W3C CSS Validation Service.

The default sample body { color: red; } is a complete rule: a type selector, a declaration block, a property, a value, and a semicolon. css-tree is a recovering parser. Remove the closing brace and you will often still get a pass - that is not a layout engine saying the file is pretty, it is an AST that tolerated a truncated block. Unknown properties can still parse as declarations - frobnicate: 1; is often grammatically fine even when no browser implements it. "Not supported in Safari 12" is a compatibility question this AST will not answer. Empty input is the error this UI always reports.

Nothing is injected into the document's style sheets. There is no <style> element, no element.style write, and no CSSOM insert. You can paste html { display: none; } and this page will not vanish. That is a product rule, not an accident. A validator that applied user CSS would be a layout toy and a security headache.

Vendor-specific grammar and every Working Draft are not fully reproduced. css-tree covers a large living CSS surface; it is still a library with a version, not the union of every browser's forgiving parser. If a draft at-rule fails here and works in nightly Chrome, believe the nightly for that experiment and treat this page as a portable syntax check.

How to Validate CSS Syntax - Step by Step

Checking a stylesheet here is a short loop:

  1. Paste CSS - Drop a .css file, a component module, or a snippet into the left panel. Click Sample to restore body { color: red; }.
  2. Read parse success or the first error - The right panel reports a css-tree pass when an AST can be built. A truncated block such as body { color: red often still parses. Empty input is rejected. A throw, when css-tree actually throws, includes a location.
  3. Fix and re-parse - Edit the source. The result updates as you type. The stylesheet is never applied to this document.
  4. Copy or clear - Copy the parse report. Clear wipes the editor and the draft stored under css-validator-input.

On a wide screen, drag the unique css-validator-split-track handle. That class name is exclusive to this tool so a resize listener cannot steal the JSON5 or JavaScript validator layout. Fullscreen is for reading a long error on a small laptop. Width is remembered in css-validator-panel-width.

Worked Example - Valid Rule versus Missing Brace

Input that parses

body { color: red; }

css-tree builds a stylesheet AST. This page reports valid syntax. The body of DevOkk.com does not turn red.

Truncated block - often still an AST

body { color: red

css-tree commonly recovers instead of throwing. Do not read a green check as "this file is finished." Read it as "the library built a tree." Empty input is the error this page always shows. When a throw does happen, the message includes a line and column - still not a rendered preview.

Input that parses but may be useless in a browser

.card { frobnicate: 12px; color: red; }

Unknown properties are still declarations at the grammar level. A pass here does not mean "this will paint." It means "this is a well-formed stylesheet according to css-tree."

Syntax versus Cascade, Specificity, and Support

CSS has several layers of "correct." This tool only occupies the first:

QuestionAnswered here?Where it actually lives
Are braces and declarations well-formed?Yescss-tree parse
Which rule wins in the cascade?NoBrowser CSSOM + DevTools
Is this selector unused?NoNeeds a DOM and a bundler linter
Does Safari 12 support this property?NoCan I Use, MDN, browser tests
Is contrast high enough?NoColor Studio
How large is the bundle?NoBundle size estimator

Forgiving browsers will skip a bad declaration and keep the rest of a rule. A strict parser may stop at the first unclosed block. If your production CSS "works" in Chrome and fails here, look for truncated at-rules, unclosed strings, or experimental syntax the library has not caught up with - not for cascade bugs.

When You Need a CSS Syntax Check

Pasting a snippet from a ticket

Design reviews still ship CSS in Slack and GitHub comments. A missing closing brace in a media query is easy to miss in a monospace dump. Paste it here before you drop it into a production stylesheet.

Generated CSS from a template

Server-rendered themes and email CSS generators concatenate strings. Concatenation errors show up as parse failures long before they show up as a visual bug. This page is a cheap first gate without standing up a browser.

Teaching declarations versus rules

Students confuse a declaration color: red; with a rule body { color: red; }. The default sample is a complete rule. Deleting the braces is a live lesson: a bare declaration is not a stylesheet.

Not a substitute for visual QA

Flex bugs, stacking contexts, and font loading will never appear in an AST dump. Use this for syntax. Use a real viewport for paint. Pattern and motion helpers live under CSS pattern and CSS animations.

Common CSS Syntax Failures css-tree Reports

  • Unclosed declaration blocks. Every { needs a matching }. Nested @media and @supports multiply the risk.
  • Unclosed strings and URLs. A missing quote in content or url() can swallow the rest of the file as one token.
  • Truncated at-rules. @media screen without a block is incomplete. @import still needs a valid url or string.
  • Stray semicolons in the wrong place or a property with no colon. Some of these are skipped by browsers and rejected here.
  • SCSS / Less / Stylus. Nesting, variables with a different sigil, mixins, and & parent selectors are preprocessors. This page parses CSS, not Sass. Compile first, then validate the output if you want a CSS AST check.
  • Tailwind @apply and other build-time at-rules may fail unless css-tree knows them. Treat a failure as "not plain CSS yet."

Custom Properties, At-Rules, and What css-tree Still Treats as Text

Custom properties such as --accent: #c00; are declarations. This page asks css-tree to parse custom properties, so a typical :root { --gap: 8px; } block should pass. That pass does not prove the variable is referenced, inherited, or registered with @property. A typo in a var() fallback can still parse and still fail at computed-value time in a browser.

At-rules are where grammar libraries diverge. @media, @supports, @import, @charset, @layer, @container, and @keyframes are common. Newer or experimental at-rules may tokenize as unknown at-rules rather than hard errors, or they may fail if the prelude is truncated. Treat an unknown-at-rule warning in a linter as different from a css-tree throw. This UI only surfaces throws: success or the first exception with a location.

Nested CSS (the native nesting spec, not Sass) is still settling in tooling. If your file uses & and nested blocks as shipped CSS, a pass here means css-tree's current grammar accepted it. A fail may mean you still need a preprocessor or a PostCSS nesting plugin before the file is "plain CSS" for this parser. Do not assume a fail is a browser fail; check the same snippet in the target engine.

Values are parsed when parseValue is on, which is the default on this page. That catches some truncated functions - an unclosed rgb( or url( - better than a declarations-only skim. It still will not know that color: redd is a misspelling of a named color. Invalid values are often dropped by browsers and still form a legal declaration node. Grammar is not a dictionary of every CSS keyword.

Minification and source maps are out of scope. A one-line stylesheet can parse and still be unreadable. Format it in your editor after it passes. Do not paste megabytes of generated CSS; the AST walk can hitch the tab the same way any in-browser parse can. Keep checks on the source you are about to commit, not on a production bundle dump.

css-tree versus the W3C Service versus a Browser's Forgiving Parser

The W3C CSS Validation Service historically mixed grammar with a profile of properties and a warning layer for vendor prefixes. Teams used it as a quality badge. It is a network service with a profile you choose. This page is an offline css-tree parse. It will not duplicate W3C warning codes, will not check CSS 2.1 versus CSS 3 profiles, and will not nag you about -webkit- prefixes. If you need that report, use the W3C service. If you need a private, local syntax gate, stay here.

Browsers are famously forgiving. A bad declaration is skipped; the next one in the same rule may still apply. An unknown at-rule may be ignored. That recovery is why a site can look "fine" with a missing semicolon in one property. css-tree is closer to a compiler front-end: unclosed blocks tend to throw. When Chrome paints and this page fails, believe both. Chrome recovered; your file is still a hazard for the next tool that is not a browser - a static extractor, an email CSS inliner, or a native WebView with a pickier engine.

PostCSS, Lightning CSS, and esbuild CSS each have their own parsers. They may accept syntax this library rejects, especially when plugins rewrite nesting or custom at-rules before emit. The right order is: run your pipeline, then validate the CSS that actually ships, or validate hand-written CSS that is already the output. Validating Sass before compile is the wrong layer.

Selectors can be grammatically fine and still match nothing. .btn .btn { color: red; } parses. Whether it matches your DOM is a document question. Specificity wars, !important, and cascade layers change paint without changing parse. Keep this tool in the commit checklist next to a formatter, not instead of visual QA.

Comments /* ... */ are part of CSS. Unclosed comments swallow the rest of the file. That shows up as a surprising parse error far below the missing */. If an error location looks unrelated, search upward for a comment. Strings have the same trap: a missing quote in content is a classic time sink.

Privacy - Parse Only, No Style Injection

The stylesheet never leaves the device. Drafts live under css-validator-input for up to 30 days. Panel width uses css-validator-panel-width. Those keys are unique so this tool cannot overwrite JSON5 or JavaScript drafts. Clear deletes the source immediately.

Because CSS is not applied, pasting * { position: fixed; } cannot overlay the UI. That is the difference between a validator and a live preview pane. If you need a playground that paints, use a dedicated CSS sandbox - not this page.

Frequently Asked Questions

What does this CSS validator check?

Syntax. css-tree parses the stylesheet. It does not compute cascade, specificity, or whether a property is supported in a given browser.

What is the default sample?

body { color: red; } is valid. css-tree is a recovering parser, so a missing brace often still produces an AST instead of a throw. Unknown properties still parse as declarations; they are not automatically “invalid CSS” at the grammar level. Empty input is rejected.

Is this the W3C CSS validator?

No. It is an in-browser css-tree parse. Vendor-specific grammar and every CSS draft are not fully reproduced.

Does it run or inject my CSS?

No. Nothing is applied to the page. There is no style injection.

Does the CSS leave the browser?

No. The draft is stored locally for up to 30 days.

Can I lint unused selectors?

Not here. Unused-selector analysis needs a DOM. Pair with your build linter.

Does a valid parse mean the CSS looks correct in every browser?

No. A declaration can parse and still be ignored by a browser, overridden by cascade, or fail at computed-value time. This page only reports whether css-tree could build an AST.

Is this CSS validator free?

Yes. No signup and no upload. Parse as much CSS as you need in the browser.

Related CSS & Validator Tools

Syntax is only one slice of a CSS workflow:

  • JavaScript Validator - Acorn parse for scripts, never eval. Pair it when a page has both CSS and JS snippets.
  • JSON Validator - For design tokens stored as JSON, not CSS.
  • Color Studio - Contrast and color work after the stylesheet parses.
  • Bundle size estimator - Payload size is not a parse error.
  • CSS pattern / CSS animations - Visual helpers, not grammar checks.