HTML Guides for parse error
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The media attribute tells the browser under which conditions a linked stylesheet (or other resource) should be applied. Its value must be a valid media query list as defined by the CSS Media Queries specification. When the W3C HTML Validator reports a parse error for this attribute, it means the value couldn’t be parsed as a valid media query. The browser may ignore the attribute entirely or behave unpredictably, potentially loading the stylesheet in all conditions or not at all.
Common causes of this error include:
- Typos in media types or features — e.g., scrren instead of screen, or max-widht instead of max-width.
- Missing parentheses around media features — e.g., max-width: 600px instead of (max-width: 600px).
- Invalid or stray characters — e.g., extra commas, semicolons, or unmatched parentheses.
- Using CSS syntax instead of media query syntax — e.g., writing @media screen or including curly braces.
- Incorrect logical operators — e.g., using or at the top level instead of a comma, or misspelling not or only.
- Server-side template placeholders left unresolved — e.g., media="{{mediaQuery}}" rendered literally.
Getting this right matters for standards compliance and predictable cross-browser behavior. Browsers are generally lenient and may try to recover from malformed media queries, but the recovery behavior isn’t guaranteed to be consistent. A broken media attribute can cause stylesheets to load when they shouldn’t (wasting bandwidth) or not load when they should (breaking layout). It also affects performance, since browsers use the media attribute to prioritize resource loading.
To fix the issue, verify that your media value is a syntactically correct media query. Use valid media types (screen, print, all), wrap media features in parentheses, and separate multiple queries with commas.
Examples
Incorrect: missing parentheses around media feature
<!-- ❌ Parse error: media features must be wrapped in parentheses -->
<link rel="stylesheet" href="responsive.css" media="max-width: 600px">
Correct: parentheses around media feature
<link rel="stylesheet" href="responsive.css" media="(max-width: 600px)">
Incorrect: typo in media type
<!-- ❌ Parse error: "scrren" is not a valid media type -->
<link rel="stylesheet" href="styles.css" media="scrren">
Correct: valid media type
<link rel="stylesheet" href="styles.css" media="screen">
Incorrect: using or instead of a comma to separate queries
<!-- ❌ Parse error: top-level "or" is not valid between media queries -->
<link rel="stylesheet" href="styles.css" media="screen or print">
Correct: comma-separated media query list
<link rel="stylesheet" href="styles.css" media="screen, print">
Incorrect: stray semicolon in the value
<!-- ❌ Parse error: semicolons are not valid in media queries -->
<link rel="stylesheet" href="styles.css" media="screen; (max-width: 768px)">
Correct: combining media type and feature with and
<link rel="stylesheet" href="styles.css" media="screen and (max-width: 768px)">
More valid media query examples
<!-- Simple media type -->
<link rel="stylesheet" href="print.css" media="print">
<!-- Apply to all media (default behavior, but explicit) -->
<link rel="stylesheet" href="base.css" media="all">
<!-- Multiple conditions with "and" -->
<link rel="stylesheet" href="tablet.css" media="screen and (min-width: 768px) and (max-width: 1024px)">
<!-- Using "not" to exclude a media type -->
<link rel="stylesheet" href="no-print.css" media="not print">
<!-- Multiple queries separated by commas (logical OR) -->
<link rel="stylesheet" href="special.css" media="(max-width: 600px), (orientation: portrait)">
<!-- Prefers-color-scheme for dark mode -->
<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">
If you’re unsure whether your media query is valid, try testing it in a browser’s developer tools by adding a <style> block with @media and the same query — if the browser highlights it as invalid, the same value will fail in the media attribute.
The sizes attribute tells the browser how wide an image will be displayed under different viewport conditions, allowing it to choose the best candidate from srcset before the page layout is calculated. Its value is a comma-separated list where each entry (except optionally the last) pairs a media condition with a CSS length. The final entry can be a bare length that serves as the default fallback. The full syntax looks like this:
(media-condition) length, (media-condition) length, fallback-length
Media conditions use the same grammar as CSS media queries. They must be enclosed in parentheses and can use logical operators like and, or, and not to combine sub-expressions. The slot size (length) that follows each condition must use a valid CSS length unit such as px, em, rem, vw, vh, vmin, vmax, or ch. Percentages are not valid in sizes slot lengths, and unitless numbers (other than 0) are also invalid.
This error matters for several reasons. First, if the browser cannot parse the sizes value, it falls back to a default of 100vw, which may cause it to download an unnecessarily large image — hurting performance and wasting bandwidth. Second, an invalid sizes attribute signals a misunderstanding of responsive image markup that could lead to layout or rendering issues. Third, standards-compliant HTML ensures consistent behavior across all browsers.
Common Parse Errors
Here are the most frequent mistakes that trigger this validation error:
- Missing parentheses around the media condition. Writing min-width: 600px instead of (min-width: 600px).
- Missing slot size after a condition. Each media condition must be followed by a length value, e.g., (min-width: 600px) 50vw. Writing (min-width: 600px), 100vw without a slot size after the condition is invalid — the browser interprets (min-width: 600px) alone as the entry.
- Using percentages as slot sizes. Values like 50% are not allowed; use viewport-relative units like 50vw instead.
- Unitless numbers. A slot size of 300 is invalid; it must be 300px or another valid length.
- Trailing or extra commas. A trailing comma after the last entry or double commas between entries will cause a parse error.
- Mixing up range syntax. Modern media query range syntax like (width >= 600px) is valid, but hybrid forms like (min-width <= 600px) are not. Use either the traditional (min-width: 600px) or the range form (width >= 600px).
- Invalid tokens or typos. Misspelled feature names (e.g., min-widht) or unsupported tokens will break parsing.
How to Fix
- Wrap every media condition in parentheses. Even simple conditions need them: (min-width: 600px).
- Follow each condition with a valid length. For example, (min-width: 600px) 50vw.
- End with a fallback length. The last item should be a bare length with no media condition, like 100vw.
- Use valid CSS length units for slot sizes — px, em, rem, vw, vh, etc. Never use %.
- Ensure your srcset uses w descriptors that match the intrinsic pixel widths of the image files, since sizes only works with width descriptors.
Examples
Incorrect: missing parentheses and missing slot size
The media condition lacks parentheses, and there is no slot size telling the browser how wide the image will be when the condition matches.
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="min-width: 600px, 100vw"
alt="A mountain landscape">
Correct: parentheses and slot size added
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(min-width: 600px) 50vw, 100vw"
alt="A mountain landscape">
Incorrect: percentage used as slot size
<img
src="banner-1200.jpg"
srcset="banner-600.jpg 600w, banner-1200.jpg 1200w"
sizes="(min-width: 768px) 50%, 100%"
alt="Promotional banner">
Correct: viewport units instead of percentages
<img
src="banner-1200.jpg"
srcset="banner-600.jpg 600w, banner-1200.jpg 1200w"
sizes="(min-width: 768px) 50vw, 100vw"
alt="Promotional banner">
Incorrect: trailing comma
<img
src="icon-256.png"
srcset="icon-128.png 128w, icon-256.png 256w"
sizes="(min-width: 1024px) 128px, 64px,"
alt="App icon">
Correct: trailing comma removed
<img
src="icon-256.png"
srcset="icon-128.png 128w, icon-256.png 256w"
sizes="(min-width: 1024px) 128px, 64px"
alt="App icon">
Incorrect: invalid range syntax mixing traditional and modern forms
<img
src="hero-1600.jpg"
srcset="hero-800.jpg 800w, hero-1600.jpg 1600w"
sizes="(min-width <= 600px) 100vw, 50vw"
alt="Hero image">
Correct: using proper range syntax
<img
src="hero-1600.jpg"
srcset="hero-800.jpg 800w, hero-1600.jpg 1600w"
sizes="(width <= 600px) 100vw, 50vw"
alt="Hero image">
Multiple conditions with a fallback
This example shows a fully valid sizes attribute with several breakpoints, combining traditional and modern range syntax across entries.
<img
src="article-1200.jpg"
srcset="article-400.jpg 400w, article-800.jpg 800w, article-1200.jpg 1200w"
sizes="(min-width: 1200px) 33vw, (min-width: 768px) 50vw, 100vw"
alt="Article thumbnail">
Using calc() in slot sizes
You can use calc() for more precise slot sizes. This is fully valid in the sizes attribute.
<img
src="card-800.jpg"
srcset="card-400.jpg 400w, card-800.jpg 800w"
sizes="(min-width: 960px) calc(33.33vw - 2rem), calc(100vw - 2rem)"
alt="Product card">
The sizes attribute tells the browser how wide an image will be displayed at different viewport sizes, so it can choose the best candidate from srcset. It only applies when srcset uses width descriptors (e.g., 480w, 800w). The value is a comma-separated list where:
- Each entry (except the last) is a media condition in parentheses followed by a CSS length — for example, (min-width: 800px) 50vw.
- The final entry is a fallback length with no media condition — for example, 100vw.
The browser evaluates the media conditions from left to right and uses the length from the first one that matches. If none match, it uses the fallback.
The media condition syntax mirrors CSS media queries but without the @media keyword. You can use logical operators like and, or, and not, and features like min-width, max-width, orientation, etc.
Why This Error Occurs
The validator parses the sizes value according to the HTML living standard and CSS Media Queries specification. A parse error is triggered when the value doesn’t conform to the expected grammar. Common causes include:
- Missing parentheses around the media condition: min-width: 600px 50vw instead of (min-width: 600px) 50vw.
- Missing length after a media condition: (min-width: 800px) with no length following it.
- Invalid or missing units on the length: 50 instead of 50vw, 50px, or 50rem.
- Trailing commas or extra separators: (min-width: 600px) 50vw, , 100vw.
- Invalid media feature syntax: typos like (minwidth: 600px) or using unsupported tokens.
- Using sizes with pixel-density descriptors: when srcset uses 1x, 2x instead of width descriptors, the sizes attribute is meaningless and can confuse validators.
Why It Matters
- Browser image selection: Browsers rely on a correctly parsed sizes value to pick the optimal image from srcset. A malformed value causes the browser to fall back to a default size (typically 100vw), which can result in downloading unnecessarily large images on small screens or blurry images on large screens.
- Standards compliance: Invalid sizes values violate the HTML specification and may behave unpredictably across different browsers.
- Performance: Correct sizes values are essential for responsive image optimization. Without them, you lose the bandwidth savings that srcset with width descriptors is designed to provide.
How to Fix It
- Wrap every media condition in parentheses: (min-width: 600px), not min-width: 600px.
- Always include a valid CSS length after each condition: (min-width: 600px) 50vw, not just (min-width: 600px).
- End with a fallback length that has no condition: 100vw.
- Use valid CSS length units: vw, px, em, rem, or calc() expressions.
- Remove trailing or duplicate commas.
- Omit sizes entirely if your srcset uses pixel-density descriptors (1x, 2x).
Examples
Incorrect: missing parentheses around the media condition
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="min-width: 600px 50vw, 100vw"
alt="A landscape photo">
Correct: parentheses added
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w"
sizes="(min-width: 600px) 50vw, 100vw"
alt="A landscape photo">
Incorrect: missing length after the media condition
<img
src="banner-800.jpg"
srcset="banner-400.jpg 400w, banner-800.jpg 800w"
sizes="(min-width: 700px), 100vw"
alt="A promotional banner">
The first entry (min-width: 700px) has no length value — the comma makes it look like a separate entry, but it’s incomplete.
Correct: length added after the condition
<img
src="banner-800.jpg"
srcset="banner-400.jpg 400w, banner-800.jpg 800w"
sizes="(min-width: 700px) 60vw, 100vw"
alt="A promotional banner">
Incorrect: using sizes with pixel-density descriptors
<img
src="avatar.jpg"
srcset="avatar@1x.jpg 1x, avatar@2x.jpg 2x"
sizes="(min-width: 600px) 80px, 40px"
alt="User avatar">
The sizes attribute is only meaningful with width descriptors (w). When srcset uses density descriptors (1x, 2x), omit sizes.
Correct: sizes removed for density descriptors
<img
src="avatar.jpg"
srcset="avatar@1x.jpg 1x, avatar@2x.jpg 2x"
alt="User avatar">
Incorrect: trailing comma
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w"
sizes="(min-width: 800px) 800px, 100vw,"
alt="Hero image">
Correct: trailing comma removed
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w"
sizes="(min-width: 800px) 800px, 100vw"
alt="Hero image">
Using sizes on a <source> inside <picture>
<picture>
<source
type="image/webp"
srcset="hero-480.webp 480w, hero-800.webp 800w, hero-1200.webp 1200w"
sizes="(min-width: 1200px) 1200px, (min-width: 800px) 800px, 100vw">
<img
src="hero-800.jpg"
srcset="hero-480.jpg 480w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(min-width: 1200px) 1200px, (min-width: 800px) 800px, 100vw"
alt="Hero image">
</picture>
Using compound media conditions
You can combine conditions with and:
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(min-width: 900px) and (orientation: landscape) 50vw, 100vw"
alt="A sample photo">
Full valid document
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Responsive Image Example</title>
</head>
<body>
<img
src="pic-800.jpg"
srcset="pic-400.jpg 400w, pic-800.jpg 800w"
sizes="(min-width: 600px) 50vw, 100vw"
alt="A picture demonstrating valid sizes usage">
</body>
</html>
When the CSS parser encounters a background-image value it cannot understand, it flags a parse error. This doesn’t necessarily mean the browser won’t render your styles — browsers are often more forgiving than validators — but it does indicate that your CSS doesn’t conform to the specification. Invalid CSS can lead to unpredictable rendering across different browsers, makes your code harder to maintain, and may cause styles to silently fail in certain environments.
Common causes of this error include:
- Missing the url() function around image paths.
- Unquoted or improperly quoted URLs containing special characters like spaces or parentheses.
- Typos in CSS function names (e.g., lnear-gradient instead of linear-gradient).
- Using vendor-prefixed values (e.g., -webkit-linear-gradient) in contexts where the validator expects standard CSS.
- Invalid gradient syntax, such as missing color stops, incorrect angle units, or malformed function arguments.
- Using CSS custom properties (variables) or newer syntax in a style attribute, which the validator’s CSS parser may not fully support.
To fix this, review the exact background-image declaration the validator is pointing to. Make sure all URLs are wrapped in url(), all gradients use correct function names and valid arguments, and all strings are properly quoted and closed.
Examples
Missing url() function
A bare file path without the url() wrapper is invalid:
<!-- ❌ Parse error: missing url() -->
<div style="background-image: /images/hero.jpg;"></div>
Wrap the path in url():
<!-- ✅ Correct -->
<div style="background-image: url('/images/hero.jpg');"></div>
Typo in gradient function name
<!-- ❌ Parse error: misspelled function -->
<div style="background-image: lnear-gradient(to right, red, blue);"></div>
<!-- ✅ Correct -->
<div style="background-image: linear-gradient(to right, red, blue);"></div>
Invalid gradient syntax
Missing color stops or using incorrect angle notation causes parse errors:
<!-- ❌ Parse error: invalid angle unit and missing second color stop -->
<div style="background-image: linear-gradient(45, red);"></div>
Angles need a unit (like deg), and gradients need at least two color stops:
<!-- ✅ Correct -->
<div style="background-image: linear-gradient(45deg, red, blue);"></div>
Unescaped special characters in URL
File paths with spaces or parentheses need to be quoted:
<!-- ❌ Parse error: unquoted URL with spaces -->
<div style="background-image: url(/images/my hero image.jpg);"></div>
<!-- ✅ Correct: quoted URL -->
<div style="background-image: url('/images/my hero image.jpg');"></div>
Vendor-prefixed values
Using non-standard prefixed syntax can trigger a parse error in the validator:
<!-- ❌ Parse error: vendor prefix not recognized by validator -->
<div style="background-image: -webkit-linear-gradient(left, red, blue);"></div>
Use the standard, unprefixed syntax instead. Modern browsers no longer need the prefix for gradients:
<!-- ✅ Correct: standard syntax -->
<div style="background-image: linear-gradient(to right, red, blue);"></div>
Multiple backgrounds with incorrect separator
Multiple background images must be separated by commas, not semicolons or spaces:
<!-- ❌ Parse error: wrong separator -->
<div style="background-image: url('a.png') url('b.png');"></div>
<!-- ✅ Correct: comma-separated -->
<div style="background-image: url('a.png'), url('b.png');"></div>
Moving styles to an external stylesheet
If the validator struggles with complex background-image values in inline style attributes, consider moving the CSS to a <style> block or external stylesheet, where the validator’s CSS parser handles them more reliably:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Background Image Example</title>
<style>
.hero {
background-image: url('hero.jpg');
background-size: cover;
}
</style>
</head>
<body>
<div class="hero"></div>
</body>
</html>
A CSS parse error means the validator’s CSS parser encountered something unexpected and could not make sense of the code from that point forward. Unlike many HTML errors that pinpoint a specific rule violation, a parse error is more general — the parser simply gave up trying to interpret the CSS. This can sometimes cause a cascade of additional errors, since the parser may lose track of context after the initial failure.
This matters because browsers handle broken CSS unpredictably. While most browsers are forgiving and will skip invalid rules, the way they recover varies. Styles may render differently across browsers, or entire rule blocks may be silently ignored. Valid CSS ensures consistent rendering, easier debugging, and better maintainability.
Common causes of CSS parse errors include:
- Missing semicolons between declarations
- Unclosed curly braces { or extra closing braces }
- Unclosed comments (/* without a matching */)
- Invalid or empty property values (e.g., color: ;)
- Unexpected characters such as stray text, unsupported tokens, or HTML markup inside <style> blocks
- Typos in property names or values (e.g., colr: red)
- Using CSS syntax that isn’t valid in an attribute context, such as placing selectors inside a style attribute
To fix the error, go to the line indicated by the validator and carefully inspect the CSS around that point. Look for the common issues listed above. Sometimes the actual mistake is on a line before the reported one — for example, a missing semicolon on line 5 might only cause a parse error on line 6.
Examples
Missing semicolon
A missing semicolon causes the parser to misinterpret where one declaration ends and the next begins.
❌ Incorrect:
<p style="color: red font-size: 16px">Hello</p>
✅ Fixed:
<p style="color: red; font-size: 16px">Hello</p>
Unclosed curly brace
A missing closing brace causes the parser to treat subsequent rules as part of the unclosed block.
❌ Incorrect:
<style>
.container {
margin: 0 auto;
padding: 20px;
.title {
font-size: 24px;
}
</style>
✅ Fixed:
<style>
.container {
margin: 0 auto;
padding: 20px;
}
.title {
font-size: 24px;
}
</style>
Unclosed comment
A comment that is never closed causes everything after it to be consumed by the parser as part of the comment.
❌ Incorrect:
<style>
/* Set the main color
body {
color: #333;
}
</style>
✅ Fixed:
<style>
/* Set the main color */
body {
color: #333;
}
</style>
Empty or invalid property value
Declaring a property with no value or a clearly invalid value triggers a parse error.
❌ Incorrect:
<div style="background-color: ;">Content</div>
✅ Fixed:
<div style="background-color: #f0f0f0;">Content</div>
Selectors inside an inline style attribute
The style attribute only accepts declarations (property-value pairs), not selectors or full rule blocks.
❌ Incorrect:
<div style="p { color: blue; }">Content</div>
✅ Fixed:
<div style="color: blue;">Content</div>
Stray characters or typos
Unexpected characters anywhere in CSS will cause parsing to fail.
❌ Incorrect:
<style>
.box {
width: 100px;;
height: 50px
border: 1px solid #ccc;
}
</style>
While a double semicolon (;;) is technically harmless in most parsers, a missing semicolon after height: 50px merges it with the next line, producing an invalid value.
✅ Fixed:
<style>
.box {
width: 100px;
height: 50px;
border: 1px solid #ccc;
}
</style>
If the validator points to a line but the cause isn’t obvious, try isolating sections of your CSS and validating them separately using the W3C CSS Validation Service. This can help narrow down the exact location of the problem.
When the W3C HTML Validator checks your document, it also validates any inline styles (in style attributes) and embedded stylesheets (in <style> elements). A CSS parse error occurs when the parser encounters something it cannot interpret according to CSS specifications. The “X” in the error message refers to the specific property, value, or token that triggered the failure.
Understanding CSS Parse Errors
CSS parse errors can stem from many different causes:
- Typos in property names or values — e.g., colr instead of color, or 10xp instead of 10px.
- Missing or extra punctuation — a forgotten semicolon, an extra colon, unmatched braces or parentheses.
- Invalid values for a property — using a value that doesn’t belong to that property’s grammar.
- Vendor-prefixed or non-standard syntax — properties like -webkit-appearance or -moz-osx-font-smoothing are not part of the CSS standard and will trigger parse errors in the validator.
- Modern CSS features not yet recognized — some newer CSS syntax may not be supported by the validator’s parser yet.
- Stray characters or encoding issues — invisible characters, smart quotes, or copy-paste artifacts from word processors.
While browsers are generally forgiving and will skip CSS they don’t understand, parse errors can indicate real bugs that cause styles to silently fail. Fixing them ensures your CSS is standards-compliant and behaves predictably across all browsers.
Common Causes and Fixes
Typos and syntax mistakes
The most frequent cause is a simple typo or a missing character. Always double-check the exact line the validator points to.
Missing semicolons
A forgotten semicolon between declarations can cause the parser to misinterpret subsequent properties.
Invalid or malformed values
Using values that don’t match the property’s expected syntax — such as omitting units, using incorrect function syntax, or providing the wrong number of arguments — will trigger parse errors.
Vendor prefixes
The W3C validator checks against the CSS specification. Vendor-prefixed properties and values are non-standard and will produce parse errors. While you may still need them in production, be aware that these will always flag in validation.
Examples
❌ Missing semicolon between declarations
<p style="color: red background-color: blue;">Hello</p>
The missing semicolon after red causes the parser to try to interpret red background-color: blue as a single value, resulting in a parse error.
✅ Fixed: semicolons separating declarations
<p style="color: red; background-color: blue;">Hello</p>
❌ Typo in property name
<style>
.box {
widht: 100px;
hieght: 200px;
}
</style>
✅ Fixed: correct property names
<style>
.box {
width: 100px;
height: 200px;
}
</style>
❌ Missing unit on a value
<style>
.container {
margin: 10;
padding: 20px;
}
</style>
Numeric values (other than 0) require a unit. The value 10 without a unit like px, em, or rem is invalid.
✅ Fixed: unit included
<style>
.container {
margin: 10px;
padding: 20px;
}
</style>
❌ Extra or misplaced characters
<style>
.title {
font-size:: 16px;
color: #3333;
}
</style>
The double colon after font-size and the 4-digit hex color #3333 (which is valid in CSS Color Level 4 but may not be recognized by all validator parsers) can trigger errors.
✅ Fixed: correct syntax
<style>
.title {
font-size: 16px;
color: #333333;
}
</style>
❌ Unmatched parentheses in a function
<style>
.overlay {
background: rgba(0, 0, 0, 0.5;
}
</style>
✅ Fixed: closing parenthesis added
<style>
.overlay {
background: rgba(0, 0, 0, 0.5);
}
</style>
Tips for Debugging Parse Errors
- Read the error message carefully. The validator usually points to the specific token or line that caused the failure.
- Validate CSS separately. Use the W3C CSS Validation Service for more detailed CSS-specific error messages.
- Check for invisible characters. If you copied CSS from a word processor, PDF, or website, hidden characters like zero-width spaces or smart quotes (" instead of ") may be present. Retype the line manually if in doubt.
- Simplify and isolate. If you can’t find the error, remove declarations one at a time until the error disappears, then inspect the last removed declaration closely.
Ready to validate your sites?
Start your free trial today.