HTML Guides
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 seamless attribute was originally drafted as part of the HTML5 specification to allow an <iframe> to appear as though its content were part of the containing document. When present, it was supposed to remove borders, inherit styles from the parent page, and allow the iframe content to participate in the parent document’s styling context. However, no browser ever fully implemented the attribute, and it was officially removed from the WHATWG HTML Living Standard.
Because seamless is not a recognized attribute in the current HTML specification, using it triggers a validation error. Beyond validation, including it has no practical effect in any modern browser — it’s simply ignored. Keeping unsupported attributes in your markup creates confusion for other developers who may assume the attribute is doing something meaningful. It also adds unnecessary clutter to your HTML.
How to Fix It
Remove the seamless attribute from any <iframe> elements. If you want to replicate the visual effects that seamless was intended to provide, you can use CSS:
- Remove the border: Apply border: none; or use the frameborder="0" attribute (though frameborder is also obsolete — CSS is preferred).
- Blend the background: Set background: transparent; and add the allowtransparency attribute if targeting older browsers.
- Auto-resize to content: Use JavaScript to dynamically adjust the iframe’s height based on its content (subject to same-origin restrictions).
Note that true seamless integration — where the iframe inherits parent styles and its content flows naturally within the parent document — is not achievable with standard iframe behavior. If you need that level of integration, consider including the content directly in the page, using a server-side include, or fetching the content with JavaScript via the fetch API and inserting it into the DOM.
Examples
❌ Invalid: Using the seamless attribute
<iframe src="widget.html" seamless></iframe>
✅ Fixed: Attribute removed, CSS used for styling
<iframe src="widget.html" style="border: none;"></iframe>
✅ Fixed: Using a CSS class for cleaner markup
<style>
.seamless-iframe {
border: none;
width: 100%;
background: transparent;
}
</style>
<iframe src="widget.html" class="seamless-iframe" title="Embedded widget"></iframe>
✅ Alternative: Embedding content directly instead of using an iframe
If the content is on the same origin and you need true seamless integration, consider loading it directly:
<div id="embedded-content">
<!-- Content loaded via server-side include or JavaScript fetch -->
</div>
The padding-bottom property defines the amount of space between an element’s content and its bottom border. Like all CSS length properties, it expects a length value — a number paired with a unit such as px, em, rem, %, vh, etc. The lone string px is just a unit identifier with no magnitude, so CSS parsers cannot interpret it as a meaningful measurement. This typically happens when a numeric value is accidentally deleted during editing, when a CSS preprocessor or template engine outputs an empty variable before the unit, or when code is manually written with a typo.
When the browser encounters an invalid value like padding-bottom: px, it discards the entire declaration and falls back to the default or inherited value. This can lead to unexpected layout shifts, where the spacing looks correct in one browser but breaks in another depending on how defaults are applied. Fixing these errors ensures consistent rendering across browsers and keeps your stylesheets standards-compliant.
How to fix it
- Add a numeric value before the unit: change px to something like 10px, 1.5em, or 20%.
- Use 0 without a unit if you want zero padding — writing padding-bottom: 0 is valid and preferred over 0px.
- Check template variables — if you’re using a preprocessor like Sass or a templating engine, make sure the variable that generates the number is not empty or undefined.
- Remove the declaration entirely if padding-bottom is not needed, rather than leaving a broken value in place.
Examples
Incorrect: unit without a number
<div style="padding-bottom: px;">Content</div>
The value px alone is not valid because there is no number specifying the amount of padding.
Correct: numeric value with a unit
<div style="padding-bottom: 10px;">Content</div>
Correct: zero padding (no unit needed)
<div style="padding-bottom: 0;">Content</div>
Incorrect in an external stylesheet
.card {
padding-bottom: px;
}
Correct in an external stylesheet
.card {
padding-bottom: 16px;
}
Common preprocessor pitfall
In Sass or similar tools, this issue often arises from an empty or undefined variable:
$spacing: null;
.card {
padding-bottom: #{$spacing}px; // Outputs "padding-bottom: px;" if $spacing is empty
}
The fix is to ensure the variable holds a valid number, or provide a fallback:
$spacing: 16;
.card {
padding-bottom: #{$spacing}px; // Outputs "padding-bottom: 16px;"
}
Even better, include the unit in the variable itself to avoid concatenation issues:
$spacing: 16px;
.card {
padding-bottom: $spacing;
}
The HTML specification defines a specific set of allowed attributes for each element. The <span> element supports global attributes (such as id, class, style, title, etc.) but does not recognize currency as a valid attribute. When you add a non-standard attribute like currency to an element, the W3C validator flags it because it doesn’t conform to the HTML standard.
This pattern often appears in e-commerce sites, financial applications, or internationalization contexts where developers want to associate a currency code (like USD, EUR, or GBP) with a price displayed in a <span>. While browsers will typically ignore unrecognized attributes without breaking the page, using them creates several problems:
- Standards compliance: Invalid HTML can lead to unpredictable behavior across different browsers and future browser versions.
- Maintainability: Other developers (or tools) won’t recognize non-standard attributes, making the codebase harder to understand and maintain.
- Accessibility: Assistive technologies rely on valid, well-structured HTML. Non-standard attributes may be ignored or misinterpreted.
- JavaScript interoperability: The HTMLElement.dataset API is specifically designed to work with data-* attributes, providing a clean and standard way to read custom data from elements.
The fix is straightforward: HTML provides the data-* attribute mechanism specifically for embedding custom data on elements. Any attribute prefixed with data- is valid on any HTML element, and its value is accessible in JavaScript via the element.dataset property.
Examples
❌ Invalid: Non-standard currency attribute
<span currency="USD">49.99</span>
This triggers the validation error because currency is not a recognized attribute for <span>.
✅ Fixed: Using a data-currency attribute
<span data-currency="USD">49.99</span>
The data-currency attribute is valid HTML. In JavaScript, you can access its value like this:
const span = document.querySelector('span');
console.log(span.dataset.currency); // "USD"
✅ Alternative: Using data-* with richer markup
If you need to convey more structured information, you can combine multiple data-* attributes:
<span class="price" data-currency="EUR" data-amount="29.99">€29.99</span>
✅ Alternative: Using microdata or structured markup
For SEO and machine-readable data, consider using established vocabularies like Schema.org:
<span itemscope itemtype="https://schema.org/MonetaryAmount">
<meta itemprop="currency" content="USD">
<span itemprop="value">49.99</span>
</span>
This approach provides semantic meaning that search engines and other consumers can understand, while remaining fully valid HTML.
The W3C HTML Validator reports this error when it encounters isolang on the <html> element because isolang is not a recognized attribute in any version of HTML. This typically happens when developers attempt to specify the document’s language but use an incorrect or made-up attribute name, possibly confusing it with ISO language code terminology.
The correct attribute for declaring a document’s language is lang. This attribute accepts a valid BCP 47 language tag, which in most cases is a simple two-letter ISO 639-1 code (like en for English, fr for French, or pt for Portuguese). You can also use extended subtags for regional variants, such as en-US for American English or pt-BR for Brazilian Portuguese.
Setting the lang attribute properly is important for several reasons:
- Accessibility: Screen readers use the lang attribute to select the correct pronunciation rules, ensuring content is read aloud accurately.
- SEO: Search engines use the language declaration to serve the right content to users based on their language preferences.
- Browser behavior: Browsers rely on lang for features like spell-checking, hyphenation, and selecting appropriate default fonts for the given language.
- Standards compliance: Only recognized attributes pass W3C validation, and valid markup ensures consistent, predictable behavior across browsers.
To fix this issue, simply replace isolang with lang on your <html> element. Keep the same language code value—it’s the attribute name that’s wrong, not the value.
Examples
❌ Incorrect: Using the invalid isolang attribute
<!DOCTYPE html>
<html isolang="pt">
<head>
<title>Minha Página</title>
</head>
<body>
<p>Olá, mundo!</p>
</body>
</html>
This triggers the error: Attribute “isolang” not allowed on element “html” at this point.
✅ Correct: Using the lang attribute
<!DOCTYPE html>
<html lang="pt">
<head>
<title>Minha Página</title>
</head>
<body>
<p>Olá, mundo!</p>
</body>
</html>
✅ Correct: Using a regional language subtag
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<title>Minha Página</title>
</head>
<body>
<p>Olá, mundo!</p>
</body>
</html>
Common language codes
Here are some frequently used ISO 639-1 language codes for the lang attribute:
- en — English
- es — Spanish
- fr — French
- de — German
- pt — Portuguese
- zh — Chinese
- ja — Japanese
- ar — Arabic
- ko — Korean
- ru — Russian
The line-height CSS property controls the spacing between lines of text within an element. When the validator reports that a value “is not a line-height value,” it means the value you provided doesn’t match any of the accepted formats defined in the CSS specification.
Common mistakes that trigger this error include:
- Misspelled keywords — writing norml or Normal instead of normal (CSS keywords are case-insensitive in browsers, but some validators may flag inconsistencies; the real issue is outright misspellings).
- Invalid or missing units — using a unit the spec doesn’t support (e.g., line-height: 1.5x;) or accidentally adding a unit to what should be a unitless value (e.g., confusing 1.5 with 1.5 em with a space).
- Malformed numbers — typos like 1..5 or 24ppx.
- Using unsupported keywords — values like auto, thin, or large are not valid for line-height.
- Negative values — line-height does not accept negative numbers.
This matters for standards compliance and predictable rendering. While browsers may silently ignore an invalid line-height value and fall back to a default, this means your intended styling won’t be applied — potentially causing overlapping text, poor readability, or inconsistent layouts across browsers. Fixing validation errors ensures your styles work as intended everywhere.
Valid line-height values
| Format | Example | Description |
|---|---|---|
| Keyword | normal | Browser default (typically around 1.2) |
| Unitless number | 1.5 | Multiplied by the element’s font size — recommended |
| Length | 24px, 1.5em, 2rem | An absolute or relative length |
| Percentage | 150% | Relative to the element’s font size |
The unitless number format is generally preferred because it scales properly with inherited font sizes, avoiding unexpected results in nested elements.
Examples
❌ Incorrect: invalid values that trigger the error
<!-- Misspelled keyword -->
<p style="line-height: norml;">Text with an invalid line-height.</p>
<!-- Invalid unit -->
<p style="line-height: 1.5x;">Text with an unrecognized unit.</p>
<!-- Malformed number -->
<p style="line-height: 1..5;">Text with a typo in the number.</p>
<!-- Unsupported keyword -->
<p style="line-height: auto;">Auto is not valid for line-height.</p>
<!-- Negative value -->
<p style="line-height: -1.5;">Negative values are not allowed.</p>
✅ Correct: valid line-height values
<!-- Keyword -->
<p style="line-height: normal;">Browser default line height.</p>
<!-- Unitless number (recommended) -->
<p style="line-height: 1.5;">1.5 times the font size.</p>
<!-- Length with px -->
<p style="line-height: 24px;">Fixed 24px line height.</p>
<!-- Length with em -->
<p style="line-height: 1.5em;">1.5em line height.</p>
<!-- Percentage -->
<p style="line-height: 150%;">150% of the font size.</p>
Full document example
<!DOCTYPE html>
<html lang="en">
<head>
<title>Valid line-height Example</title>
</head>
<body>
<h1 style="line-height: 1.2;">A Heading with Tight Spacing</h1>
<p style="line-height: 1.6;">This paragraph uses a unitless line-height of 1.6,
which is a common choice for body text readability. It scales correctly even
if child elements have different font sizes.</p>
</body>
</html>
Tip: unitless vs. percentage/length
A unitless line-height and a percentage line-height may look equivalent, but they behave differently with inherited styles. A unitless value is recalculated for each child element based on its own font size, while a percentage or length is computed once on the parent and that fixed value is inherited. For most cases, unitless numbers are the safest choice.
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 vertical-align property controls the vertical positioning of inline-level elements (like <span>, <img>, and <a>) and table-cell elements (<td>, <th>) relative to their surrounding content or cell. Unlike some other CSS properties (such as float or border), vertical-align has no none keyword. Attempting to use none results in an invalid declaration that browsers will ignore, meaning the element will fall back to the default value of baseline.
This mistake often happens when a developer wants to “reset” or “remove” vertical alignment. Since there is no none value, the correct approach is to either set vertical-align: baseline (the initial value) or remove the vertical-align declaration altogether.
The valid keyword values for vertical-align are:
- baseline — aligns the element’s baseline with the parent’s baseline (default)
- sub — aligns as a subscript
- super — aligns as a superscript
- text-top — aligns with the top of the parent’s font
- text-bottom — aligns with the bottom of the parent’s font
- middle — aligns the middle of the element with the baseline plus half the x-height of the parent
- top — aligns the top of the element with the top of the tallest element on the line
- bottom — aligns the bottom of the element with the bottom of the lowest element on the line
In addition to keywords, vertical-align also accepts length values (e.g., 5px, 0.5em) and percentage values (e.g., 50%), which offset the element relative to the baseline.
Using an invalid value like none causes a W3C validation error and means your intended styling is silently ignored by the browser. This can lead to unexpected layout results that are difficult to debug, especially in table layouts or inline formatting contexts where vertical alignment significantly affects appearance.
Examples
❌ Invalid: using none
<p>
Text with an <img src="icon.png" alt="icon" style="vertical-align: none;"> inline image.
</p>
The validator will report that none is not a valid vertical-align value. The browser ignores the declaration and defaults to baseline.
✅ Fixed: using a valid keyword
If you want the image vertically centered with the text, use middle:
<p>
Text with an <img src="icon.png" alt="icon" style="vertical-align: middle;"> inline image.
</p>
✅ Fixed: resetting to the default
If your intent was to “remove” any vertical alignment, use baseline (the initial value) or simply remove the property:
<p>
Text with an <img src="icon.png" alt="icon" style="vertical-align: baseline;"> inline image.
</p>
❌ Invalid: none in a stylesheet for table cells
<style>
td.reset {
vertical-align: none;
}
</style>
<table>
<tr>
<td class="reset">Cell content</td>
</tr>
</table>
✅ Fixed: valid value for table cells
For table cells, the default vertical-align value is middle in most browsers. To explicitly reset it or set a specific alignment:
<style>
td.top-aligned {
vertical-align: top;
}
</style>
<table>
<tr>
<td class="top-aligned">Cell content</td>
</tr>
</table>
✅ Fixed: using a length value
You can also use a specific length to offset the element from the baseline:
<p>
Text with a <span style="vertical-align: 4px;">slightly raised</span> word.
</p>
Choose the value that matches your design intent — baseline to reset, middle or top for common alignment needs, or a specific length or percentage for precise control.
When the W3C validator reports that "px" is not a valid margin-left value, it means the CSS declaration is missing its numeric component. A bare unit like px is meaningless on its own — CSS needs to know how many pixels you want. This typically happens due to a typo, an accidental deletion, or a templating/build tool that outputted an empty variable before the unit.
This matters because browsers will discard the entire declaration as invalid, meaning margin-left will fall back to its default or inherited value. This can cause unexpected layout shifts and make your design behave inconsistently. The issue applies equally to any CSS length property, not just margin-left.
Valid values for margin-left
The margin-left property accepts:
- A length value: a number followed by a unit, such as 10px, 2em, 1.5rem, 5vw
- A percentage: e.g., 5%
- The keyword auto
- The value 0 (which requires no unit)
A unit without a preceding number (like px, em, or %) is never valid.
Examples
Incorrect: unit with no number
<div style="margin-left: px;">Content</div>
The browser cannot interpret px alone and will ignore the declaration entirely.
Correct: number with a unit
<div style="margin-left: 10px;">Content</div>
Correct: zero margin (no unit needed)
<div style="margin-left: 0;">Content</div>
Incorrect: empty variable in a template
This issue often appears when a dynamic value is missing. For example, in a template:
<!-- If "spacing" is empty, this produces "margin-left: px;" -->
<div style="margin-left: {{spacing}}px;">Content</div>
To guard against this, ensure the variable always contains a valid number, or provide a fallback default.
Correct: using CSS custom properties with a fallback
If you’re working with CSS custom properties, you can use var() with a fallback value to prevent invalid declarations:
<div style="margin-left: var(--spacing, 10px);">Content</div>
Correct: in an external stylesheet
If the issue is in a linked stylesheet rather than inline styles, the same fix applies:
/* Incorrect */
.sidebar {
margin-left: px;
}
/* Correct */
.sidebar {
margin-left: 20px;
}
Quick checklist
- Ensure every length value has a number before the unit (e.g., 16px, 1em, 2rem).
- If you want no margin, use 0 — it’s the only numeric value that doesn’t need a unit.
- If using templates or preprocessors, verify that variables resolve to actual numbers before being concatenated with units.
- Consider using CSS calc() if you need computed values: margin-left: calc(2em + 4px);.
The HTML living standard mandates UTF-8 as the only permitted character encoding for HTML documents. Legacy encodings like windows-1252, iso-8859-1, shift_jis, and others were common in older web pages, but they support only a limited subset of characters. UTF-8, on the other hand, can represent every character in the Unicode standard, making it universally compatible across languages and scripts.
This issue typically arises from one or more of these causes:
- Missing or incorrect <meta charset> declaration — Your document either lacks a charset declaration or explicitly declares a legacy encoding like <meta charset="windows-1252">.
- File not saved as UTF-8 — Even with the correct <meta> tag, if your text editor saves the file in a different encoding, characters may become garbled (mojibake).
- Server sends a conflicting Content-Type header — The HTTP Content-Type header can override the in-document charset declaration. If your server sends Content-Type: text/html; charset=windows-1252, the browser will use that encoding regardless of what the <meta> tag says.
Why This Matters
- Standards compliance: The WHATWG HTML living standard explicitly states that documents must be encoded in UTF-8. Using a legacy encoding makes your document non-conforming.
- Internationalization: Legacy encodings like windows-1252 only support a limited set of Western European characters. If your content ever includes characters outside that range—emoji, CJK characters, Cyrillic, Arabic, or even certain punctuation—they won’t render correctly.
- Security: Mixed or ambiguous encodings can lead to security vulnerabilities, including certain types of cross-site scripting (XSS) attacks that exploit encoding mismatches.
- Consistency: When the declared encoding doesn’t match the actual file encoding, browsers may misinterpret characters, leading to garbled text that’s difficult to debug.
How to Fix It
Step 1: Declare UTF-8 in your HTML
Add a <meta charset="utf-8"> tag as the first element inside <head>. It must appear within the first 1024 bytes of the document so browsers can detect it early.
Step 2: Save the file as UTF-8
In most modern text editors and IDEs, you can set the file encoding:
- VS Code: Click the encoding label in the bottom status bar and select “Save with Encoding” → “UTF-8”.
- Sublime Text: Go to File → Save with Encoding → UTF-8.
- Notepad++: Go to Encoding → Convert to UTF-8.
If your file already contains characters encoded in windows-1252, simply changing the declaration without re-encoding the file will cause those characters to display incorrectly. You need to convert the file’s actual encoding.
Step 3: Check your server configuration
If your server sends a charset parameter in the Content-Type HTTP header, make sure it specifies UTF-8. For example, in Apache you can add this to your .htaccess file:
AddDefaultCharset UTF-8
In Nginx, you can set it in your server block:
charset utf-8;
Examples
Incorrect: Legacy encoding declared
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="windows-1252">
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
This triggers the error because windows-1252 is a legacy encoding.
Incorrect: Using the long-form http-equiv with a legacy encoding
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
This older syntax also triggers the error when it specifies a non-UTF-8 encoding.
Correct: UTF-8 declared properly
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
The <meta charset="utf-8"> tag appears as the first child of <head>, and the file itself should be saved with UTF-8 encoding.
Correct: Using http-equiv with UTF-8
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
While the shorter <meta charset="utf-8"> form is preferred, this longer syntax is also valid as long as it specifies UTF-8.
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 revert keyword is one of the CSS-wide keywords defined in the CSS Cascading and Inheritance specification (along with initial, inherit, and unset). These keywords are valid values for every CSS property. When applied, revert rolls back the cascade to the value the property would have had if no author-level styles were applied — effectively reverting to the browser’s default stylesheet (or the user stylesheet, if one exists).
Older versions of the Nu HTML Checker (the engine behind the W3C HTML Validator) did not fully recognize revert as a valid CSS-wide keyword for all properties, which caused this false positive. This has been fixed in newer versions of the validator. If you’re using a local or outdated instance of the validator, updating to the latest version should resolve the issue.
Since this is a validator bug rather than a code issue, you have a few options: ignore the warning, update your validator, or use an alternative approach if you need a clean validation report. For example, you could use unset instead, which behaves similarly in many cases (though not identically — unset reverts to the inherited or initial value, while revert reverts to the user-agent default).
Examples
Code that triggers the false positive
This inline style uses revert on font-size, which is perfectly valid CSS but may trigger the validator warning:
<p style="font-size: revert;">This paragraph uses the browser's default font size.</p>
Workaround using unset
If you need to pass validation on an older validator instance, unset can serve as a partial substitute. Note that unset behaves differently from revert — it resets to the inherited value (for inherited properties like font-size) rather than the user-agent default:
<p style="font-size: unset;">This paragraph inherits the font size from its parent.</p>
Using revert in a stylesheet
The revert keyword is especially useful when you want to undo author styles for specific elements. This is valid CSS and should not produce errors in up-to-date validators:
<style>
p {
font-size: 2rem;
}
.default-size {
font-size: revert;
}
</style>
<p>This paragraph has a 2rem font size.</p>
<p class="default-size">This paragraph reverts to the browser default font size.</p>
All CSS-wide keywords
For reference, all of these CSS-wide keywords are valid for font-size and every other CSS property:
<div style="font-size: initial;">Uses the property's initial value</div>
<div style="font-size: inherit;">Inherits from the parent element</div>
<div style="font-size: unset;">Resets to inherited or initial value</div>
<div style="font-size: revert;">Reverts to the user-agent default</div>
<div style="font-size: revert-layer;">Reverts to the previous cascade layer</div>
The text-align CSS property controls horizontal alignment of inline-level content within a block element. When the W3C HTML validator encounters an inline style attribute containing a text-align value it doesn’t recognize, it flags the error with a message like CSS: “text-align”: X is not a “text-align” value, where X is the offending value.
This error commonly occurs for a few reasons:
- Confusing text-align with vertical-align: Using middle, top, or bottom — these are vertical-align values, not text-align values.
- Typos: Writing cetner instead of center, or rigth instead of right.
- Using non-standard values: Trying values like auto, none, or arbitrary strings that aren’t part of the specification.
- Confusing CSS properties: Using Flexbox or Grid alignment values like flex-start or space-between with text-align.
While most browsers will silently ignore an invalid text-align value and fall back to the inherited or default alignment, relying on this behavior is problematic. It makes your intent unclear, can lead to inconsistent rendering, and signals that there may be a deeper misunderstanding in your styling approach. Valid CSS ensures predictable behavior across all browsers and assistive technologies.
Valid values for text-align
| Value | Description |
|---|---|
| left | Aligns content to the left edge |
| right | Aligns content to the right edge |
| center | Centers the content horizontally |
| justify | Stretches content to fill the full width |
| start | Aligns to the start edge (direction-aware) |
| end | Aligns to the end edge (direction-aware) |
The start and end values are logical properties that respect the document’s writing direction (dir attribute or direction CSS property), making them ideal for internationalized content.
Examples
Invalid: using middle instead of center
A common mistake is using middle, which is a valid value for vertical-align but not for text-align:
<p style="text-align: middle;">This text will fail validation.</p>
Fix: Replace middle with center:
<p style="text-align: center;">This text is properly centered.</p>
Invalid: typo in the value
<h2 style="text-align: cetner;">Heading</h2>
Fix: Correct the spelling:
<h2 style="text-align: center;">Heading</h2>
Invalid: using a non-existent value
<div style="text-align: auto;">Some content</div>
Fix: Choose a valid alignment value:
<div style="text-align: left;">Some content</div>
Invalid: using a vertical alignment value
<p style="text-align: top;">Paragraph text</p>
Fix: If you intended horizontal alignment, use a valid text-align value. If you actually need vertical positioning, use vertical-align on an inline or table-cell element instead:
<p style="text-align: left;">Paragraph text</p>
Valid examples showing all common values
<p style="text-align: left;">Left-aligned text.</p>
<p style="text-align: right;">Right-aligned text.</p>
<p style="text-align: center;">Centered text.</p>
<p style="text-align: justify;">Justified text stretches to fill the full width of its container.</p>
<p style="text-align: start;">Start-aligned (respects text direction).</p>
<p style="text-align: end;">End-aligned (respects text direction).</p>
When fixing this error, double-check which property you actually need. If you want to center a block-level element itself (not its text content), text-align isn’t the right tool — consider using margin: 0 auto or Flexbox instead. The text-align property is specifically for the horizontal alignment of inline content within its containing block.
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 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 padding-block shorthand property sets padding on the block-start and block-end sides of an element. In horizontal writing modes (like English), this corresponds to the top and bottom padding; in vertical writing modes, it maps to left and right. It’s the logical equivalent of combining padding-block-start and padding-block-end.
The reason auto is invalid here is that padding, by definition in the CSS specification, must resolve to a definite size. Margins can be auto because the browser uses that value in layout algorithms to distribute remaining space (e.g., centering a block element with margin-inline: auto). Padding, however, adds space inside an element’s border and has no such auto-distribution behavior defined in the spec. Attempting to use auto will cause the declaration to be ignored by browsers, meaning no padding is applied, which can lead to unexpected layout results.
This validation error often arises when developers confuse padding-block with margin-block, or when they copy centering patterns that work with margins and try to apply them to padding. If your intent was to center content, consider using margin-block: auto instead, or use Flexbox/Grid alignment properties.
How to Fix
Replace auto with a valid value:
- Length values: 0, 10px, 1em, 1.5rem, etc.
- Percentage values: 5%, 2% 1%, etc. (relative to the inline size of the containing block).
- Two values: padding-block: 20px 10px; sets padding-block-start to 20px and padding-block-end to 10px.
- CSS-wide keywords: inherit, initial, revert, revert-layer, or unset.
If you used auto to try to eliminate padding, use 0 instead. If you used it to try to center something, switch to margins or a layout method like Flexbox.
Examples
Incorrect: using auto as a padding-block value
<style>
.box {
padding-block: auto;
}
</style>
<div class="box">This box has invalid padding.</div>
The browser will ignore the padding-block: auto declaration entirely, and the W3C validator will flag it as an error.
Correct: using length values
<style>
.box {
padding-block: 20px 10px;
}
</style>
<div class="box">20px padding on block-start, 10px on block-end.</div>
Correct: using a single value for equal padding
<style>
.box {
padding-block: 1em;
}
</style>
<div class="box">1em padding on both block-start and block-end.</div>
Correct: removing padding with zero
<style>
.box {
padding-block: 0;
}
</style>
<div class="box">No block padding.</div>
If you intended to center: use margin-block instead
<style>
.container {
display: flex;
flex-direction: column;
height: 300px;
}
.centered {
margin-block: auto;
}
</style>
<div class="container">
<div class="centered">This element is vertically centered using margin-block: auto.</div>
</div>
The margin-block: auto approach works inside flex or grid containers to distribute space evenly, achieving vertical centering. This is likely what you want if you originally reached for padding-block: auto.
The padding-right property defines the amount of space between an element’s content and its right border. Like all CSS length properties, it expects either a valid length value (a number paired with a unit like px, em, rem, %, vw, etc.), the keyword 0 (which needs no unit), or the keyword inherit/initial/unset. A bare unit such as px with no number is meaningless — it doesn’t tell the browser how much padding to apply.
This error typically occurs due to a typo, a templating issue where a variable failed to render, or accidental deletion of the numeric portion of the value. For example, a template like padding-right: {{ value }}px; might produce padding-right: px; if value is empty or undefined.
When the browser encounters an invalid value like px, it discards the entire declaration and falls back to the default or inherited value for padding-right. This can lead to unexpected layout differences across browsers and makes your intentions unclear to other developers. Fixing these validation errors also helps maintain clean, predictable stylesheets.
How to Fix
- Add the missing number before the unit: change px to a specific value like 10px.
- Use 0 without a unit if you want no padding: padding-right: 0; is valid and preferred over padding-right: 0px;.
- Check template variables and dynamic style generation to ensure numeric values are always output correctly.
Examples
Incorrect: bare unit with no number
<div style="padding-right: px;">Content</div>
The value px is not valid because it lacks a numeric component.
Correct: numeric value with unit
<div style="padding-right: 10px;">Content</div>
Correct: zero padding (no unit needed)
<div style="padding-right: 0;">Content</div>
Correct: using other valid units
<div style="padding-right: 2em;">Content</div>
<div style="padding-right: 5%;">Content</div>
Incorrect in an external stylesheet
.sidebar {
padding-right: px;
}
Fixed in an external stylesheet
.sidebar {
padding-right: 16px;
}
Guarding against empty values in templates
If you generate CSS dynamically, make sure the numeric value is always present. For instance, provide a fallback:
.sidebar {
padding-right: 16px; /* safe default */
}
Rather than relying on a template that might produce an empty value, consider setting defaults in your CSS and only overriding with inline styles when you’re certain the value is valid.
This error is misleading at first glance because the <meta> tag in question is often perfectly well-formed. The real problem is usually above the <meta> tag — an element that doesn’t belong in <head> (such as <img>, <div>, <p>, or other flow content) has been placed there. When the HTML parser encounters such an element inside <head>, it implicitly closes the <head> and opens the <body>. From that point on, any subsequent <meta> tags are now technically inside the <body>, where the name attribute on <meta> is not permitted.
In other cases, the error can also occur when a <meta name="..."> tag is explicitly placed inside <body>, or when a typo or malformed tag earlier in the document breaks the expected document structure.
This matters for several reasons. Search engines and social media platforms rely on <meta> tags being in the <head> to extract page descriptions, Open Graph data, and other metadata. If the document structure is broken and <meta> tags end up in the <body>, this metadata may be ignored entirely. Additionally, elements like <img> inside <head> won’t render as expected, and the overall document structure will be invalid, potentially causing unpredictable behavior across browsers.
How to fix it
- Look above the flagged <meta> tag. Find any element in the <head> that doesn’t belong there — common culprits include <img>, <div>, <span>, <p>, <a>, or <section>.
- Move the offending element into the <body> where it belongs.
- If the <meta> tag itself is in the <body>, move it into the <head>.
- Check for malformed tags above the <meta> — an unclosed tag or a typo can break the parser’s understanding of the document structure.
Only certain elements are allowed inside <head>: <title>, <meta>, <link>, <style>, <script>, <noscript>, <base>, and <template>.
Examples
An invalid element in <head> breaks the context
The <img> tag is not allowed inside <head>. The parser implicitly closes <head> when it encounters it, so the <meta> tag that follows ends up in <body>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<img src="photo.jpg" alt="A smiling cat">
<meta name="description" content="A page about cats">
</head>
<body>
<p>Welcome!</p>
</body>
</html>
Move the <img> into the <body> to fix the issue:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<meta name="description" content="A page about cats">
</head>
<body>
<img src="photo.jpg" alt="A smiling cat">
<p>Welcome!</p>
</body>
</html>
A <meta> tag accidentally placed in <body>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<meta name="author" content="Jane Doe">
<p>Hello world</p>
</body>
</html>
Move the <meta> tag into <head>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<meta name="author" content="Jane Doe">
</head>
<body>
<p>Hello world</p>
</body>
</html>
A malformed tag disrupts the <head>
A missing closing > on a <link> tag can confuse the parser, causing subsequent elements to be misinterpreted:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<link rel="stylesheet" href="style.css"
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Content</p>
</body>
</html>
Close the <link> tag properly:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Content</p>
</body>
</html>
Nested comments are not allowed in HTML. When you place an opening comment tag <!-- within an existing comment, it causes a parsing error.
To fix this issue, you should avoid nesting comments. If you need to include multiple comments in your HTML code, you can separate them or consider alternative ways to convey the information without nested comments.
Here’s an example of a nested comments, which is not allowed in HTML:
<!-- This is a valid comment -->
<!-- This <!-- is not allowed -->
nested comment -->
To fix the nested comment issue, you can rewrite the comments like this:
<!-- This is a valid comment -->
<!-- Avoid nesting comments and provide comments separately -->
<!-- Another comment here -->
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 border-radius property controls the rounding of an element’s corners. Its valid values include lengths (e.g., 5px, 1em), percentages (e.g., 50%), and CSS-wide keywords like inherit, initial, and unset. Unlike many other border-related properties, border-radius has no none keyword in its value syntax.
This confusion typically arises because developers associate “no effect” with the keyword none, which works for properties like border: none or text-decoration: none. However, border-radius describes a geometric measurement — the radius of the corner curve — so “zero radius” (0) is the correct way to express no rounding.
Using an invalid value means the browser will ignore the entire declaration. This can lead to unexpected results: if a parent stylesheet or an earlier rule sets a border-radius, your none declaration won’t override it, and the element will retain its rounded corners. Fixing this ensures your CSS is standards-compliant, behaves predictably across browsers, and passes W3C validation.
How to fix it
- To remove rounding, replace none with 0.
- To set a specific radius, use a valid length (5px, 0.5em), a percentage (50%), or a CSS-wide keyword (inherit, initial, unset).
- The same rule applies to the longhand properties: border-top-left-radius, border-top-right-radius, border-bottom-right-radius, and border-bottom-left-radius.
Examples
Incorrect: using none
<style>
.box {
border-radius: none; /* "none" is not a valid border-radius value */
}
</style>
<div class="box">Content</div>
Correct: removing rounded corners with 0
<style>
.box {
border-radius: 0;
}
</style>
<div class="box">Content</div>
Correct: applying a specific radius
<style>
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
}
.rounded {
border-radius: 8px;
}
.pill {
border-radius: 9999px;
}
</style>
<div class="circle">Circle</div>
<div class="rounded">Rounded</div>
<div class="pill">Pill shape</div>
Correct: resetting to the initial value
If you need to undo a border-radius set by another rule, you can use initial or unset, both of which resolve to 0:
<style>
.card {
border-radius: 12px;
}
.card.sharp {
border-radius: initial; /* Resets to 0 */
}
</style>
<div class="card">Rounded card</div>
<div class="card sharp">Sharp-cornered card</div>
The mask CSS shorthand property allows you to hide parts of an element by masking or clipping it at specific points. It combines several longhand properties into one declaration: mask-image, mask-mode, mask-repeat, mask-position, mask-clip, mask-origin, mask-size, and mask-composite.
Because mask is a shorthand that accepts values for many sub-properties, it’s easy to trigger validation errors. Common causes include:
- Too many values: Providing more values than the shorthand grammar allows, or duplicating values for the same sub-property.
- Unrecognized values: Using vendor-specific values (like -webkit- prefixed keywords), typos, or values that belong to a different CSS property.
- Incorrect value order: The shorthand has a specific grammar. For example, mask-size values must follow mask-position values and be separated by a /, similar to the background shorthand.
- Mixing shorthand and longhand concepts: Trying to set values that aren’t part of the mask shorthand grammar.
The formal syntax for a single mask layer is:
<mask-layer> = <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> ||
<geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator> ||
<masking-mode>
This is a problem for standards compliance because invalid CSS can lead to the entire declaration being ignored by browsers, causing your masking effect to silently fail. It also affects cross-browser compatibility — different browsers have varying levels of support for the mask shorthand, and using individual longhand properties is often more reliable.
To fix this issue:
- Check each value in your mask declaration and ensure it’s a valid value for one of the mask sub-properties.
- Use longhand properties instead of the shorthand if you only need to set one or two aspects of the mask. This avoids ambiguity and improves readability.
- Separate position and size with / if you’re specifying both, e.g., center / contain.
- Remove or separate vendor prefixes — use -webkit-mask for WebKit-specific syntax and the standard mask for standards-compliant syntax, but don’t mix prefixed values into the unprefixed property.
Examples
Incorrect: too many or unrecognized values in the shorthand
<style>
.masked {
/* Error: too many values / unrecognized combination */
mask: url(mask.svg) center center no-repeat contain;
}
</style>
<div class="masked">Content</div>
Here, contain is a mask-size value but it must be separated from the position with a /. Without the slash, the validator sees an extra unrecognized value.
Correct: proper shorthand syntax with position and size
<style>
.masked {
mask: url(mask.svg) center / contain no-repeat;
}
</style>
<div class="masked">Content</div>
The / separates mask-position (center) from mask-size (contain), just like in the background shorthand.
Correct: using longhand properties for clarity and compatibility
<style>
.masked {
width: 100px;
height: 100px;
background-color: #8cffb0;
-webkit-mask-image: url(sun.svg);
mask-image: url(sun.svg);
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
</style>
<div class="masked">Content</div>
Using individual longhand properties avoids shorthand parsing issues entirely. Including the -webkit-mask-image prefix alongside the standard mask-image ensures broader browser support.
Incorrect: unrecognized value in the shorthand
<style>
.masked {
/* "luminance" is a mask-mode value but may not be recognized in the shorthand by all validators */
mask: url(mask.png) luminance;
}
</style>
<div class="masked">Content</div>
Correct: using the longhand for mask mode
<style>
.masked {
mask-image: url(mask.png);
mask-mode: luminance;
}
</style>
<div class="masked">Content</div>
When in doubt, splitting the mask shorthand into its individual longhand properties is the safest approach. It makes your intent explicit, avoids validation errors, and tends to have better cross-browser support.
The W3C validator checks inline styles and embedded stylesheets for valid CSS. When it encounters a height declaration with multiple values or an unrecognized value, it flags the error because height is not a shorthand property — it only accepts one value at a time. This differs from properties like margin or padding, which accept multiple values to target different sides of an element.
This error commonly occurs when you:
- Accidentally provide two values, perhaps confusing height with a shorthand property (e.g., height: 100px 50px;).
- Include a typo or invalid unit (e.g., height: 100ppx; or height: 100pixels;).
- Use a CSS function incorrectly (e.g., height: calc(100% 20px); — missing the operator).
- Copy a value meant for another property, such as pasting a grid-template-rows value into height.
Browsers may silently ignore invalid height declarations, causing your element to fall back to its default sizing (auto). This can lead to unexpected layout behavior that’s difficult to debug. Keeping your CSS valid ensures consistent rendering across browsers and helps catch mistakes early.
Valid values for height
The height property accepts exactly one of the following:
- Length values: 100px, 10em, 5rem, 20vh, etc.
- Percentage values: 50%, 100%
- Keyword values: auto, max-content, min-content, fit-content(200px)
- Global values: inherit, initial, revert, unset
- Calc expressions: calc(100% - 20px), calc(50vh + 2rem)
Examples
Incorrect: too many values
<style>
.box {
height: 100px 50px; /* Error: height only accepts one value */
}
</style>
<div class="box">Content</div>
Incorrect: unrecognized value
<style>
.box {
height: 100pixels; /* Error: "pixels" is not a valid unit */
}
</style>
<div class="box">Content</div>
Incorrect: malformed calc() expression
<style>
.box {
height: calc(100% 20px); /* Error: missing operator between values */
}
</style>
<div class="box">Content</div>
Correct: single length value
<style>
.box {
height: 100px;
}
</style>
<div class="box">Content</div>
Correct: percentage value
<style>
.box {
height: 50%;
}
</style>
<div class="box">Content</div>
Correct: calc() with proper operator
<style>
.box {
height: calc(100% - 20px);
}
</style>
<div class="box">Content</div>
Correct: keyword value
<style>
.box {
height: auto;
}
</style>
<div class="box">Content</div>
If you need to set both width and height, remember they are separate properties and must be declared individually. If you were trying to set a minimum and maximum height, use min-height and max-height as distinct declarations instead of combining values into a single height property.
The <meta charset="utf-8"> declaration is not only valid but recommended by the HTML living standard. So when the validator complains that the charset attribute is “not allowed at this point,” the problem isn’t the <meta> tag itself — it’s what surrounds it. The HTML parser follows strict rules about which elements can appear inside <head>. When it encounters an element that doesn’t belong there (like <img>, <div>, <p>, or other flow/phrasing content), it implicitly closes the <head> and opens the <body>. Any <meta> tags that come after that point are now parsed as being inside <body>, where <meta charset> is not permitted.
This is a problem for several reasons. First, the <meta charset> declaration must appear within the first 1024 bytes of the document so browsers can determine the character encoding early. If the parser moves it out of <head>, browsers may not apply the encoding correctly, potentially leading to garbled text — especially for non-ASCII characters. Second, this often signals a structural error in your HTML that could cause other unexpected rendering issues.
Common causes include:
- An element that only belongs in <body> (like <img>, <div>, <span>, or <p>) placed before <meta charset> in the <head>.
- A stray closing tag (like </head>) appearing too early.
- A <script> tag with content that causes the parser to break out of <head>.
To fix the issue, inspect the elements that appear before <meta charset> in your <head>. Move any elements that don’t belong in <head> into <body>, and place <meta charset="utf-8"> as the very first element inside <head>.
Examples
Incorrect — element before <meta> forces parser out of <head>
An <img> tag inside <head> causes the parser to implicitly close <head> and open <body>. The <meta charset> that follows is now parsed as being in <body>, triggering the error.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<img src="photo.jpg" alt="A smiling cat">
<meta charset="utf-8">
</head>
<body>
<p>Some content</p>
</body>
</html>
Correct — <meta charset> first, invalid elements moved to <body>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<img src="photo.jpg" alt="A smiling cat">
<p>Some content</p>
</body>
</html>
Incorrect — stray <div> in <head> breaks context
<!DOCTYPE html>
<html lang="en">
<head>
<div>Oops</div>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Hello</p>
</body>
</html>
Correct — only valid head elements before <meta charset>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<div>Content goes here</div>
<p>Hello</p>
</body>
</html>
Best practice
As a general rule, always make <meta charset="utf-8"> the very first child of <head>. This ensures the browser detects the encoding as early as possible and avoids the risk of other elements accidentally breaking the parser context before the charset is declared.
The pointer-events CSS property controls whether an element can be the target of pointer events such as clicks, taps, and hover states. Unlike many other CSS properties that accept normal as a keyword (e.g., white-space, letter-spacing), the pointer-events property does not include normal in its list of valid values. This is a common mistake since normal and auto are often used interchangeably across different CSS properties, but each property defines its own set of accepted keywords.
Using an invalid value like normal means the browser will ignore the entire declaration. In most cases this won’t cause visible breakage because the default behavior already allows pointer interaction, but it can lead to unexpected results if you’re relying on the property to override an inherited pointer-events: none from a parent element. The invalid declaration would simply be discarded, and the inherited none value would remain in effect, making the element unclickable.
For standard HTML elements, the two primary values you’ll use are:
- auto — The element behaves as it normally would regarding pointer events. This is the default.
- none — The element is never the target of pointer events. Clicks and hovers pass through to whatever is behind it.
Several additional values exist (visiblePainted, visibleFill, visibleStroke, visible, painted, fill, stroke, all) but these only apply to SVG elements. Global CSS keywords like inherit, initial, unset, and revert are also valid.
To fix the issue, replace normal with auto wherever it appears as a pointer-events value. If you’re using pointer-events: normal to restore default interactivity after a parent set pointer-events: none, then auto is exactly what you need.
Examples
Incorrect — using normal
<div style="pointer-events: normal;">
<a href="/about">About us</a>
</div>
The validator will flag normal as an invalid value for pointer-events.
Correct — using auto
<div style="pointer-events: auto;">
<a href="/about">About us</a>
</div>
Practical use case: restoring pointer events on a child
A common pattern is disabling pointer events on a parent and re-enabling them on a specific child. Using normal here would silently fail, leaving the button unclickable:
<!-- Incorrect -->
<style>
.overlay {
pointer-events: none;
}
.overlay .close-btn {
pointer-events: normal; /* Invalid — button remains unclickable */
}
</style>
<div class="overlay">
<button class="close-btn">Close</button>
</div>
<!-- Correct -->
<style>
.overlay {
pointer-events: none;
}
.overlay .close-btn {
pointer-events: auto; /* Valid — button is clickable again */
}
</style>
<div class="overlay">
<button class="close-btn">Close</button>
</div>
In the incorrect version, the browser discards the invalid pointer-events: normal declaration entirely, so the .close-btn inherits none from the parent and cannot be clicked. Changing it to auto correctly restores interactivity on the button.
The CSS width property sets an element’s width and accepts a single value. The W3C validator reports this error when it encounters something it cannot parse as a valid width declaration. Common causes include:
- Missing units: Writing width: 300 instead of width: 300px. CSS requires explicit units for non-zero lengths.
- Multiple values: Writing width: 100px 200px as if width accepted shorthand-style multiple values (it doesn’t).
- Typos or invalid keywords: Writing width: auot instead of width: auto, or using a made-up keyword.
- Invalid functions or syntax: Using incorrect function syntax like width: calc(100% - 20px) with missing spaces around operators, or using browser-prefixed values without a standard fallback.
- Unsupported values: Using newer CSS values like fit-content or max-content in a context where the validator’s CSS level doesn’t recognize them.
This matters because invalid CSS can cause browsers to silently discard the entire declaration, meaning your intended layout won’t be applied. Different browsers may handle invalid values differently, leading to inconsistent rendering. Keeping your CSS valid ensures predictable, cross-browser behavior.
Valid values for width
The width property accepts exactly one of the following:
- Length values: A number with a unit, such as 300px, 25em, 10rem, 5vw.
- Percentage values: A percentage relative to the containing block, such as 75%.
- Keyword values: auto, max-content, min-content, fit-content.
- Function values: fit-content(20em), calc(100% - 40px), min(300px, 100%), max(200px, 50%), clamp(200px, 50%, 600px).
- Global values: inherit, initial, revert, revert-layer, unset.
Note that 0 is the only numeric value that does not require a unit.
Examples
Incorrect: missing unit
<style>
.box {
width: 300;
}
</style>
<div class="box">Content</div>
A bare number (other than 0) is not valid. The browser won’t know if you mean pixels, ems, or something else.
Correct: unit provided
<style>
.box {
width: 300px;
}
</style>
<div class="box">Content</div>
Incorrect: too many values
<style>
.sidebar {
width: 200px 400px;
}
</style>
<aside class="sidebar">Sidebar</aside>
Unlike properties such as margin or padding, width only accepts a single value.
Correct: single value
<style>
.sidebar {
width: 200px;
}
</style>
<aside class="sidebar">Sidebar</aside>
Incorrect: typo in keyword
<style>
.container {
width: auot;
}
</style>
<div class="container">Content</div>
Correct: proper keyword
<style>
.container {
width: auto;
}
</style>
<div class="container">Content</div>
Incorrect: malformed calc() expression
<style>
.panel {
width: calc(100%-40px);
}
</style>
<div class="panel">Content</div>
The calc() function requires spaces around + and - operators.
Correct: properly spaced calc() expression
<style>
.panel {
width: calc(100% - 40px);
}
</style>
<div class="panel">Content</div>
Incorrect: accidental semicolon or extra text
<style>
.card {
width: 50% important;
}
</style>
<div class="card">Content</div>
If you intended to use !important, the ! is required.
Correct: proper !important syntax
<style>
.card {
width: 50% !important;
}
</style>
<div class="card">Content</div>
Ready to validate your sites?
Start your free trial today.