HTML Guides for CSS
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 background-blend-mode property controls how an element’s background layers — including background images and background colors — blend with each other. Each value must be a valid blend mode keyword as defined in the CSS Compositing and Blending specification. The W3C validator flags this error when it encounters a value that doesn’t match any recognized keyword, which can happen due to typos, made-up values, or confusion with similar properties like mix-blend-mode.
While browsers typically ignore unrecognized CSS values and fall back to the default (normal), relying on this behavior is risky. It means the blending effect you intended simply won’t appear, and the silent failure can be hard to debug. Fixing validation errors ensures your styles work as intended across all browsers.
The complete list of valid values for background-blend-mode is:
- normal (default)
- multiply
- screen
- overlay
- darken
- lighten
- color-dodge
- color-burn
- hard-light
- soft-light
- difference
- exclusion
- hue
- saturation
- color
- luminosity
You can also specify multiple comma-separated values when an element has multiple background layers. Each value corresponds to a background layer in the same order.
Examples
Invalid values
These examples will trigger the validation error:
/* Typo: "multipley" is not a valid keyword */
.hero {
background-blend-mode: multipley;
}
/* "blend" is not a recognized value */
.banner {
background-blend-mode: blend;
}
/* Numeric values are not accepted */
.card {
background-blend-mode: 50%;
}
Corrected values
/* Fixed: correct spelling */
.hero {
background-blend-mode: multiply;
}
/* Fixed: use a valid blend mode keyword */
.banner {
background-blend-mode: overlay;
}
/* Fixed: use a keyword instead of a numeric value */
.card {
background-blend-mode: soft-light;
}
Multiple background layers
When you have multiple background images, provide a comma-separated list of valid blend modes:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Background Blend Mode Example</title>
<style>
.blended {
width: 300px;
height: 200px;
background-color: teal;
background-image: url("pattern.png"), url("photo.jpg");
background-blend-mode: screen, multiply;
}
</style>
</head>
<body>
<div class="blended">Blended background layers</div>
</body>
</html>
In this example, screen applies to the first background image layer and multiply applies to the second. Both are valid keywords, so no validation error is produced.
The background CSS property accepts a variety of value types: named colors (red, blue), hexadecimal codes (#fff, #ff0000), color functions (rgb(), hsl(), rgba()), gradient functions (linear-gradient(), radial-gradient()), image URLs, and CSS keywords like none, transparent, or inherit. The word from is not among these valid values.
Why this happens
This error most commonly appears in one of these scenarios:
-
Legacy WebKit gradient syntax. Older versions of Safari and Chrome used a proprietary syntax: -webkit-gradient(linear, left top, right top, from(#fff), to(#000)). The from() and to() functions are part of this deprecated, non-standard format. If this syntax is used without the -webkit- prefix—or if the validator encounters it—the word from gets flagged as an invalid color value.
-
Incorrectly written gradient shorthand. Some developers unfamiliar with the CSS gradient specification write something resembling natural language, like background: from #fff to #000, which has no meaning in CSS.
-
CSS from keyword in relative color syntax. CSS Color Level 5 introduces relative color syntax using the from keyword (e.g., rgb(from red r g b / 50%)). This is a newer feature that may not yet be recognized by the W3C CSS validator, which can lag behind the latest specifications. If you’re using this syntax intentionally, the error may be a false positive from the validator, but be aware that browser support may still be limited.
Why it matters
Invalid CSS values are silently ignored by browsers, meaning your intended background styling won’t be applied. The element will fall back to its default or inherited background, which can result in broken layouts, missing visual cues, or poor contrast that harms readability and accessibility. Using standard, valid CSS ensures consistent rendering across all browsers.
How to fix it
- Replace legacy -webkit-gradient() syntax with the standard linear-gradient() or radial-gradient() functions.
- Use valid color formats for solid backgrounds: hex codes, named colors, or color functions.
- If using relative color syntax (from keyword in CSS Color Level 5), understand that the validator may not yet support it. Consider adding a fallback value for broader compatibility.
Examples
Incorrect: legacy WebKit gradient syntax
The from() and to() functions in -webkit-gradient() are non-standard and will trigger this error if used as a background value:
<style>
.banner {
/* Non-standard syntax; "from" is not a valid CSS value */
background: -webkit-gradient(linear, left top, right top, from(#fff), to(#000));
}
</style>
<div class="banner">Legacy gradient</div>
Incorrect: made-up gradient shorthand
Writing gradient-like syntax without a proper CSS function is invalid:
<style>
.banner {
/* "from" and "to" are not valid CSS keywords here */
background: from #fff to #000;
}
</style>
<div class="banner">Invalid gradient</div>
Correct: standard linear gradient
Use linear-gradient() with a direction and comma-separated color stops:
<style>
.banner {
background: linear-gradient(to right, #fff, #000);
}
</style>
<div class="banner">Standard gradient</div>
Correct: solid color background
For a simple solid color, use any valid CSS color value:
<style>
.banner {
background: #fff;
}
</style>
<div class="banner">White background</div>
Correct: gradient with a fallback for older browsers
When using gradients, it’s good practice to provide a solid color fallback:
<style>
.banner {
background: #fff;
background: linear-gradient(to bottom, #ffffff, #cccccc);
}
</style>
<div class="banner">Gradient with fallback</div>
Correct: relative color syntax with a fallback
If you intentionally use CSS Color Level 5 relative color syntax and the validator flags from, provide a fallback and be aware of current browser support:
<style>
.banner {
background: rgb(255, 0, 0);
background: rgb(from red r g b / 50%);
}
</style>
<div class="banner">Relative color with fallback</div>
Always verify that your background values use standard CSS syntax. When in doubt, test your styles in the W3C CSS Validator and check browser support on Can I Use.
The background-image CSS property accepts a specific set of value types defined by the CSS specification. The most common are none (the default, meaning no image), the url() function pointing to an image file, and gradient functions like linear-gradient() or radial-gradient(). When the validator encounters a value that doesn’t match any of these patterns, it flags the error.
This issue often appears in inline style attributes within HTML, which is where the W3C HTML Validator checks your CSS. Common mistakes include providing a bare filename without url(), forgetting parentheses or quotes, using incorrect gradient syntax, or introducing typos in CSS function names.
Fixing this matters for several reasons. Browsers may silently ignore an invalid background-image declaration entirely, meaning your intended background simply won’t appear. This leads to broken visual designs that can be difficult to debug. Additionally, invalid CSS can cause parsing errors that may affect subsequent declarations in the same rule block.
How to fix it
- Wrap image paths in url() — A bare filename like background-image: photo.jpg is invalid. It must be background-image: url("photo.jpg").
- Use proper quoting — While quotes inside url() are technically optional for simple paths, always use them for paths containing spaces, parentheses, or special characters. Single or double quotes both work.
- Check gradient syntax — If using gradients, ensure the function name is correct (e.g., linear-gradient, not linear-gradiant) and the arguments follow valid syntax.
- Use recognized keywords — The only non-function keyword accepted is none. Values like transparent, auto, or arbitrary strings are not valid for this property.
Examples
Incorrect: bare filename without url()
<div style="background-image: hero.jpg;">
Content here
</div>
Incorrect: misspelled function name
<div style="background-image: urls('hero.jpg');">
Content here
</div>
Incorrect: missing parentheses in url
<div style="background-image: url 'hero.jpg';">
Content here
</div>
Incorrect: invalid keyword
<div style="background-image: transparent;">
Content here
</div>
Correct: using url() with a file path
<div style="background-image: url('hero.jpg');">
Content here
</div>
Correct: using none to explicitly set no background image
<div style="background-image: none;">
Content here
</div>
Correct: using a gradient function
<div style="background-image: linear-gradient(to right, #ff7e5f, #feb47b);">
Content here
</div>
Correct: multiple background images
<div style="background-image: url('overlay.png'), linear-gradient(to bottom, #000, #333);">
Content here
</div>
Correct: using a <style> block
<!DOCTYPE html>
<html lang="en">
<head>
<title>Background Image Example</title>
<style>
.banner {
background-image: url("banner.png");
background-size: cover;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<div class="banner">Welcome</div>
</body>
</html>
Always wrap image paths in the url() function, double-check function names for typos, and use quotes around paths that contain special characters. When in doubt, move your styles out of inline style attributes and into a <style> block or external stylesheet, which makes debugging CSS issues much easier.
The linear-gradient() function went through several syntax revisions during CSS standardization. Early drafts and vendor-prefixed implementations (like -webkit-linear-gradient()) used bare direction keywords such as top, bottom left, etc., where the keyword indicated the starting point of the gradient. The final standard, defined in the CSS Images Module Level 3 and Level 4 specifications, changed this so that direction keywords use the to prefix and indicate the ending point of the gradient. For example, the old linear-gradient(top, #fff, #000) meant “start at the top and go to the bottom,” while the correct modern equivalent is linear-gradient(to bottom, #fff, #000).
This matters because the old syntax without to is not valid CSS per the current specification. While some browsers may still interpret the legacy syntax for backward compatibility, relying on it is risky — behavior can vary across browsers, and it will trigger validation errors. Using standard-compliant CSS ensures consistent rendering and forward compatibility.
How to fix it
Replace the bare direction keyword with the correct to syntax. Note that the direction meaning is inverted: the old syntax specified where the gradient starts, while the new syntax specifies where it goes to.
Here’s a quick mapping from old to new syntax:
| Old (invalid) | New (valid) | Angle equivalent |
|---|---|---|
| top | to bottom | 180deg |
| bottom | to top | 0deg |
| left | to right | 90deg |
| right | to left | 270deg |
| top left | to bottom right | N/A (use to syntax) |
Important: Notice that top in the old syntax means “start at top, go to bottom.” So the modern equivalent is to bottom, not to top. If the validator message says the argument should be to top, it means you wrote top — but be sure you understand which direction your gradient should actually go before blindly replacing it. If you truly want the gradient to go toward the top, use to top. If you want it to go from the top downward, use to bottom.
If you don’t specify a direction at all, linear-gradient() defaults to to bottom (top-to-bottom), which is often what you want.
Examples
Invalid: bare direction keyword
<div style="background: linear-gradient(top, #ffffff, #000000);">
Content
</div>
The bare keyword top is not valid in the standard linear-gradient() syntax and will trigger the validator error.
Fixed: using the to keyword
<div style="background: linear-gradient(to bottom, #ffffff, #000000);">
Content
</div>
Since the old top meant “start at the top,” the equivalent standard syntax is to bottom.
Fixed: using an angle
<div style="background: linear-gradient(180deg, #ffffff, #000000);">
Content
</div>
An angle of 180deg produces the same top-to-bottom gradient.
Full document example
<!DOCTYPE html>
<html lang="en">
<head>
<title>Gradient Example</title>
<style>
.box {
width: 200px;
height: 100px;
/* Valid: direction keyword with "to" */
background: linear-gradient(to top, #ffffff, #000000);
}
.box-angle {
width: 200px;
height: 100px;
/* Valid: angle equivalent of "to top" */
background: linear-gradient(0deg, #ffffff, #000000);
}
.box-default {
width: 200px;
height: 100px;
/* Valid: no direction specified, defaults to "to bottom" */
background: linear-gradient(#ffffff, #000000);
}
</style>
</head>
<body>
<div class="box"></div>
<div class="box-angle"></div>
<div class="box-default"></div>
</body>
</html>
All three approaches are valid. Choose whichever is clearest for your use case — the to keyword syntax is generally the most readable, while angles offer more precision for diagonal or non-cardinal directions.
The background CSS property is a shorthand that can accept values for background-color, background-image, background-position, background-size, background-repeat, background-origin, background-clip, and background-attachment. When the validator encounters an unrecognized value, it tries to match it against individual sub-properties like background-color. If the value doesn’t match any of them, you’ll see this error.
Common causes include typos in color names (e.g., bleu instead of blue), malformed hex codes (e.g., #gggggg or a missing #), incorrect function syntax (e.g., rgb(255 0 0 with a missing parenthesis), or using values that simply don’t exist in CSS. This error can also appear when a CSS custom property (variable) is used in inline styles and the validator can’t resolve it, or when a browser-specific value is used that isn’t part of the CSS specification.
Fixing this issue ensures your styles render predictably across browsers. While browsers are often forgiving and may ignore invalid declarations silently, relying on that behavior can lead to inconsistent rendering. Standards-compliant CSS is easier to maintain and debug.
How to Fix
- Check for typos in color names, hex codes, or function syntax.
- Verify the value format — hex colors need a # prefix, rgb() and rgba() need proper comma-separated or space-separated values with closing parentheses.
- Use background-color instead of the shorthand background if you only intend to set a color. This makes your intent clearer and reduces the chance of conflicting shorthand values.
- Remove vendor-prefixed or non-standard values that the validator doesn’t recognize.
Examples
Incorrect — Typo in color name
<div style="background: aquaa;">Content</div>
aquaa is not a valid CSS color name, so the validator rejects it.
Correct — Valid color name
<div style="background: aqua;">Content</div>
Incorrect — Malformed hex code
<div style="background: #xyz123;">Content</div>
Hex color codes only allow characters 0–9 and a–f.
Correct — Valid hex code
<div style="background: #00a123;">Content</div>
Incorrect — Missing hash symbol
<div style="background: ff0000;">Content</div>
Without the #, the validator interprets ff0000 as an unknown keyword.
Correct — Hex code with hash
<div style="background: #ff0000;">Content</div>
Incorrect — Broken rgb() syntax
<div style="background: rgb(255, 0, 300);">Content</div>
RGB channel values must be between 0 and 255 (or 0% to 100%).
Correct — Valid rgb() value
<div style="background: rgb(255, 0, 128);">Content</div>
Correct — Using background-color for clarity
When you only need to set a color, prefer the specific background-color property over the shorthand:
<div style="background-color: rgba(255, 0, 0, 0.5);">Semi-transparent red</div>
Correct — Valid shorthand with image and other properties
<div style="background: url('image.jpg') no-repeat center / cover;">Content</div>
Note the / between background-position (center) and background-size (cover) — this is required syntax in the shorthand.
The border-radius property accepts one to four values, each of which must be a valid <length> or <percentage>. You can also specify elliptical corners using a / separator with up to four values on each side. Any value that falls outside this syntax — such as a bare number without a unit, a misspelled keyword, a negative value, or a var() reference the validator can’t resolve — will trigger this error.
Here are the most common reasons this error appears:
- Missing units: Writing border-radius: 10 instead of border-radius: 10px. CSS requires explicit units for all non-zero length values.
- Invalid keywords: Using a keyword like border-radius: large that isn’t part of the CSS specification.
- Negative values: The border-radius property does not accept negative lengths or percentages.
- Unresolvable var() references: The W3C validator performs static analysis and cannot evaluate CSS custom properties. If you use var(--my-radius) in an inline style attribute, the validator has no way to confirm the variable holds a valid value, so it flags it as an error.
- Malformed shorthand: Incorrect use of the / separator or too many values, such as border-radius: 10px 5px / 20px 15px 10px 5px 3px.
This matters for standards compliance and cross-browser consistency. While browsers are generally forgiving and will ignore invalid property values, this means the style silently fails — your element won’t get the rounded corners you intended. Catching these errors during validation helps prevent subtle visual bugs.
How to fix it
- Add units to any bare numeric values (except 0, which doesn’t need a unit).
- Remove negative values — use 0 as the minimum.
- Check shorthand syntax — you can provide one to four values, optionally followed by / and one to four more values for elliptical radii.
- Replace unresolvable var() references with static values for validation purposes, or move them into a <style> block where the custom property is defined (though the validator may still flag var() usage).
- Use valid units such as px, em, rem, %, vw, etc.
Examples
Invalid: missing unit on a non-zero value
<div style="border-radius: 10;"></div>
Fixed: adding the correct unit
<div style="border-radius: 10px;"></div>
Invalid: negative value
<div style="border-radius: -5px;"></div>
Fixed: using a non-negative value
<div style="border-radius: 5px;"></div>
Invalid: unrecognized keyword
<div style="border-radius: round;"></div>
Fixed: using a valid percentage for a circular shape
<div style="border-radius: 50%;"></div>
Invalid: var() in inline style that the validator cannot resolve
<div style="border-radius: var(--my-radius);"></div>
Fixed: defining the custom property in a stylesheet
<!DOCTYPE html>
<html lang="en">
<head>
<title>Border Radius Example</title>
<style>
:root {
--my-radius: 8px;
}
.rounded {
border-radius: var(--my-radius);
}
</style>
</head>
<body>
<div class="rounded">Rounded corners via custom property</div>
</body>
</html>
Note that even with the custom property properly defined, the W3C CSS validator may still flag var() usage because it performs static analysis without evaluating custom properties. This is a known limitation. If full validator compliance is important, use static values directly:
<div style="border-radius: 8px;"></div>
Valid shorthand with elliptical radii
The / syntax lets you define horizontal and vertical radii separately:
<div style="border-radius: 10px 20px / 5px 15px;"></div>
This sets horizontal radii of 10px and 20px (alternating corners) and vertical radii of 5px and 15px, creating elliptical corners. Both sides of the / follow the same one-to-four value pattern.
The border-style property controls the visual pattern of a border — whether it appears as a solid line, a series of dots, dashes, or other decorative styles. Its valid values are: none, hidden, dotted, dashed, solid, double, groove, ridge, inset, and outset.
The keyword thick is a valid value for border-width, which controls how wide or heavy the border appears. It’s one of three named width keywords: thin, medium, and thick. When thick is mistakenly used as a border-style value, the browser cannot interpret the declaration, and the border may not render at all or may fall back to unexpected defaults.
This is a common mix-up because people often think of a “thick border” as a single concept, but CSS separates the concern into two distinct properties: the style (what it looks like) and the width (how thick it is). Both must be set correctly for the border to display as intended. Without a valid border-style, most browsers default to none, meaning no border is visible regardless of other border properties.
To fix the issue, replace thick in your border-style declaration with a valid style keyword, and move thick to border-width if you want a heavier border. Alternatively, you can use the border shorthand to set width, style, and color in a single declaration.
Examples
Incorrect: using thick as a border style
<div style="border-style: thick;">This border will not render correctly.</div>
The value thick is not recognized for border-style, so the declaration is invalid.
Correct: separating style and width
<div style="border-style: solid; border-width: thick;">This has a thick solid border.</div>
Here, solid defines the border pattern and thick defines the border width — each value is used with the correct property.
Correct: using a specific pixel width
<div style="border-style: dashed; border-width: 4px;">This has a 4px dashed border.</div>
You can use any length value (like 4px or 0.25em) for border-width instead of the thick keyword for more precise control.
Correct: using the border shorthand
<div style="border: thick solid #333;">This uses the border shorthand.</div>
The border shorthand accepts width, style, and color in any order. This is often the most concise way to define a border and avoids confusion between the individual properties.
The border shorthand property lets you set the width, style, and color of an element’s border in a single declaration. The CSS specification allows up to three values, each corresponding to one of the longhand properties: border-width, border-style, and border-color. Each component may appear at most once, and the browser determines which value maps to which component based on the value’s type. When the validator encounters more values than expected or a value it can’t match to any of the three components, it raises this error.
This error commonly occurs for several reasons:
- Too many values — Providing four values (like you might with margin or padding) doesn’t work with border. Unlike box-model spacing properties, border does not accept per-side values in its shorthand.
- Misspelled keywords — A typo like sollid instead of solid, or doted instead of dotted, produces an unrecognized value.
- Invalid or unsupported values — Using values that don’t belong to any of the three components, such as border: 2px solid black inset (mixing shorthand with a style that creates a duplicate).
- Missing spaces — Writing 1pxsolid black instead of 1px solid black creates an unrecognized token.
- Using border syntax for border-radius or other properties — Accidentally placing values like 5px 10px 5px 10px on border instead of on border-radius.
Fixing the issue means ensuring your border value contains only recognized values, with no more than one from each category:
- Width: A length (e.g., 1px, 0.5em), 0, or a keyword (thin, medium, thick).
- Style: One of none, hidden, dotted, dashed, solid, double, groove, ridge, inset, or outset.
- Color: Any valid CSS color (e.g., red, #333, rgb(0, 0, 0), transparent).
If you need different borders on each side, use the side-specific properties (border-top, border-right, border-bottom, border-left) or the individual longhand properties (border-width, border-style, border-color), which do accept multiple values for each side.
Examples
Incorrect: too many values
<div style="border: 1px 2px solid black;">Content</div>
This provides two width values (1px and 2px), which the border shorthand does not allow. If you want different widths per side, use border-width separately.
Incorrect: misspelled keyword
<div style="border: 2px sollid red;">Content</div>
The value sollid is not a recognized border style, causing the validator to reject the declaration.
Incorrect: four-value syntax used on border
<div style="border: 1px 2px 1px 2px solid grey;">Content</div>
The border shorthand does not support per-side values. This syntax is valid for border-width, not for border.
Correct: standard shorthand with all three components
<div style="border: 2px solid black;">Content</div>
Correct: omitting optional components
You don’t need to provide all three values. Any omitted component resets to its initial value (medium, none, and currentcolor respectively).
<p style="border: solid;">Content</p>
Correct: two components in any order
<p style="border: dashed #00f;">Content</p>
Correct: different borders per side using longhand properties
<div style="border-width: 1px 2px 1px 2px; border-style: solid; border-color: grey;">Content</div>
Correct: using side-specific shorthand properties
<div style="border-top: 1px solid red; border-bottom: 2px dashed blue;">Content</div>
The border-width property controls the thickness of an element’s border. According to the CSS specification, its accepted values fall into two categories:
- Length values — any valid CSS length such as 1px, 0.25em, 2rem, 3pt, or 0.1cm. The value must not be negative.
- Keywords — exactly three are defined: thin, medium, and thick. These map to implementation-defined sizes but are guaranteed to maintain the relationship thin ≤ medium ≤ thick.
A bare number like 5 (without a unit) is not valid, even though some browsers may silently accept it. Similarly, words like large, bold, normal, or color values like red are not valid border-width values. Percentage values (e.g., 10%) are also not accepted for border-width, unlike many other CSS properties that accept lengths.
This matters for several reasons. First, invalid CSS values cause the declaration to be ignored entirely, meaning the border may not render as intended — or may fall back to the initial value of medium, producing unexpected results. Second, relying on browser error-recovery behavior leads to inconsistent rendering across different browsers and versions. Third, valid CSS ensures your stylesheets are maintainable and predictable.
Common causes of this error include:
- Missing units — writing border-width: 2 instead of border-width: 2px. The only unitless length allowed in CSS is 0.
- Misspelled or invented keywords — using large, small, normal, or none instead of thin, medium, or thick.
- Wrong value type — accidentally using a color name, percentage, or other non-length value.
- Typos in units — writing 5xp instead of 5px.
To fix the issue, locate the offending border-width declaration and replace the invalid value with a proper CSS length (including its unit) or one of the three accepted keywords.
Examples
Invalid: using a non-existent keyword
<style>
.box {
border-style: solid;
border-width: large; /* "large" is not a valid border-width value */
}
</style>
<div class="box">Content</div>
Fixed: using a valid keyword
<style>
.box {
border-style: solid;
border-width: thick;
}
</style>
<div class="box">Content</div>
Invalid: missing unit on a number
<style>
.alert {
border: solid;
border-width: 3; /* unitless number is not valid */
}
</style>
<div class="alert">Warning</div>
Fixed: adding a proper unit
<style>
.alert {
border: solid;
border-width: 3px;
}
</style>
<div class="alert">Warning</div>
Invalid: using a percentage
<style>
.panel {
border-style: solid;
border-width: 5%; /* percentages are not valid for border-width */
}
</style>
<div class="panel">Panel</div>
Fixed: using a length value instead
<style>
.panel {
border-style: solid;
border-width: 0.3em;
}
</style>
<div class="panel">Panel</div>
Using multiple values with shorthand
The border-width property accepts one to four values (for top, right, bottom, left), and each must independently be valid:
<style>
.card {
border-style: solid;
border-width: thin 2px medium 1px;
}
</style>
<div class="card">Card content</div>
Replace any invalid border-width value with a recognized CSS length (always including the unit, except for 0) or one of the keywords thin, medium, or thick to resolve the validation error.
The box-shadow property applies one or more shadow effects to an element’s box. The W3C CSS validator checks that each value in the declaration conforms to the specification. When it encounters something it doesn’t recognize — such as a unitless number (other than 0), a misspelled keyword, or values arranged in the wrong order — it reports that the value is not valid for box-shadow.
The correct syntax for a single box-shadow value is:
box-shadow: none | [inset? && <offset-x> <offset-y> <blur-radius>? <spread-radius>? <color>?]
- inset (optional): If present, the shadow is drawn inside the element’s border.
- <offset-x> and <offset-y> (required): Horizontal and vertical offsets. Must be valid CSS lengths with units (e.g., px, em, rem). The value 0 is the only length that doesn’t require a unit.
- <blur-radius> (optional): Must be a non-negative length. Defaults to 0.
- <spread-radius> (optional): Can be positive or negative. Defaults to 0. You can only include this if you also include <blur-radius>.
- <color> (optional): Any valid CSS color. Can appear at the beginning or end of the value list.
Common causes of this validation error include:
- Missing units on length values — Writing 10 10 instead of 10px 10px.
- Invalid or misspelled keywords — Using something like outerbox or shadows instead of inset or none.
- Too many or too few values — Providing five length values when the maximum is four.
- Vendor prefixes — Using -webkit-box-shadow or non-standard values that the standard validator rejects.
- Invalid color values — Using a malformed color like rgb(0,0,0,0.5) (missing the a in rgba for CSS3 validation) or a typo in a named color.
- Incorrect value order — Placing the color between the length values instead of at the start or end.
Fixing this issue ensures your CSS is standards-compliant, which improves cross-browser consistency and reduces the risk of unexpected rendering behavior.
Examples
Missing units on length values
Unitless numbers (except 0) are not valid CSS lengths. This is one of the most common triggers for this error.
<!-- ❌ Invalid: missing units on offset values -->
<div style="box-shadow: 10 10 5 rgba(0,0,0,0.5);">
Shadow text
</div>
<!-- ✅ Valid: all lengths have proper units -->
<div style="box-shadow: 10px 10px 5px rgba(0,0,0,0.5);">
Shadow text
</div>
Invalid keyword
Only none and inset are valid keywords for box-shadow. Any other keyword triggers the error.
<!-- ❌ Invalid: "outset" is not a recognized keyword -->
<div style="box-shadow: outset 4px 4px 8px #333;">
Shadow text
</div>
<!-- ✅ Valid: using the correct "inset" keyword -->
<div style="box-shadow: inset 4px 4px 8px #333;">
Shadow text
</div>
Color value in the wrong position or malformed
The color value should appear either first or last in the shadow definition. Some validators are strict about placement, and a malformed color will always fail.
<!-- ❌ Invalid: color placed between length values -->
<div style="box-shadow: 2px red 2px 5px;">
Shadow text
</div>
<!-- ✅ Valid: color at the end -->
<div style="box-shadow: 2px 2px 5px red;">
Shadow text
</div>
Using zero without units alongside other values
While 0 alone doesn’t require a unit, mixing it into the declaration is fine — just make sure other values have proper units.
<!-- ✅ Valid: 0 doesn't need a unit -->
<div style="box-shadow: 0 0 10px 2px rgba(0,0,0,0.75);">
Shadow text
</div>
Multiple shadows
Multiple shadow values are separated by commas. Each individual shadow must independently follow the correct syntax.
<!-- ✅ Valid: two properly formatted shadows -->
<div style="box-shadow: 2px 2px 5px #888, inset 0 0 10px 2px blue;">
Multiple shadows
</div>
Vendor-prefixed property
The W3C validator does not recognize vendor-prefixed properties. If you need them for legacy browser support, keep the standard property alongside.
<!-- ❌ Triggers a warning or error in the validator -->
<div style="-webkit-box-shadow: 3px 3px 6px #000;">
Shadow text
</div>
<!-- ✅ Valid: use the standard property -->
<div style="box-shadow: 3px 3px 6px #000;">
Shadow text
</div>
The clip-path property defines a clipping region that controls which parts of an element are visible. It accepts a specific set of value types, and any deviation from the expected syntax will trigger a validation error. The validator checks your CSS against the specification and flags values that don’t conform.
The accepted value types for clip-path are:
- none — No clipping (the default).
- Basic shape functions — inset(), circle(), ellipse(), polygon(), and path().
- url() reference — Points to an SVG <clipPath> element, e.g., url(#myClip).
- Geometry-box keywords — border-box, padding-box, content-box, margin-box, fill-box, stroke-box, view-box. These can be used alone or combined with a basic shape.
Here are the most common mistakes that cause this error:
- Missing units on length values. Writing circle(50 at 50% 50%) is invalid because 50 needs a unit like px, em, or %. The value 0 is the only length that doesn’t require a unit.
- Wrong separators. In circle() and ellipse(), the position coordinates after at must be separated by spaces, not commas. In polygon(), each coordinate pair uses a space between x and y, while commas separate the points from each other.
- Malformed path() data. The SVG path string inside path() must be wrapped in quotes, e.g., path("M0 0 L100 0 L100 100 Z").
- Typos or unsupported functions. Using a function name the specification doesn’t define, or misspelling one like cirlce(), will trigger the error.
- Invalid polygon() fill-rule. If you specify a fill rule in polygon(), it must be nonzero or evenodd, followed by a comma before the first point.
Getting clip-path syntax right matters for standards compliance and cross-browser consistency. Browsers may silently ignore an invalid clip-path value, meaning your intended visual effect simply won’t appear — and you may not realize why. Validating your CSS catches these issues early.
Here is a quick reference for the correct syntax of each basic shape function:
- circle(<radius> at <cx> <cy>) — Radius is a length or percentage. Position uses spaces, not commas.
- ellipse(<rx> <ry> at <cx> <cy>) — Both radii are lengths or percentages.
- inset(<top> <right> <bottom> <left> round <border-radius>) — Offsets are lengths or percentages. The round keyword and border-radius are optional.
- polygon([<fill-rule>,] <x1> <y1>, <x2> <y2>, ...) — Space between x and y within a point; comma between points.
- path("<SVG path data>") — Path data string must be quoted.
Examples
Invalid clip-path values
<style>
/* Invalid: unitless radius; comma between position coordinates */
.clip-a {
clip-path: circle(50 at 50%, 50%);
}
/* Invalid: commas between x and y within each point */
.clip-b {
clip-path: polygon(0%, 0%, 100%, 0%, 100%, 100%, 0%, 100%);
}
/* Invalid: path data not wrapped in quotes */
.clip-c {
clip-path: path(M0 0 L100 0 L100 100 Z);
}
/* Invalid: misspelled function name */
.clip-d {
clip-path: cirlce(50% at 50% 50%);
}
</style>
Valid clip-path values
<style>
/* Valid circle: radius has a unit; position uses spaces */
.clip-a {
clip-path: circle(50px at 50% 50%);
}
/* Valid polygon: space between x and y, commas between points */
.clip-b {
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}
/* Valid path: SVG data is quoted */
.clip-c {
clip-path: path("M0 0 L100 0 L100 100 Z");
}
/* Valid inset with rounded corners */
.clip-d {
clip-path: inset(10% 20% 10% 20% round 8px);
}
/* Valid geometry-box keyword combined with a shape */
.clip-e {
clip-path: padding-box circle(50% at 50% 50%);
}
/* Valid: referencing an SVG clipPath */
.clip-f {
clip-path: url(#roundClip);
}
</style>
Full example with SVG <clipPath> reference
<!doctype html>
<html lang="en">
<head>
<title>Valid clip-path with SVG reference</title>
<style>
.clipped {
clip-path: url(#roundClip);
width: 200px;
height: 200px;
background: coral;
}
</style>
</head>
<body>
<svg width="0" height="0" aria-hidden="true">
<clipPath id="roundClip" clipPathUnits="objectBoundingBox">
<circle cx="0.5" cy="0.5" r="0.5"></circle>
</clipPath>
</svg>
<div class="clipped">Clipped element</div>
</body>
</html>
When you encounter this validation error, carefully check the value reported in the error message. Compare it against the accepted syntax for the function you’re using, paying close attention to units, separators, and quoting. Small syntax differences — a comma where a space should be, or a missing unit — are the most frequent culprits.
The CSS cursor property controls the appearance of the mouse pointer when it hovers over an element. The value hand was introduced by early versions of Internet Explorer (IE 5.5 and earlier) as a proprietary extension to show a pointing-hand cursor over clickable elements. However, this value was never part of any CSS specification, and no other browser adopted it. The W3C-standard equivalent is pointer, which has been supported by all browsers — including Internet Explorer 6 and later — for over two decades.
When the W3C validator encounters cursor: hand, it flags it as an invalid value because hand does not exist in the CSS specification’s list of accepted cursor values. While some legacy browsers may still interpret it, modern browsers will simply ignore the invalid declaration, meaning your clickable elements won’t display the expected hand cursor for many users.
Beyond validation, using non-standard CSS values can cause inconsistent behavior across browsers and platforms. The pointer value is universally supported and is the correct way to signal that an element is interactive, such as a link, button, or any custom clickable region.
To fix this issue, replace every instance of cursor: hand with cursor: pointer in your stylesheets. If you need to support extremely old versions of Internet Explorer (IE 5.5 or earlier), you can declare both values — the browser will use whichever it recognizes — though this is almost never necessary today.
Examples
Invalid CSS
The value hand is not recognized by the CSS specification and will trigger a validation error:
.clickable {
cursor: hand;
}
Valid CSS
Use the standard pointer value instead:
.clickable {
cursor: pointer;
}
Using it in context with HTML
<style>
.card {
padding: 16px;
border: 1px solid #ccc;
cursor: pointer;
}
</style>
<div class="card">
Click me to view details
</div>
Legacy fallback (rarely needed)
If for some reason you must support IE 5.5 or earlier alongside modern browsers, you can provide both declarations. The browser will apply the last value it understands:
.clickable {
cursor: hand;
cursor: pointer;
}
Note that this fallback pattern will still produce a validation warning for the hand value. In practice, there is virtually no reason to support browsers this old, so using cursor: pointer alone is the recommended approach.
Common cursor values
For reference, here are some of the most frequently used valid cursor values defined in the CSS specification:
- auto — the browser determines the cursor based on context (default behavior)
- default — the platform’s default cursor, typically an arrow
- pointer — a pointing hand, indicating a link or clickable element
- text — an I-beam, indicating selectable text
- move — indicates something can be moved
- not-allowed — indicates an action is not permitted
- grab / grabbing — indicates a draggable element
- crosshair — a precise selection cursor
- wait — indicates the program is busy
- help — indicates help is available
The full list of accepted values is defined in the CSS Basic User Interface Module specification.
The device-width and device-height media features (including their min- and max- prefixed versions) were originally designed to query the physical dimensions of a device’s screen. In practice, this caused significant problems. On high-DPI (Retina) displays, max-device-width could report unexpected values depending on the device pixel ratio. When users resized their browser window, these features didn’t respond because the physical screen size never changed. And with browser zoom, the layout could break because the query still referenced the fixed device dimensions rather than the actual available space.
The Media Queries Level 4 specification formally deprecated these features. Modern browsers still support them for backward compatibility, but they should not be used in new code. The W3C validator raises this warning to encourage migration to the current standard.
The viewport-based equivalents — width, min-width, and max-width — respond to the browser’s layout viewport. This means they correctly adapt when the user resizes the window, zooms the page, or views the page in a split-screen mode. They also behave consistently across devices regardless of pixel density.
If your existing code uses max-device-width or min-device-width, the fix is straightforward: drop the word device from the feature name. For example, max-device-width: 768px becomes max-width: 768px. If you were relying on device dimensions to detect high-DPI screens, use the resolution media feature instead (e.g., min-resolution: 2dppx), which is the standards-compliant replacement for vendor-prefixed features like -webkit-min-device-pixel-ratio.
When choosing breakpoint values, prefer content-driven breakpoints — values where your layout actually needs to adapt — rather than targeting specific device widths. This produces more resilient designs that work well on any screen size.
Examples
Deprecated usage triggering the warning
The max-device-width media feature in the <style> block triggers the validator warning:
<!doctype html>
<html lang="en">
<head>
<title>Deprecated Media Feature</title>
<style>
/* Deprecated: queries the physical device screen */
@media only screen and (max-device-width: 480px) {
body {
background: pink;
}
}
</style>
</head>
<body>
<p>This page uses a deprecated media feature.</p>
</body>
</html>
The same warning appears if the deprecated feature is used in a <link> element’s media attribute:
<link rel="stylesheet" href="mobile.css" media="(max-device-width: 480px)">
Fixed example using viewport-based queries
Replace max-device-width with max-width to query the viewport instead:
<!doctype html>
<html lang="en">
<head>
<title>Viewport-Based Media Query</title>
<style>
/* Correct: responds to the viewport width */
@media (max-width: 480px) {
body {
background: pink;
}
}
</style>
</head>
<body>
<p>This page uses a modern media feature.</p>
</body>
</html>
And for the <link> element:
<link rel="stylesheet" href="mobile.css" media="(max-width: 480px)">
Replacing device pixel ratio queries
If you were using device-width features alongside -webkit-min-device-pixel-ratio to target high-DPI screens, switch to the standard resolution feature:
<style>
/* Deprecated approach */
@media (-webkit-min-device-pixel-ratio: 2) {
.logo {
background-image: url("logo@2x.png");
}
}
/* Standards-compliant replacement */
@media (min-resolution: 2dppx) {
.logo {
background-image: url("logo@2x.png");
}
}
</style>
Quick reference of replacements
| Deprecated feature | Modern replacement |
|---|---|
| max-device-width | max-width |
| min-device-width | min-width |
| max-device-height | max-height |
| min-device-height | min-height |
| -webkit-min-device-pixel-ratio: 2 | min-resolution: 2dppx |
The min-device-width and max-device-width media features were originally designed to query the physical screen dimensions of a device. However, these features have been deprecated in Media Queries Level 4 and Level 5 because they are unreliable in modern browsing contexts. The physical screen size is a poor proxy for the actual available layout space — it doesn’t account for browser chrome, split-screen modes, zoom levels, or the fact that many modern devices report abstract pixel values that don’t correspond to physical hardware pixels in a straightforward way.
The viewport-based alternatives — min-width and max-width — respond to the layout viewport, which is the actual space your content is rendered into. This makes them far more useful for responsive design. When a user zooms in, the layout viewport shrinks, and min-width/max-width queries respond accordingly. With min-device-width, zooming has no effect on the query result, which can lead to layouts that don’t adapt when they should.
Beyond practical concerns, using deprecated features means your CSS may behave inconsistently across browsers in the future, as support could be removed entirely. Validators flag this to encourage migration to the modern, standards-compliant approach.
How to fix it
The fix is a straightforward replacement:
- min-device-width → min-width
- max-device-width → max-width
If your original query also included the screen keyword solely to pair with device-width targeting, you can safely drop it — min-width and max-width apply across all media types and the screen qualifier is rarely necessary in modern CSS.
If you were using min-device-width to detect high-density or Retina displays (a common pattern in older code), the correct modern approach is to use the resolution media feature instead, such as min-resolution: 2dppx.
Examples
Deprecated usage (triggers warning)
<!doctype html>
<html lang="en">
<head>
<title>Deprecated media feature</title>
<style>
@media screen and (min-device-width: 768px) {
.sidebar { display: block; }
}
@media screen and (max-device-width: 480px) {
.sidebar { display: none; }
}
</style>
</head>
<body>
<aside class="sidebar">Sidebar content</aside>
</body>
</html>
Both min-device-width and max-device-width are deprecated and will produce validation warnings.
Fixed example using viewport-based queries
<!doctype html>
<html lang="en">
<head>
<title>Viewport-based media queries</title>
<style>
@media (min-width: 768px) {
.sidebar { display: block; }
}
@media (max-width: 480px) {
.sidebar { display: none; }
}
</style>
</head>
<body>
<aside class="sidebar">Sidebar content</aside>
</body>
</html>
Replacing device-width with resolution for pixel density
Older code sometimes used min-device-width in combination with -webkit-min-device-pixel-ratio to target high-density screens. The modern equivalent uses the resolution media feature:
<!doctype html>
<html lang="en">
<head>
<title>Resolution media query</title>
<style>
/* Deprecated approach */
/*
@media screen and (min-device-width: 768px) and (-webkit-min-device-pixel-ratio: 2) {
.hero { background-image: url("hero@2x.jpg"); }
}
*/
/* Modern approach */
@media (min-width: 768px) and (min-resolution: 2dppx) {
.hero { background-image: url("hero@2x.jpg"); }
}
</style>
</head>
<body>
<div class="hero">Hero section</div>
</body>
</html>
The min-resolution: 2dppx query cleanly replaces vendor-prefixed pixel ratio queries and works alongside the standard min-width viewport query.
The correct value is nowrap (without a hyphen), not no-wrap.
The flex-wrap CSS property controls whether flex items are forced onto a single line or can wrap onto multiple lines. It accepts three values: nowrap (the default), wrap, and wrap-reverse. A common mistake is writing no-wrap with a hyphen, likely because the white-space CSS property uses nowrap and no-wrap interchangeably in some contexts, or simply because it looks more natural in English. However, for flex-wrap, only the unhyphenated nowrap is valid.
HTML Example With the Issue
<div style="display: flex; flex-wrap: no-wrap;">
<p>Item 1</p>
<p>Item 2</p>
</div>
Fixed HTML Example
<div style="display: flex; flex-wrap: nowrap;">
<p>Item 1</p>
<p>Item 2</p>
</div>
The font-size property defines the size of text in CSS and accepts a specific set of value types. When the W3C validator reports that a value “is not a font-size value,” it means the value you provided doesn’t match any of the accepted formats. Browsers may attempt to ignore or guess what you meant, but this leads to unpredictable rendering across different browsers and devices.
This error commonly occurs for a few reasons:
- Missing units on numeric values. Writing font-size: 16 instead of font-size: 16px. In CSS, unitless numbers (other than 0) are not valid lengths.
- Typos in units or keywords. For example, font-size: 16xp, font-size: 1.2erm, or font-size: lage.
- Using values from the wrong property. For example, font-size: bold (which belongs to font-weight) or font-size: center.
- Invalid or unsupported syntax. For example, font-size: 16 px (with a space between the number and unit) or font-size: auto (which is not valid for this property).
Valid font-size value types
| Type | Examples | Notes |
|---|---|---|
| Absolute keywords | xx-small, x-small, small, medium, large, x-large, xx-large, xxx-large | Browser-defined sizes |
| Relative keywords | smaller, larger | Relative to the parent element’s font size |
| Length units | 16px, 1.2em, 0.9rem, 12pt, 1vw | Must include a unit (except 0) |
| Percentages | 100%, 120%, 80% | Relative to the parent element’s font size |
| Math functions | calc(1rem + 2px), clamp(1rem, 2vw, 3rem) | CSS math expressions that resolve to a length |
Examples
Incorrect: missing unit on a number
<p style="font-size: 16;">This triggers a validation error.</p>
The value 16 is not valid because it lacks a CSS unit. Browsers may ignore this declaration entirely, leaving the text at its default or inherited size.
Correct: number with a valid unit
<p style="font-size: 16px;">This text has a valid font size.</p>
Incorrect: typo in the unit
<p style="font-size: 1.2erm;">Typo in the unit.</p>
Correct: proper em unit
<p style="font-size: 1.2em;">Correct em unit.</p>
Incorrect: value from the wrong property
<p style="font-size: bold;">Bold is not a font-size value.</p>
Correct: using a valid keyword
<p style="font-size: large;">Using a valid size keyword.</p>
Incorrect: space between number and unit
<p style="font-size: 16 px;">Space before the unit is invalid.</p>
Correct: no space between number and unit
<p style="font-size: 16px;">No space between number and unit.</p>
Full document example
<!DOCTYPE html>
<html lang="en">
<head>
<title>Font Size Example</title>
<style>
.heading {
font-size: 2rem;
}
.body-text {
font-size: 1em;
}
.small-print {
font-size: 80%;
}
.responsive {
font-size: clamp(1rem, 2.5vw, 2rem);
}
</style>
</head>
<body>
<h1 class="heading">Valid heading size</h1>
<p class="body-text">Body text at 1em.</p>
<p class="small-print">Small print at 80%.</p>
<p class="responsive">Responsive text using clamp().</p>
</body>
</html>
To resolve this validation error, review every font-size declaration in your CSS or inline styles. Make sure each value is either a recognized keyword, a number immediately followed by a valid unit, a percentage, or a supported CSS function like calc(). If you intended 0, that is the one numeric value that does not require a unit — font-size: 0 is valid, though rarely useful in practice.
The CSS font shorthand property has a specific syntax defined in the CSS specification. At minimum, it requires both a font-size and a font-family value. Optionally, you can prepend font-style, font-variant, and font-weight, and you can append a line-height value after the font-size using a slash separator. The full syntax looks like this:
font: [font-style] [font-variant] [font-weight] font-size[/line-height] font-family;
When the W3C validator reports that a value “is not a font-family value,” it means the parser reached a point in the font declaration where it expected to find a font family name but instead found something it couldn’t interpret as one. This often happens in two scenarios:
- Using font when you meant a specific property — For example, writing font: 300 when you only intended to set the font weight. The validator tries to parse 300 as a complete font value, and since there’s no font-size or font-family, it fails.
- Incomplete font shorthand — Providing some values but forgetting the mandatory font-family at the end, such as font: 300 16px without a family name.
This matters because browsers may ignore an invalid font declaration entirely, causing your text to render with default or inherited styles instead of what you intended. Keeping your CSS valid also ensures consistent behavior across different browsers and helps maintain clean, predictable stylesheets.
How to fix it:
- If you only need to set a single font-related property, use the specific property (font-weight, font-size, font-style, font-variant, or font-family) instead of the font shorthand.
- If you want to use the font shorthand, make sure you include at least font-size and font-family, and that all values appear in the correct order.
- Remember that the font shorthand resets any omitted font sub-properties to their initial values, so use it deliberately.
Examples
Incorrect: Using font to set only the weight
<p style="font: 300;">This text has an invalid font declaration.</p>
The validator reports that 300 is not a valid font-family value because the font shorthand expects at least a font-size and font-family.
Correct: Using font-weight directly
<p style="font-weight: 300;">This text has a light font weight.</p>
Incorrect: Missing font-family in the shorthand
<p style="font: italic 300 16px;">This is also invalid.</p>
Even though font-style, font-weight, and font-size are all present, the required font-family is missing.
Correct: Complete font shorthand
<p style="font: italic 300 16px/1.5 'Helvetica', sans-serif;">This is valid.</p>
This includes all components in the correct order: font-style, font-weight, font-size/line-height, and font-family.
Correct: Minimal valid font shorthand
<p style="font: 16px sans-serif;">Only size and family — the minimum required.</p>
Correct: Using individual properties instead of the shorthand
<p style="font-style: italic; font-weight: 300; font-size: 16px; line-height: 1.5; font-family: 'Helvetica', sans-serif;">
Each property set individually.
</p>
Using individual properties avoids the pitfalls of the shorthand and gives you explicit control without accidentally resetting other font sub-properties.
The gap property is a shorthand for row-gap and column-gap, used in CSS Grid, Flexbox, and multi-column layouts to define spacing between items or tracks. According to the CSS Box Alignment specification, the accepted values for gap are length values (px, em, rem, %, vh, etc.), the normal keyword, or the calc() function. The keyword auto — while valid for many other CSS properties like margin, width, and grid-template-columns — is simply not part of the gap property’s value grammar.
This confusion often arises because developers are accustomed to using auto for spacing in other contexts. For instance, margin: auto is a common centering technique, and auto is widely used in grid track sizing. However, the gap property serves a different purpose: it defines a fixed or computed gutter size between items, and auto has no defined meaning in that context.
Why this matters
- Standards compliance: Using an invalid value means the browser will ignore the entire gap declaration, falling back to the default value of normal (which is typically 0px in Grid and Flexbox). This can lead to unexpected layout results where items have no spacing at all.
- Cross-browser consistency: While some browsers may be lenient with invalid CSS values, others will strictly discard them. This creates inconsistent layouts across different browsers and versions.
- Maintainability: Invalid CSS values can mask the developer’s intent, making it harder for others (or your future self) to understand what spacing was desired.
How to fix it
Replace auto with a valid value for gap:
- A specific length: gap: 16px;, gap: 1rem;, gap: 0.5em;
- A percentage: gap: 2%;
- The normal keyword: gap: normal; (resolves to 0px in Flexbox and Grid)
- A calc() expression: gap: calc(1rem + 4px);
- Two values for row and column separately: gap: 16px 24px;
If you were using auto because you wanted the browser to determine the spacing dynamically, consider using a percentage value, a viewport-relative unit (vw, vh), or CSS clamp() for responsive gutters.
Examples
Incorrect: using auto as a gap value
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: auto;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
This triggers the validation error because auto is not a valid gap value. The browser will discard the declaration entirely.
Correct: using a fixed length
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
Correct: using separate row and column gaps
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
Correct: using a percentage for responsive spacing
<div style="display: flex; flex-wrap: wrap; gap: 2%;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
Correct: using clamp() for fluid responsive gaps
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: clamp(8px, 2vw, 32px);">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
This approach gives you a gap that scales with the viewport width, bounded between 8px and 32px — a useful alternative if you were reaching for auto to get flexible spacing behavior.
The grid-column property is a shorthand for grid-column-start and grid-column-end. It defines where a grid item is placed horizontally within a CSS Grid layout. The validator checks that inline style attributes and <style> blocks contain valid CSS, and it will flag any value that doesn’t conform to the property’s grammar.
Why This Happens
Several kinds of invalid values can trigger this error:
- Using 0 as a line number. CSS Grid lines are 1-indexed. Line 0 does not exist, so values like grid-column: 0, grid-column: 0 / 3, or grid-column: span 0 are all invalid.
- Typos or unrecognized keywords. Values like grid-column: center or grid-column: full are not valid unless they match named grid lines you’ve explicitly defined.
- Malformed shorthand syntax. Missing the / separator, using commas instead, or providing too many values will cause a parse error.
- Using span incorrectly. The span keyword must be followed by a positive integer or a named line, e.g., span 2. Writing span -1 or span 0 is invalid.
Valid Syntax
The grid-column shorthand accepts:
grid-column: <grid-line> / <grid-line>;
Each <grid-line> can be:
- A positive or negative integer (but not 0) representing a grid line number
- A named grid line (e.g., content-start)
- The span keyword followed by a positive integer or a name (e.g., span 2)
- auto
If only one value is provided (no /), the end line defaults to auto.
Why It Matters
Invalid CSS values are ignored by browsers, meaning the grid item will fall back to automatic placement. This can cause unexpected layout shifts. Ensuring valid values improves standards compliance, makes your layout predictable across browsers, and prevents silent failures that are hard to debug.
Examples
❌ Invalid: Using 0 as a line number
<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
<div style="grid-column: 0 / 3;">Item</div>
</div>
Grid lines start at 1, so 0 is not a valid line number.
✅ Fixed: Using a valid line number
<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
<div style="grid-column: 1 / 3;">Item</div>
</div>
❌ Invalid: Unrecognized keyword
<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
<div style="grid-column: full;">Item</div>
</div>
The value full is not a valid grid line value unless it’s a named line defined in the grid template.
✅ Fixed: Using span to cover all columns
<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
<div style="grid-column: 1 / -1;">Item</div>
</div>
Using -1 refers to the last grid line, effectively spanning all columns.
❌ Invalid: span 0
<div style="display: grid; grid-template-columns: repeat(4, 1fr);">
<div style="grid-column: span 0;">Item</div>
</div>
The span keyword requires a positive integer. 0 is not valid.
✅ Fixed: Using a positive span value
<div style="display: grid; grid-template-columns: repeat(4, 1fr);">
<div style="grid-column: span 2;">Item</div>
</div>
❌ Invalid: Malformed syntax with a comma
<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
<div style="grid-column: 1, 3;">Item</div>
</div>
✅ Fixed: Using the / separator
<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
<div style="grid-column: 1 / 3;">Item</div>
</div>
The start and end lines must be separated by a /, not a comma.
Quick Reference of Valid Patterns
| Value | Meaning |
|---|---|
| grid-column: 2 | Start at line 2, end at auto |
| grid-column: 2 / 5 | Start at line 2, end at line 5 |
| grid-column: 1 / -1 | Span from first to last line |
| grid-column: span 3 | Span 3 columns from auto-placed start |
| grid-column: 2 / span 3 | Start at line 2, span 3 columns |
| grid-column: auto / auto | Fully automatic placement |
When in doubt, check that every numeric value is a non-zero integer and that the overall format uses / to separate the start and end values.
The grid-template-columns property defines the column track sizes of a CSS grid container. When the W3C validator reports that a particular value “is not a grid-template-columns value,” it means the parser encountered something it cannot interpret as a valid track size or track listing.
This error can be triggered by many common mistakes: a simple typo (like auто instead of auto), using a CSS custom property (the validator may not resolve var() references), forgetting units on a length value (e.g., 100 instead of 100px), using JavaScript-like terms (e.g., undefined or null), or using newer syntax that the validator’s CSS parser doesn’t yet support.
While browsers are generally forgiving and will simply ignore an invalid grid-template-columns declaration, this means your grid layout silently breaks — the container won’t form a grid as intended, and content may stack in a single column. Fixing validation errors ensures your layout works predictably across browsers and makes your stylesheets easier to maintain.
Valid values
The grid-template-columns property accepts these value types:
- none — the default; no explicit grid columns are defined.
- Length and percentage values — px, em, rem, %, vh, vw, etc. (e.g., 200px, 50%).
- The fr unit — distributes remaining space proportionally (e.g., 1fr 2fr).
- Keywords — auto, min-content, max-content.
- The repeat() function — shorthand for repeated track patterns (e.g., repeat(3, 1fr)).
- The minmax() function — sets a minimum and maximum size for a track (e.g., minmax(150px, 1fr)).
- The fit-content() function — clamps the track to a given maximum (e.g., fit-content(300px)).
- Named grid lines — defined with square brackets (e.g., [sidebar-start] 200px [sidebar-end content-start] 1fr [content-end]).
- Any combination of the above.
Common causes
- Typos or made-up keywords — values like undefined, inherit-grid, or misspelled units.
- Missing units — writing 100 instead of 100px. The fr unit, px, and all other units are mandatory (only 0 can be unitless).
- Invalid function syntax — missing commas or parentheses in repeat() or minmax().
- CSS custom properties — var(--cols) may trigger validator warnings because the validator cannot resolve the variable at parse time. This is typically a false positive.
Examples
Incorrect: invalid keyword
<style>
.grid {
display: grid;
grid-template-columns: undefined;
}
</style>
Incorrect: missing unit on a length
<style>
.grid {
display: grid;
grid-template-columns: 200 1fr;
}
</style>
Incorrect: malformed repeat() syntax
<style>
.grid {
display: grid;
grid-template-columns: repeat(3 1fr);
}
</style>
Correct: using fr units
<style>
.grid {
display: grid;
grid-template-columns: 1fr 2fr;
}
</style>
Correct: mixing lengths, fr, and auto
<style>
.grid {
display: grid;
grid-template-columns: 250px 1fr auto;
}
</style>
Correct: using repeat() and minmax()
<style>
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
</style>
Correct: named grid lines with track sizes
<style>
.grid {
display: grid;
grid-template-columns: [sidebar] 240px [content] 1fr [aside] 200px;
}
</style>
If the validator flags a var() custom property usage and you’re confident the variable resolves to a valid value at runtime, the warning can generally be disregarded — this is a known limitation of static CSS validation. For all other cases, double-check spellings, ensure every numeric value (other than 0) has a unit, and verify that function syntax includes the correct commas and parentheses.
The grid-template-rows property defines the size of each row in a CSS grid layout. The W3C validator checks that every value in the declaration conforms to the CSS Grid specification. When you see this error, the validator has encountered something it cannot parse as a valid track size.
Common causes of this error include:
- Typos or invalid units — writing 100 px (with a space), 100pixels, or 1 fr instead of 1fr.
- Using values from other properties — for example, flex, inline, or space-between are not valid row track sizes.
- Incorrect function syntax — missing commas in repeat(), providing wrong arguments to minmax(), or using unsupported functions.
- Missing units — writing a bare number like 100 instead of 100px (zero is the only number that doesn’t require a unit).
- Using newer syntax not yet recognized — some cutting-edge features like subgrid or the masonry value may trigger validation warnings depending on the validator’s supported spec level.
The grid-template-rows property accepts these valid value types:
- Length values: 100px, 5em, 10rem, 20vh
- Percentages: 50%, 33.3%
- Flexible lengths: 1fr, 2fr
- Keywords: auto, min-content, max-content, none
- Functions: repeat(), minmax(), fit-content()
- Named lines: [row-start] 100px [row-end]
This matters for standards compliance and forward compatibility. While browsers may be lenient and ignore invalid values, relying on that behavior can lead to layouts that silently break. Valid CSS ensures your grid behaves predictably across all browsers.
Examples
Incorrect — invalid values
<style>
/* ERROR: "full" is not a valid track size */
.grid-a {
display: grid;
grid-template-rows: full auto;
}
/* ERROR: space between number and unit */
.grid-b {
display: grid;
grid-template-rows: 100 px 200 px;
}
/* ERROR: bare number without a unit */
.grid-c {
display: grid;
grid-template-rows: 100 200;
}
/* ERROR: missing comma in repeat() */
.grid-d {
display: grid;
grid-template-rows: repeat(3 1fr);
}
</style>
Correct — valid track sizes
<style>
/* Fixed pixel heights */
.grid-a {
display: grid;
grid-template-rows: 100px auto;
}
/* Flexible units */
.grid-b {
display: grid;
grid-template-rows: 1fr 2fr;
}
/* Repeat function with correct syntax */
.grid-c {
display: grid;
grid-template-rows: repeat(3, 1fr);
}
/* Minmax with auto */
.grid-d {
display: grid;
grid-template-rows: minmax(100px, 1fr) auto;
}
</style>
Full working example
<!DOCTYPE html>
<html lang="en">
<head>
<title>Grid template rows example</title>
<style>
.grid-container {
display: grid;
grid-template-rows: 80px minmax(150px, 1fr) auto;
gap: 8px;
height: 400px;
}
.grid-container > div {
background: #e0e0e0;
padding: 16px;
}
</style>
</head>
<body>
<div class="grid-container">
<div>Row 1 — fixed 80px</div>
<div>Row 2 — between 150px and 1fr</div>
<div>Row 3 — auto-sized to content</div>
</div>
</body>
</html>
Using fit-content() and named lines
<style>
.grid {
display: grid;
grid-template-rows: [header] fit-content(100px) [main] 1fr [footer] auto;
}
</style>
If your value looks correct but the validator still flags it, check whether you’re using a very new CSS feature like subgrid or masonry. These may not yet be recognized by the validator even if some browsers support them. In that case, the warning can be acknowledged while keeping the value intentionally.
The height CSS property defines the height of an element’s content area. According to CSS specifications, it accepts several value types: length values (like px, em, rem, vh, cm), percentages (%), and keywords such as auto, min-content, max-content, and fit-content. When the validator encounters a value that doesn’t belong to any of these accepted types, it reports a type incompatibility error.
This error commonly occurs in a few scenarios:
- Missing units on numeric values. In CSS, a bare number like 100 is not a valid length. The only exception is 0, which doesn’t require a unit because zero is the same in any unit system. Writing height: 100; instead of height: 100px; is invalid CSS.
- Unrecognized keywords. Using a word that isn’t a valid CSS keyword for height, such as big, small, or full, will trigger this error. These are not part of the CSS specification for the height property.
- Values from the wrong property. Sometimes values valid for other properties get mistakenly used with height. For example, height: bold; or height: block; are type mismatches because those keywords belong to font-weight and display, respectively.
- Typos or syntax errors. A stray character, misspelled unit (e.g., 100xp instead of 100px), or malformed calc() expression can also cause this error.
While modern browsers often try to recover from invalid CSS by ignoring the offending declaration, this means the height rule silently has no effect, which can lead to unexpected layout behavior. Writing valid CSS ensures your styles work predictably across all browsers and avoids hard-to-debug rendering issues.
How to Fix It
- Add a valid unit to any bare numeric value. Use px, em, rem, vh, %, or another valid CSS length unit.
- Use only recognized keywords for height: auto, min-content, max-content, fit-content, or fit-content(<length>).
- Check for typos in both the value and the unit.
- Validate calc() expressions to ensure the types inside are compatible (e.g., you can’t add a length and a color).
Examples
Incorrect: Missing unit on a numeric value
<style>
.box {
height: 100; /* invalid — no unit specified */
}
</style>
Incorrect: Unrecognized keyword
<style>
.box {
height: big; /* invalid — "big" is not a CSS keyword for height */
}
</style>
Incorrect: Misspelled unit
<style>
.box {
height: 250xp; /* invalid — "xp" is not a recognized unit */
}
</style>
Correct: Valid length values, percentages, and keywords
<style>
.fixed {
height: 200px;
}
.relative {
height: 70%;
}
.viewport {
height: 100vh;
}
.flexible {
height: auto;
}
.zero {
height: 0;
}
.intrinsic {
height: min-content;
}
.calculated {
height: calc(100vh - 60px);
}
</style>
Correct: Using height in context
<div style="height: 300px;">
<p style="height: 50%;">
This paragraph is 150px tall because its parent has a defined height.
</p>
</div>
Keep in mind that percentage-based height values only work when the parent element has a defined height. If the parent’s height is auto, a child with height: 50% will behave as if it were set to auto as well. When in doubt, use an absolute length like px or a viewport unit like vh, or set height: auto to let the content determine the element’s size.
The W3C validator parses inline CSS values character by character. When it encounters a numeric value for the left property, it expects the characters that follow to be part of a valid number (digits, a decimal point, or e for scientific notation) or a recognized CSS unit. If it instead finds an unexpected letter like n, it raises this error. This can happen in several ways:
- Missing units: Writing left: 10; instead of left: 10px;. The CSS specification requires a unit for all non-zero length values. While some browsers may interpret unitless numbers in quirks mode, this is invalid CSS and produces unpredictable results across browsers.
- Typos in units: Writing something like left: 10n; or left: 10xp; where the intended unit was px but a typo introduced invalid characters.
- Template or scripting artifacts: Dynamically generated values like left: {{offset}}px; that weren’t properly resolved, leaving non-numeric characters in the output.
- Using calc() incorrectly: Writing left: 10 + 5px; instead of left: calc(10px + 5px);.
The left property accepts the following value types:
- Lengths: A number followed by a unit such as px, em, rem, vw, vh, ch, etc. (e.g., left: 10px;)
- Percentages: A number followed by % (e.g., left: 50%;)
- Keywords: auto, inherit, initial, unset, or revert
- Functions: calc(), min(), max(), clamp(), etc.
- Zero: The value 0 is the only number that does not require a unit.
Invalid CSS not only triggers validation errors but can cause layout issues. Browsers may ignore the entire declaration, falling back to the default value, which can break your intended positioning. Ensuring valid CSS improves cross-browser consistency and maintainability.
Examples
Missing unit (triggers the error)
<div style="position: absolute; left: 10;">
Positioned element
</div>
The validator reads 10 and then encounters the ; (or in other cases a stray letter like n), which is not a valid part of a CSS length value.
Typo in unit (triggers the error)
<div style="position: absolute; left: 10xn;">
Positioned element
</div>
Fixed with a valid length unit
<div style="position: absolute; left: 10px;">
Positioned element
</div>
Fixed with a percentage
<div style="position: absolute; left: 50%;">
Positioned element
</div>
Fixed with the auto keyword
<div style="position: absolute; left: auto;">
Positioned element
</div>
Fixed with calc()
<div style="position: absolute; left: calc(50% - 20px);">
Positioned element
</div>
Zero without a unit (valid)
<div style="position: absolute; left: 0;">
Positioned element
</div>
Always double-check that every non-zero numeric value for left (and other length-based properties like top, right, bottom, width, margin, etc.) includes a valid CSS unit. If you’re generating styles dynamically, verify that template variables resolve to proper values before rendering.
The left property specifies the horizontal offset of a positioned element — one that has its position set to relative, absolute, fixed, or sticky. The W3C validator checks CSS within style attributes and <style> elements, and it will flag any value it cannot recognize as a valid left value.
Common causes of this error include:
- Misspelled or non-existent units: Writing 10 px (with a space), 10pixels, or 20ppx instead of 10px.
- Unsupported keywords: Using values like none, center, or middle, which are not valid for the left property.
- Missing units on non-zero numbers: Writing left: 10 instead of left: 10px. Zero is the only number that doesn’t require a unit.
- Typos in keyword values: Writing auто or autoo instead of auto.
- CSS custom properties in inline styles: Using var(--offset) in a style attribute may trigger validation warnings depending on the validator’s CSS level.
The valid values for the left property are:
- <length>: A numeric value with a unit, such as 10px, 2em, 3rem, 1vw.
- <percentage>: A percentage relative to the containing block’s width, such as 50%.
- auto: Lets the browser determine the position (this is the default).
- Global keywords: inherit, initial, unset, and revert.
Using an invalid value means the browser will ignore the declaration entirely, which can break your layout. Fixing these values ensures consistent rendering across browsers and compliance with CSS standards.
Examples
Invalid: Using an unsupported keyword
The keyword none is not a valid value for the left property.
<div style="position: absolute; left: none;">Positioned element</div>
Invalid: Missing unit on a non-zero number
A bare number (other than 0) is not valid without a CSS unit.
<div style="position: relative; left: 20;">Shifted element</div>
Invalid: Misspelled unit
The unit xp does not exist in CSS.
<div style="position: absolute; left: 15xp;">Positioned element</div>
Valid: Using a length value
<div style="position: absolute; left: 20px;">20 pixels from the left</div>
Valid: Using a percentage
<div style="position: absolute; left: 50%;">Offset by 50% of containing block</div>
Valid: Using the auto keyword
<div style="position: absolute; left: auto;">Browser-determined position</div>
Valid: Using zero without a unit
Zero does not require a unit in CSS.
<div style="position: absolute; left: 0;">Flush with the left edge</div>
Valid: Using inherit
<div style="position: relative; left: inherit;">Inherits left value from parent</div>
To fix this error, identify the invalid value the validator is reporting and replace it with one of the accepted value types listed above. If you intended to reset the position, use auto or 0. If you meant to remove a previously set left value, use initial or unset rather than an unsupported keyword like none.
NaN in JavaScript stands for “Not a Number” and appears when a numeric operation fails — for example, parsing a non-numeric string with parseFloat(), dividing 0 by 0, or referencing an undefined variable in arithmetic. When this NaN value gets concatenated with a unit string like "rem", the result is "NaNrem", which is meaningless to CSS. The browser cannot interpret it, and the W3C validator flags it as an invalid letter-spacing value.
This issue almost always originates from dynamically generated styles — either through JavaScript that sets inline styles, a server-side template that computes CSS values, or a CSS-in-JS library. The rendered HTML ends up containing something like style="letter-spacing: NaNrem", which the validator rightly rejects.
Beyond validation, this is a practical problem: the browser will ignore the invalid declaration entirely, so whatever letter-spacing you intended won’t be applied. Your layout may look different than expected, and the invalid value in the markup signals a bug in your code that could affect other computed styles too.
How to Fix It
-
Trace the source of the value. Search your codebase for where letter-spacing is set. If it’s an inline style, look at the JavaScript or server-side code that generates it.
-
Validate the number before using it. In JavaScript, use Number.isNaN() or isFinite() to check that a computed value is valid before applying it.
-
Provide a sensible fallback. If the calculation might fail, default to a known-good value like 0 or normal.
-
Fix the root cause. Determine why the calculation produces NaN — common causes include missing data attributes, undefined variables, or parsing non-numeric strings.
Examples
❌ Invalid: NaN concatenated with a unit
This is what the rendered HTML looks like when the bug occurs:
<p style="letter-spacing: NaNrem">Spaced text</p>
The JavaScript that likely produced it:
// Bug: getAttribute returns null if data-spacing is missing
let spacing = parseFloat(element.getAttribute('data-spacing'));
element.style.letterSpacing = spacing + 'rem'; // "NaNrem" if attribute is missing
✅ Fixed: Validate the value before applying it
let raw = parseFloat(element.getAttribute('data-spacing'));
let spacing = Number.isFinite(raw) ? raw : 0.1; // fallback to 0.1
element.style.letterSpacing = spacing + 'rem';
This produces valid inline CSS:
<p style="letter-spacing: 0.1rem">Spaced text</p>
✅ Fixed: Using a static CSS value
If the letter-spacing doesn’t need to be dynamic, the simplest fix is to use a plain CSS rule instead of computing it in JavaScript:
<style>
.spaced-text {
letter-spacing: 0.1rem;
}
</style>
<p class="spaced-text">Spaced text</p>
✅ Fixed: Server-side template with a guard
If a server-side template generates the style, add a check before rendering:
<!-- Pseudocode for a template engine -->
<!-- Only output the style attribute if the value is a valid number -->
<p style="letter-spacing: 0.05rem">Spaced text</p>
Ensure your template logic verifies the value is numeric before injecting it into the markup. If the value is missing or invalid, either omit the style attribute entirely or use a safe default.
Valid letter-spacing values for reference
The letter-spacing property accepts:
- The keyword normal (default, lets the browser decide)
- Any valid CSS length: 0.1rem, 1px, 0.05em, 2px, etc.
- 0 (no extra spacing)
The numeric part must always be a real number — NaN, Infinity, and empty strings are never valid.
Ready to validate your sites?
Start your free trial today.