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 padding-left property accepts a valid CSS length value, a percentage, or the keyword 0. A CSS length is always composed of two parts: a number and a unit (e.g., 10px, 2em, 1.5rem). Writing just px with no number is syntactically invalid — it’s a bare unit with no magnitude, so the browser cannot determine what spacing to apply. This commonly occurs due to a typo, a missing variable in a template or preprocessor, or accidentally deleting the numeric portion during editing.
When the validator encounters this in a style attribute, it flags the value as invalid CSS. While most browsers will simply ignore the malformed declaration and fall back to the default padding, relying on this error-recovery behavior leads to unpredictable layouts. Fixing the issue ensures your styles are applied consistently across all browsers and that your markup passes validation.
How to fix it
- Add a numeric value before the unit: change px to something like 10px, 1em, or 5%.
- If you want zero padding, use 0 — no unit is needed (though 0px is also valid).
- Check template variables and preprocessors. If you’re using a system like PHP, JavaScript templating, or a CSS preprocessor (Sass, Less), make sure the variable that should supply the number isn’t empty or undefined. For example, padding-left: <?= $indent ?>px; will produce padding-left: px; if $indent is empty.
Examples
Incorrect: bare unit with no number
<div style="padding-left: px;">Content</div>
The value px has no numeric component, so it is not a valid length.
Correct: numeric value before the unit
<div style="padding-left: 10px;">Content</div>
Correct: zero padding (no unit required)
<div style="padding-left: 0;">Content</div>
Incorrect: empty variable producing a bare unit
This is a common source of the bug in templated or dynamically generated HTML:
<!-- If the variable is empty, this renders as "padding-left: px;" -->
<div style="padding-left: px;">Content</div>
Correct: ensuring a fallback value
When generating styles dynamically, always provide a sensible default so the output is valid even if the variable is missing:
<div style="padding-left: 16px;">Content</div>
Using an external stylesheet
The same rule applies in external or embedded CSS. The incorrect version:
.sidebar {
padding-left: px;
}
The corrected version with a proper numeric value:
.sidebar {
padding-left: 20px;
}
Other valid padding-left values
Any valid CSS length or percentage works:
<div style="padding-left: 2em;">Em-based padding</div>
<div style="padding-left: 1.5rem;">Rem-based padding</div>
<div style="padding-left: 5%;">Percentage-based padding</div>
The font-style and font-weight properties serve different purposes. font-style controls whether text appears in a normal, italic, or oblique style, while font-weight controls how thick or thin the characters are rendered. Writing font-style: bold is a mistake because bold is not among the accepted values for font-style. Browsers will ignore the invalid declaration entirely, meaning your text won’t become bold at all — it will simply render in the default weight.
This error typically comes from confusing the two properties or misremembering which property handles boldness. The valid values for each property are:
- font-style: normal, italic, oblique, or oblique with an angle (e.g., oblique 10deg)
- font-weight: normal, bold, bolder, lighter, or numeric values from 100 to 900
To fix this issue, replace font-style: bold with font-weight: bold. If you intended to make text both bold and italic, you’ll need to use both properties separately.
Examples
Incorrect — using bold with font-style
This triggers the validation error because bold is not a valid font-style value:
<p style="font-style: bold;">This text won't actually be bold.</p>
Correct — using font-weight for boldness
Move the bold value to the font-weight property:
<p style="font-weight: bold;">This text is bold.</p>
Correct — combining bold and italic
If you want text that is both bold and italic, use both properties:
<p style="font-weight: bold; font-style: italic;">This text is bold and italic.</p>
Correct — using font-weight in a stylesheet
You can also apply bold styling through a <style> block or external stylesheet, using either keyword or numeric values:
<style>
.emphasis {
font-weight: bold;
}
.light {
font-weight: 300;
}
.heavy {
font-weight: 900;
}
</style>
<p class="emphasis">This text is bold (weight 700).</p>
<p class="light">This text is light (weight 300).</p>
<p class="heavy">This text is extra heavy (weight 900).</p>
Note that the keyword bold is equivalent to the numeric value 700, and normal is equivalent to 400. Numeric values give you finer control over text weight, especially when using variable fonts or font families that offer multiple weight variations.
The aria-labelledby attribute is part of the WAI-ARIA specification and provides an accessible name for an element by referencing the id values of other elements that contain the labeling text. Without the aria- prefix, labelledby is simply an unrecognized attribute that browsers and assistive technologies will ignore. This means your SVG graphic won’t have the accessible label you intended, leaving screen reader users without a meaningful description of the content.
This issue is especially important for <svg> elements because SVG graphics are often used for icons, charts, and illustrations that need descriptive labels for accessibility. Using the incorrect attribute name means the graphic is effectively unlabeled for users who rely on assistive technology.
How to Fix It
Replace labelledby with aria-labelledby on your <svg> element. The attribute’s value should be a space-separated list of one or more id values that reference elements containing the label text.
If you want to label an SVG using text that’s already visible on the page, aria-labelledby is the ideal approach. You can also reference a <title> element inside the SVG itself.
Examples
❌ Incorrect: Using labelledby (invalid attribute)
<h2 id="chart-title">Monthly Sales</h2>
<svg labelledby="chart-title" role="img" viewBox="0 0 200 100">
<!-- chart content -->
</svg>
✅ Correct: Using aria-labelledby to reference an external heading
<h2 id="chart-title">Monthly Sales</h2>
<svg aria-labelledby="chart-title" role="img" viewBox="0 0 200 100">
<!-- chart content -->
</svg>
✅ Correct: Using aria-labelledby to reference the SVG’s own <title>
<svg aria-labelledby="icon-title" role="img" viewBox="0 0 24 24">
<title id="icon-title">Search</title>
<path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5z"/>
</svg>
✅ Correct: Referencing multiple label sources
You can combine multiple id values to build a composite accessible name, separated by spaces:
<h2 id="section-title">Revenue</h2>
<p id="section-desc">Q1 2024 revenue by region</p>
<svg aria-labelledby="section-title section-desc" role="img" viewBox="0 0 400 200">
<!-- chart content -->
</svg>
In this case, a screen reader would announce something like “Revenue Q1 2024 revenue by region” as the accessible name for the SVG.
Tips
- When using aria-labelledby on <svg>, also add role="img" to ensure consistent behavior across screen readers.
- If the SVG is purely decorative, use aria-hidden="true" instead of labeling it.
- The aria-labelledby attribute overrides other labeling mechanisms like aria-label or the <title> element, so use it when you want a specific label to take precedence.
Character encoding tells the browser how to map the raw bytes of your HTML file into readable characters. When no encoding is declared, browsers must rely on heuristics or defaults to figure out which encoding to use. The validator’s fallback to “windows-1252” reflects the behavior described in the HTML specification: if no encoding information is found, parsers may default to this legacy encoding. This can cause serious problems — characters like curly quotes, em dashes, accented letters, emoji, and non-Latin scripts can appear as garbled text (often called “mojibake”) if the actual encoding of the file doesn’t match what the browser assumes.
Why this matters
- Correctness: If your file is saved as UTF-8 (which is the default in most modern editors) but the browser interprets it as windows-1252, multi-byte characters will render incorrectly.
- Standards compliance: The WHATWG HTML Living Standard requires that a character encoding declaration be present. The encoding must also be declared within the first 1024 bytes of the document.
- Security: Ambiguous encoding can be exploited in certain cross-site scripting (XSS) attacks where an attacker takes advantage of encoding mismatches.
- Interoperability: Different browsers may choose different fallback encodings, leading to inconsistent rendering across platforms.
How to fix it
The simplest and recommended fix is to add <meta charset="utf-8"> as the first child element inside <head>, before <title> or any other elements. It must appear within the first 1024 bytes of the document so the parser encounters it early enough.
UTF-8 is the universal standard for the web. It can represent every character in Unicode, is backward-compatible with ASCII, and is the encoding recommended by the WHATWG HTML specification. Unless you have a very specific reason to use another encoding, always use UTF-8.
You should also ensure your text editor or build tool is actually saving the file in UTF-8 encoding. Declaring <meta charset="utf-8"> while the file is saved in a different encoding will still produce garbled text.
An alternative (less common) approach is to declare the encoding via an HTTP Content-Type header sent by the server, such as Content-Type: text/html; charset=utf-8. However, the <meta> tag is still recommended as a fallback for when files are viewed locally or cached without headers.
Examples
❌ Missing character encoding declaration
This document has no encoding declaration, triggering the validator warning:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Héllo, wörld! — enjoy "quotes" and emöji 🎉</p>
</body>
</html>
✅ Fixed with <meta charset="utf-8">
Adding the <meta charset="utf-8"> tag as the first element in <head> resolves the issue:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Héllo, wörld! — enjoy "quotes" and emöji 🎉</p>
</body>
</html>
❌ Encoding declared too late
The <meta charset> must come before other content in the <head>. Placing it after a <title> that contains non-ASCII characters means the parser may have already committed to a wrong encoding:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Café Menu</title>
<meta charset="utf-8">
</head>
<body>
<p>Welcome to the café.</p>
</body>
</html>
✅ Encoding declared before all other content
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Café Menu</title>
</head>
<body>
<p>Welcome to the café.</p>
</body>
</html>
The key takeaway: always place <meta charset="utf-8"> as the very first element inside <head>. This is a small addition that prevents a whole class of character rendering and security issues.
In CSS, most numeric values of 0 don’t need a unit — for example, margin: 0 is perfectly valid because the specification allows unitless zero for <length> values. However, this exception does not apply to <time> values. Properties that accept <time> values, such as transition-delay, transition-duration, animation-delay, and animation-duration, always require a unit (s for seconds or ms for milliseconds), even when the value is zero.
The CSS specification explicitly states that <time> values must include a unit. The unitless 0 shorthand is only permitted for <length> and a few other value types. While some browsers may silently accept transition-delay: 0 and treat it as 0s, this behavior is non-standard and not guaranteed across all browsers or future implementations. Relying on it can lead to inconsistent rendering and will fail W3C CSS validation.
This issue commonly appears when transition-delay is set as part of the transition shorthand, or when developers assume that 0 is universally valid without a unit in CSS.
How to fix it
Add the s (seconds) or ms (milliseconds) unit to any <time> value that is currently a bare 0:
- 0 → 0s or 0ms
- Check both longhand properties (transition-delay, transition-duration) and the transition shorthand.
Examples
Incorrect — unitless zero
<style>
.fade {
transition-delay: 0;
transition-duration: 0.3s;
transition-property: opacity;
}
</style>
<div class="fade">Hello</div>
The validator reports: CSS: “transition-delay”: “0” is not a “transition-delay” value.
Correct — with time unit
<style>
.fade {
transition-delay: 0s;
transition-duration: 0.3s;
transition-property: opacity;
}
</style>
<div class="fade">Hello</div>
Incorrect — unitless zero in the transition shorthand
<style>
.btn {
transition: background-color 0.2s ease 0;
}
</style>
<button class="btn">Click me</button>
The fourth value in the transition shorthand is the delay, and 0 without a unit is invalid.
Correct — shorthand with time unit
<style>
.btn {
transition: background-color 0.2s ease 0s;
}
</style>
<button class="btn">Click me</button>
Multiple transitions
When specifying delays for multiple properties, ensure every <time> value has a unit:
<style>
.card {
transition-property: opacity, transform;
transition-duration: 0.3s, 0.5s;
transition-delay: 0s, 0.1s;
}
</style>
<div class="card">Content</div>
The same rule applies to transition-duration and the animation-delay and animation-duration properties — always include s or ms, even for zero values.
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 W3C validator reports this error when it encounters padding-top: px; — a unit with no numeric component. In CSS, length values are composed of two parts: a number and a unit identifier (e.g., px, em, rem, %, vh). The unit alone is meaningless without a number to quantify it. This typically happens due to a typo, a preprocessor variable that resolved to an empty value, or accidentally deleting the number during editing.
This matters for several reasons. Browsers will discard the invalid declaration entirely, meaning padding-top will fall back to its default or inherited value — which may not be what you intended. This can cause unpredictable layout differences across browsers. Additionally, invalid CSS can interfere with parsing of subsequent declarations in the same rule block, potentially causing other styles to be ignored as well.
To fix this issue:
- 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: padding-top: 0; is valid and preferred over padding-top: 0px;.
- Check preprocessor variables (Sass, Less, etc.) to make sure they resolve to complete values, not just units.
- Remove the declaration entirely if padding-top doesn’t need to be set.
Examples
Incorrect: unit without a number
<div style="padding-top: px;">Content</div>
The value px is not a valid padding-top value because it lacks a numeric component.
Correct: number with a unit
<div style="padding-top: 10px;">Content</div>
Correct: zero padding (no unit needed)
<div style="padding-top: 0;">Content</div>
Incorrect in an external stylesheet
.header {
padding-top: px;
}
Correct in an external stylesheet
.header {
padding-top: 16px;
}
Common preprocessor pitfall
If you use a CSS preprocessor like Sass, watch out for variables that might be empty or undefined:
/* If $spacing somehow resolves to empty, this produces "padding-top: px;" */
.card {
padding-top: $spacing + px;
}
/* Safer approach — define the variable with the full value */
.card {
padding-top: $spacing; /* where $spacing: 16px; */
}
Any valid CSS length value will work for padding-top, including px, em, rem, %, vw, vh, ch, and others — as long as a number precedes the unit. The only length value that doesn’t require a unit is 0.
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 font-stretch property selects a normal, condensed, or expanded face from a font family. Its valid keyword values are ultra-condensed, extra-condensed, condensed, semi-condensed, normal, semi-expanded, expanded, extra-expanded, and ultra-expanded. It also accepts percentage values (e.g., 50% to 200%). The value bold doesn’t fit into any of these categories because it describes font weight (thickness of strokes), not font width (how narrow or wide the characters are).
This error usually happens due to one of two mistakes:
- Confusing font-stretch with font-weight: You intended to make text bold but accidentally used the wrong property.
- Typo or copy-paste error in the font shorthand: When writing shorthand font declarations, the various sub-properties can easily get mixed up.
The W3C validator flags this because browsers will ignore invalid CSS values, meaning your intended styling won’t be applied. Fixing it ensures your styles work as expected across all browsers and pass validation.
How to Fix It
- If you want bold text, use font-weight: bold (or numeric values like 700).
- If you want wider or narrower characters, use font-stretch with a valid value like condensed or expanded.
- If you need both, apply each property separately or use the font shorthand correctly.
Examples
Incorrect: Using bold with font-stretch
This triggers the validation error because bold is not a valid font-stretch value:
<p style="font-stretch: bold;">This text won't render as expected.</p>
Fixed: Using font-weight for boldness
If the intent was to make the text bold, switch to font-weight:
<p style="font-weight: bold;">This text is bold.</p>
Fixed: Using font-stretch correctly for width
If the intent was to adjust the character width, use a valid font-stretch value:
<p style="font-stretch: expanded;">This text uses an expanded font face.</p>
Using both properties together
You can combine font-weight and font-stretch when you need both bold text and a different font width:
<style>
.styled-text {
font-weight: bold;
font-stretch: condensed;
font-family: Arial, sans-serif;
}
</style>
<p class="styled-text">This text is bold and condensed.</p>
Valid font-stretch values reference
Here’s a quick overview of all valid keyword values for font-stretch:
<style>
.condensed { font-stretch: condensed; }
.normal-width { font-stretch: normal; }
.expanded { font-stretch: expanded; }
.custom-width { font-stretch: 75%; }
</style>
<p class="condensed">Condensed text</p>
<p class="normal-width">Normal width text</p>
<p class="expanded">Expanded text</p>
<p class="custom-width">75% width text</p>
Note that font-stretch only works if the selected font family includes condensed or expanded faces. If the font doesn’t have these variations, the property will have no visible effect even with valid values.
The font-style CSS property controls whether text is displayed in a normal, italic, or oblique face from its font-family. It has a limited set of accepted values, and the W3C validator will flag any value that falls outside this set.
This error commonly occurs for a few reasons:
- Confusing font-style with font-size: Since both properties start with font-, it’s easy to accidentally type font-style: 1.2em when you meant font-size: 1.2em. Numeric and length values are not valid for font-style.
- Confusing font-style with font-weight: Writing font-style: bold is invalid because bold is a font-weight value, not a font-style value.
- Typos in keyword values: Misspelling a valid keyword, such as font-style: itallic or font-style: oblque, will trigger this error.
- Using the oblique angle syntax incorrectly: While oblique can accept an optional angle (e.g., oblique 10deg), providing an angle without the oblique keyword or using an invalid unit will cause a validation error.
Using invalid CSS values can lead to unpredictable rendering across browsers. Most browsers will ignore the entire declaration when they encounter an invalid value, meaning your intended styling won’t be applied at all. Keeping your CSS valid ensures consistent behavior and makes debugging easier.
Valid font-style values
The accepted values for font-style are:
- normal — displays the normal face of the font family.
- italic — selects the italic face; falls back to oblique if unavailable.
- oblique — selects the oblique face; optionally accepts an angle value (e.g., oblique 10deg). The angle defaults to 14deg if omitted.
- Global CSS values: inherit, initial, revert, revert-layer, unset.
Examples
Incorrect: size value applied to font-style
This is the most common mistake — using a length value that belongs on font-size:
<p style="font-style: 1.2em;">This text has an invalid font-style.</p>
Correct: use font-size for size values
<p style="font-size: 1.2em;">This text has a valid font size.</p>
Incorrect: using bold with font-style
<p style="font-style: bold;">This text has an invalid font-style.</p>
Correct: use font-weight for boldness
<p style="font-weight: bold;">This text is bold.</p>
Incorrect: misspelled keyword
<p style="font-style: itallic;">This text has a typo in font-style.</p>
Correct: properly spelled keyword
<p style="font-style: italic;">This text is italic.</p>
Correct: using oblique with an angle
<p style="font-style: oblique 12deg;">This text is oblique at 12 degrees.</p>
Quick reference for commonly confused properties
If you’re unsure which property to use, here’s a quick guide:
| You want to change… | Use this property | Example value |
|---|---|---|
| Italic or oblique text | font-style | italic, oblique |
| Text size | font-size | 1.2em, 16px |
| Text boldness | font-weight | bold, 700 |
| Text decoration | text-decoration | underline, line-through |
An empty alt attribute on an img element is a deliberate signal that the image is purely decorative and carries no meaningful content. According to the WHATWG HTML specification, this maps the element to the “presentation” role in the accessibility tree, effectively hiding it from screen readers and other assistive technologies.
When you add a role attribute to an img with alt="", you’re sending contradictory instructions: the empty alt says “this image is decorative, ignore it,” while the role attribute says “this image has a specific semantic purpose.” Browsers and assistive technologies cannot reliably resolve this conflict, which can lead to confusing or inconsistent behavior for users who rely on screen readers.
This rule exists to enforce clarity in how images are exposed to the accessibility tree. If an image is truly decorative, it should have alt="" and no role. If an image serves a functional or semantic purpose — such as acting as a button, link, or illustration — it should have both a descriptive alt value and, if needed, an appropriate role.
How to fix it
You have two options depending on the image’s purpose:
-
The image is decorative: Remove the role attribute entirely. The empty alt attribute already communicates that the image should be ignored by assistive technologies.
-
The image is meaningful: Provide a descriptive alt value that explains the image’s purpose. If a specific role is genuinely needed, keep it alongside the non-empty alt.
Examples
❌ Incorrect: empty alt with a role attribute
<img src="icon.png" alt="" role="img">
<img src="banner.jpg" alt="" role="presentation">
Even role="presentation" is redundant and invalid here — the empty alt already implies presentational semantics.
✅ Correct: decorative image with no role
<img src="icon.png" alt="">
If the image is decorative, simply remove the role attribute. The empty alt is sufficient.
✅ Correct: meaningful image with a descriptive alt and a role
<img src="warning-icon.png" alt="Warning" role="img">
If the image conveys information, give it a descriptive alt value. The role="img" is typically unnecessary here since img elements already have an implicit role of img when alt is non-empty, but it is at least valid.
✅ Correct: meaningful image used in a specific context
<button>
<img src="search-icon.png" alt="Search">
</button>
Here the image has a descriptive alt and doesn’t need an explicit role because its purpose is conveyed through the alt text and its context within the button.
The font-weight property controls the boldness or thickness of text characters. Unlike many other CSS properties, it does not accept length units such as px, em, or %. Instead, it uses a specific set of keywords or unitless numeric values to indicate the desired weight. Supplying an unrecognized value causes the declaration to be ignored by the browser, meaning your intended styling won’t be applied, and the text will fall back to the inherited or default weight.
The accepted values for font-weight are:
- Keywords: normal (equivalent to 400), bold (equivalent to 700), bolder (relative, one step heavier than the parent), lighter (relative, one step lighter than the parent).
- Numeric values: Any number from 1 to 1000. Historically only multiples of 100 (100 through 900) were valid, but the CSS Fonts Level 4 specification expanded this to any value in the 1–1000 range. Note that many validators and older browsers may still only recognize the 100–900 multiples.
This matters for standards compliance and predictable rendering. An invalid font-weight value is silently discarded by browsers, which can lead to confusing visual results — especially when you expect a specific weight from a variable font or a multi-weight font family.
To fix this issue, identify the invalid value in your CSS and replace it with one of the accepted values listed above. If you were using a pixel or other unit value, simply remove the unit and choose an appropriate numeric weight. If you used a misspelled keyword (e.g., bolded or heavy), replace it with the correct keyword.
Examples
Incorrect: using a length unit
p {
font-weight: 20px;
}
The validator reports this because 20px is not a valid font-weight value. The property does not accept length units.
Incorrect: using an invalid keyword
h2 {
font-weight: heavy;
}
The keyword heavy is not recognized by the CSS specification for font-weight.
Correct: using valid numeric values
p {
font-weight: 300;
}
h2 {
font-weight: 700;
}
Correct: using valid keywords
p {
font-weight: lighter;
}
h2 {
font-weight: bold;
}
Full HTML example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Font Weight Example</title>
<style>
.light {
font-weight: 300;
}
.regular {
font-weight: normal;
}
.semi-bold {
font-weight: 600;
}
.bold {
font-weight: bold;
}
</style>
</head>
<body>
<p class="light">This text uses a light font weight (300).</p>
<p class="regular">This text uses a normal font weight (400).</p>
<p class="semi-bold">This text uses a semi-bold font weight (600).</p>
<p class="bold">This text uses a bold font weight (700).</p>
</body>
</html>
Quick reference of common numeric weights
| Value | Typical name |
|---|---|
| 100 | Thin |
| 200 | Extra Light |
| 300 | Light |
| 400 | Normal / Regular |
| 500 | Medium |
| 600 | Semi Bold |
| 700 | Bold |
| 800 | Extra Bold |
| 900 | Black |
Keep in mind that the actual visual effect of a numeric weight depends on whether the loaded font family provides a matching weight. If a font only includes 400 and 700 weights, the browser will map other values to the nearest available weight.
When you write margin-right: px, the browser cannot determine what margin to apply because px alone is not a recognized CSS value — it’s just a unit suffix without a quantity. CSS length values are always a combination of a number and a unit (e.g., 10px, 1.5em, 20%), or a specific keyword like auto, inherit, or 0 (which doesn’t require a unit). The lone px is meaningless on its own and will be ignored by browsers, which means your intended spacing won’t be applied.
This issue typically arises in a few common scenarios:
- A number was accidentally deleted during editing, leaving behind just the unit.
- A CSS preprocessor variable or template expression failed to output a value, resulting in only the unit being rendered.
- A typo or copy-paste error stripped the numeric portion.
Beyond simply not working, invalid CSS can cause unpredictable rendering differences across browsers. It also makes your code harder to maintain, as other developers may not understand the intended value.
To fix this, determine what numeric value you intended and place it directly before the px unit with no space between the number and unit. If no margin is needed, either remove the property entirely or set it to 0.
Examples
Incorrect: unit without a number
<div style="margin-right: px;">Content</div>
The validator reports that px is not a valid margin-right value because no number precedes the unit.
Fixed: complete value with number and unit
<div style="margin-right: 10px;">Content</div>
Fixed: using zero (no unit required)
<div style="margin-right: 0;">Content</div>
When the value is 0, no unit is needed since zero is the same in all units.
Fixed: using a keyword value
<div style="margin-right: auto;">Content</div>
The auto keyword is a valid value for margin-right and is commonly used for centering or pushing elements.
Watch for preprocessor or template issues
If you’re using a CSS preprocessor or a templating language, make sure your variables resolve to complete values:
/* Incorrect — if $spacing is empty, this outputs "margin-right: px;" */
.sidebar {
margin-right: px;
}
/* Correct */
.sidebar {
margin-right: 16px;
}
Other valid units
Any valid CSS length unit works, as long as a number precedes it:
<div style="margin-right: 2em;">Em-based margin</div>
<div style="margin-right: 5%;">Percentage-based margin</div>
<div style="margin-right: 1.5rem;">Rem-based margin</div>
The white-space property is a shorthand that combines the behavior of white-space-collapse and text-wrap-mode. When you use a value that doesn’t match any of the accepted keywords — whether due to a typo, a made-up value, or a value that belongs to a different CSS property — the W3C validator flags it as invalid. This commonly happens when authors confuse values from related properties (like using break-spaces where it isn’t supported in inline styles being validated, or misspelling nowrap as no-wrap).
Using invalid CSS values means browsers will ignore the declaration entirely, falling back to the default behavior (white-space: normal). This can cause unexpected text wrapping or whitespace collapsing that breaks your layout. Keeping your CSS valid ensures consistent rendering across browsers and makes your stylesheets easier to maintain and debug.
The accepted values for white-space are:
- normal — Collapses whitespace sequences, wraps text as needed (default).
- nowrap — Collapses whitespace but suppresses line breaks; text won’t wrap.
- pre — Preserves whitespace and line breaks exactly as written, like the <pre> element.
- pre-wrap — Preserves whitespace and line breaks, but also allows text to wrap when necessary.
- pre-line — Collapses whitespace sequences into a single space, but preserves explicit line breaks and allows wrapping.
- break-spaces — Similar to pre-wrap, but trailing spaces and spaces at the end of lines don’t hang and do affect box sizing.
Additionally, CSS Text Level 4 introduced shorthand combinations using white-space-collapse and text-wrap-mode keywords, such as collapse, preserve, wrap, and preserve nowrap. However, support for these newer shorthand forms varies, and older validators or browsers may not recognize them.
Global CSS values (inherit, initial, revert, revert-layer, unset) are also valid.
Examples
Incorrect: invalid value triggers the error
A common mistake is using no-wrap (with a hyphen) instead of the correct nowrap:
<p style="white-space: no-wrap;">This text should not wrap.</p>
Another common mistake is using a value from a different property entirely:
<p style="white-space: hidden;">This text has an invalid white-space value.</p>
Correct: using valid white-space values
<p style="white-space: nowrap;">This text will not wrap to a new line.</p>
<p style="white-space: pre-wrap;">This text preserves whitespace
and line breaks, but also wraps when needed.</p>
<p style="white-space: pre-line;">This collapses extra spaces
but preserves explicit line breaks.</p>
Correct: using the property in a <style> block
<!DOCTYPE html>
<html lang="en">
<head>
<title>White-space example</title>
<style>
.no-wrap {
white-space: nowrap;
}
.preserve {
white-space: pre-wrap;
}
</style>
</head>
<body>
<p class="no-wrap">This long paragraph will stay on a single line without wrapping.</p>
<p class="preserve">This preserves multiple spaces
and line breaks exactly as written.</p>
</body>
</html>
If you encounter this validation error, double-check your white-space value for typos and confirm it matches one of the recognized keywords listed above.
The align-items property controls how flex or grid items are aligned along the cross axis of their container. While many CSS properties accept auto as a value, align-items is not one of them. The CSS specification defines a specific set of accepted values, and using auto will cause the declaration to be ignored by browsers, potentially breaking your intended layout.
This mistake often stems from confusion with the related property align-self, which does accept auto as its default value. When align-self is set to auto, it defers to the parent container’s align-items value. However, align-items itself has no such delegation mechanism — it is the property that sets the default alignment for all items in the container.
The valid values for align-items include:
- normal — behaves as stretch in flex containers and has context-dependent behavior in other layout modes.
- stretch — items are stretched to fill the container along the cross axis (the default behavior in flexbox).
- center — items are centered along the cross axis.
- flex-start / start — items are aligned to the start of the cross axis.
- flex-end / end — items are aligned to the end of the cross axis.
- baseline / first baseline / last baseline — items are aligned based on their text baselines.
- self-start / self-end — items are aligned based on their own writing mode.
If you intended the default behavior, use stretch (for flexbox) or normal. If you were trying to reset the property, use initial, unset, or revert instead of auto.
Examples
Incorrect: using auto as a value
<div style="display: flex; align-items: auto;">
<p>Item one</p>
<p>Item two</p>
</div>
This triggers the validation error because auto is not a recognized value for align-items.
Fixed: using stretch for default flexbox behavior
<div style="display: flex; align-items: stretch;">
<p>Item one</p>
<p>Item two</p>
</div>
Fixed: using center to center items
<div style="display: flex; align-items: center;">
<p>Item one</p>
<p>Item two</p>
</div>
Fixed: using flex-start to align items to the top
<div style="display: flex; align-items: flex-start;">
<p>Item one</p>
<p>Item two</p>
</div>
Correct use of auto with align-self
If your intention was to let a specific child item defer to its parent’s alignment, use align-self: auto on the child element instead:
<div style="display: flex; align-items: center;">
<p>Centered item</p>
<p style="align-self: auto;">Also centered (defers to parent)</p>
<p style="align-self: flex-end;">Aligned to the end</p>
</div>
Here, align-self: auto is valid on individual items and tells them to inherit the align-items value from the container.
Every CSS property has a defined value syntax that specifies exactly which values it accepts and how many. When the validator encounters a declaration that doesn’t match this syntax, it flags the error. This can happen for several distinct reasons:
- Too many values: A property receives more values than its syntax allows. For example, margin accepts one to four values, so a fifth value is invalid. The color property accepts only a single color value, so writing two colors is an error.
- Unrecognized values: A keyword is misspelled (e.g., blocky instead of block) or simply doesn’t exist for that property (e.g., color: bold).
- Newer or non-standard values: A value that belongs to a draft specification, a vendor-prefixed feature, or a browser-specific extension may not be recognized by the validator.
- Missing separators or syntax errors: A missing comma in a multi-value function like rgb() or a missing slash in shorthand like font can cause the parser to misinterpret the values.
This matters because browsers handle invalid CSS unpredictably — they typically discard the entire declaration, which means your intended styles silently disappear. Fixing these errors ensures your styles are applied consistently across browsers and makes your stylesheets easier to maintain and debug.
How to Fix
- Identify the property and value reported in the error message.
- Check spelling of every keyword. Common mistakes include inheret (should be inherit), trasparent (should be transparent), and centre (should be center).
- Count the values and compare against the property’s specification. Consult MDN Web Docs for the accepted value syntax.
- Verify function syntax — ensure commas, slashes, and parentheses are correct in functions like rgb(), calc(), and clamp().
- Check for unsupported modern syntax — if you’re using newer CSS features, the validator may not recognize them yet. In that case, verify the syntax is correct per the spec and consider the warning informational.
Examples
Too many values for a property
The color property only accepts a single color value, and margin accepts at most four values:
<!-- ❌ Invalid: too many values -->
<p style="color: red blue;">Hello</p>
<p style="margin: 10px 20px 5px 0px 15px;">Hello</p>
<!-- ✅ Valid: correct number of values -->
<p style="color: red;">Hello</p>
<p style="margin: 10px 20px 5px 0px;">Hello</p>
Unrecognized keyword value
A typo or non-existent keyword triggers the error:
<!-- ❌ Invalid: "blocky" is not a valid display value -->
<div style="display: blocky;">Content</div>
<!-- ✅ Valid: correct keyword -->
<div style="display: block;">Content</div>
Misspelled value in a <style> block
<!-- ❌ Invalid -->
<style>
.box {
background-color: trasparent;
text-align: centre;
}
</style>
<!-- ✅ Valid -->
<style>
.box {
background-color: transparent;
text-align: center;
}
</style>
Incorrect function syntax
Missing commas or extra arguments inside CSS functions can also trigger this error:
<!-- ❌ Invalid: missing commas in rgb() -->
<p style="color: rgb(255 0 0 0.5);">Hello</p>
<!-- ✅ Valid: use the correct modern syntax with a slash for alpha -->
<p style="color: rgb(255 0 0 / 0.5);">Hello</p>
Shorthand property confusion
Shorthand properties like font and background have specific value order requirements. Providing values in the wrong order or mixing incompatible values causes errors:
<!-- ❌ Invalid: incorrect font shorthand -->
<style>
p {
font: bold Arial 16px;
}
</style>
<!-- ✅ Valid: size must come before family, weight before size -->
<style>
p {
font: bold 16px Arial;
}
</style>
When in doubt, break shorthand properties into their individual longhand properties (font-weight, font-size, font-family) to isolate which value the validator is rejecting.
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.
The margin-top property accepts several types of values: lengths (like 10px, 1.5em, 2rem), percentages (like 5%), the keyword auto, or the value 0. When you write margin-top: px, the browser encounters a bare unit with no associated number, which is meaningless — it doesn’t know how many pixels you want. Browsers will ignore the invalid declaration entirely, which means margin-top will fall back to its default or inherited value. This can lead to unexpected layout results that may differ across browsers.
This error commonly happens due to a typo, an accidental deletion of the numeric portion, or a templating/build tool that failed to interpolate a variable (e.g., margin-top: ${value}px where value was empty). It can also occur when editing CSS quickly and removing the number while intending to change it.
Beyond just margin-top, this same principle applies to all CSS properties that accept length values — margin, padding, width, height, font-size, border-width, and many others. A bare unit without a number is never valid.
Note: The value 0 is the only numeric length that does not require a unit. Writing margin-top: 0 is perfectly valid and equivalent to margin-top: 0px.
How to fix it
- Add the missing number before the unit. Determine the spacing you need and prepend it to the unit (e.g., 10px, 1.5em).
- Use a valid keyword if you don’t need a specific numeric value — auto or inherit, for example.
- Check template variables if you use a preprocessor or templating system. Make sure the variable that provides the number is defined and not empty.
Examples
Incorrect: bare unit with no number
<div style="margin-top: px;">Content</div>
The validator reports that "px" is not a valid margin-top value because it lacks a numeric component.
Correct: number followed by a unit
<div style="margin-top: 10px;">Content</div>
Correct: using zero without a unit
<div style="margin-top: 0;">Content</div>
Correct: using a keyword value
<div style="margin-top: auto;">Content</div>
Incorrect in a stylesheet
<style>
.box {
margin-top: px;
}
</style>
<div class="box">Content</div>
Correct in a stylesheet
<style>
.box {
margin-top: 16px;
}
</style>
<div class="box">Content</div>
Incorrect with CSS preprocessor output
If you use a preprocessor like Sass or a JavaScript framework, an undefined or empty variable can produce this error:
<!-- If the variable was empty, the rendered output becomes: -->
<div style="margin-top: px;">Content</div>
Ensure the variable has a valid numeric value so the rendered CSS is complete:
<div style="margin-top: 20px;">Content</div>
HTML forms have built-in constraint validation that is enabled by default. When a user submits a form, the browser automatically checks inputs against their constraints (such as required, type="email", pattern, min, max, etc.) and prevents submission if any validation fails. There is no need to add a validate attribute to opt into this behavior because it is the default.
The HTML specification defines novalidate as a valid boolean attribute on the <form> element to disable this default validation, but it does not define a corresponding validate attribute. Using validate will trigger a W3C validation error because the browser doesn’t recognize it and will simply ignore it.
This matters for several reasons:
- Standards compliance: Invalid attributes make your HTML non-conforming, which can cause issues with automated testing and quality tools.
- Developer confusion: A validate attribute suggests it’s doing something functional, but it has no effect. Future maintainers may incorrectly believe it’s enabling validation and be reluctant to remove it.
- Accessibility and tooling: Screen readers and other assistive technologies rely on well-formed HTML. Unrecognized attributes can lead to unpredictable behavior in some user agents.
To fix this issue, determine your intent:
- If you want form validation enabled — simply remove the validate attribute. Validation is on by default.
- If you want form validation disabled — replace validate with novalidate.
Examples
Incorrect: using the invalid validate attribute
<form validate action="/submit">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<button type="submit">Submit</button>
</form>
This triggers the error: Attribute “validate” not allowed on element “form” at this point.
Correct: relying on default validation (attribute removed)
Since constraint validation is enabled by default, simply remove the invalid attribute:
<form action="/submit">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<button type="submit">Submit</button>
</form>
The browser will automatically validate the email input — checking both the required constraint and that the value matches a valid email format — before allowing submission.
Correct: using novalidate to disable validation
If your intention is to disable built-in validation (for example, because you handle validation with JavaScript), use the novalidate attribute instead:
<form novalidate action="/submit">
<label for="city">City:</label>
<input type="text" id="city" name="city" required>
<button type="submit">Submit</button>
</form>
In this example, even though the input has the required attribute, the browser will not prevent form submission when the field is empty, because novalidate tells the browser to skip constraint validation on submission.
Using formnovalidate on a specific button
If you want validation enabled for normal submission but want to bypass it for a specific button (such as a “Save Draft” button), use the formnovalidate attribute on that button instead of disabling validation for the entire form:
<form action="/submit">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<button type="submit">Submit</button>
<button type="submit" formnovalidate formaction="/save-draft">Save Draft</button>
</form>
The “Submit” button will enforce validation, while the “Save Draft” button will skip it. This approach gives you fine-grained control without needing an invalid attribute.
The W3C validator raises this error when it encounters a bare unit like px used as the value for margin-bottom without an accompanying number. In CSS, length values are always composed of two parts: a <number> and a <unit>. The token px alone is not a valid <length> value — it’s just a unit identifier with no magnitude. This typically happens due to a typo, an accidental deletion of the numeric portion, or a templating/build tool that outputs an empty variable before the unit.
This matters for several reasons. First, browsers will discard the invalid declaration entirely, meaning margin-bottom will fall back to its default or inherited value — likely not what you intended. This can cause unexpected layout shifts across different pages or components. Second, invalid CSS can make debugging harder, since the silent failure may not be obvious until the layout breaks in a specific context. Third, clean, valid CSS is easier to maintain and signals code quality to collaborators.
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 margin: margin-bottom: 0 is valid and preferred over margin-bottom: 0px.
- Use a keyword value if appropriate: margin-bottom also accepts auto, inherit, initial, revert, and unset.
- Check template variables: if you’re using a preprocessor like Sass or a JavaScript framework that injects values, make sure the variable isn’t empty or undefined before concatenation with the unit.
Examples
Incorrect: bare unit with no number
<div style="margin-bottom: px;">Content</div>
The value px is not a valid margin-bottom value. The browser will ignore this declaration.
Correct: numeric value with unit
<div style="margin-bottom: 10px;">Content</div>
Correct: zero margin (no unit needed)
<div style="margin-bottom: 0;">Content</div>
Correct: using a keyword value
<div style="margin-bottom: auto;">Content</div>
Incorrect in a stylesheet
<html lang="en">
<head>
<title>Example</title>
<style>
.card {
margin-bottom: px;
}
</style>
</head>
<body>
<div class="card">Content</div>
</body>
</html>
Fixed stylesheet
<html lang="en">
<head>
<title>Example</title>
<style>
.card {
margin-bottom: 16px;
}
</style>
</head>
<body>
<div class="card">Content</div>
</body>
</html>
Watch out for preprocessor issues
If you use a CSS preprocessor like Sass or Less, a common source of this error is an empty or undefined variable:
/* If $spacing resolves to empty, this produces "margin-bottom: px;" */
.card {
margin-bottom: $spacing + px;
}
Instead, ensure the variable includes the unit or has a valid fallback:
$spacing: 16px;
.card {
margin-bottom: $spacing;
}
The same principle applies to any CSS property that expects a <length> value — always pair a number with its unit, or use 0 when no spacing is needed.
The background-color property accepts a specific set of color value types defined in the CSS Color specification. When you provide something that doesn’t match any of these types — like a plain number, a misspelled keyword, or a malformed hex code — the validator flags it as an invalid value.
Common mistakes that trigger this error include:
- Bare numbers like 0 or 255 — numbers alone aren’t colors, even if you intended black or white.
- Misspelled color keywords like grren instead of green, or trasparent instead of transparent.
- Malformed hex codes like #GGG, #12345, or missing the # prefix entirely.
- Incorrect function syntax like rgb(255 0 0 0.5) when mixing legacy comma syntax with modern space syntax improperly, or using rgba with only three arguments.
- Invalid units or strings like background-color: 10px or background-color: "red" (color values should not be quoted).
While browsers are generally forgiving and will simply ignore an invalid background-color declaration, this means your intended styling silently fails. The element falls back to its inherited or default background, which can cause visual bugs, poor contrast, or accessibility issues that are hard to track down. Validating your CSS catches these problems early.
Valid color formats
The background-color property accepts these value types:
- Named keywords: red, blue, transparent, currentcolor, etc.
- Hex notation: #rgb, #rrggbb, #rgba, #rrggbbaa
- RGB/RGBA: rgb(255, 0, 0) or rgb(255 0 0 / 0.5)
- HSL/HSLA: hsl(120, 100%, 50%) or hsl(120 100% 50% / 0.5)
- The keyword inherit, initial, unset, or revert
Examples
Invalid: bare number as a color
A plain number like 0 is not a valid color value, even though black could be represented as all zeros in RGB.
<style>
.banner {
background-color: 0;
}
</style>
Invalid: misspelled keyword
<style>
.banner {
background-color: trasparent;
}
</style>
Invalid: quoted string
Color values must not be wrapped in quotes.
<style>
.banner {
background-color: "red";
}
</style>
Invalid: malformed hex code
Hex codes must be 3, 4, 6, or 8 characters after the #.
<style>
.banner {
background-color: #12345;
}
</style>
Fixed: using a named color keyword
<style>
.banner {
background-color: black;
}
</style>
Fixed: using a hex color
<style>
.banner {
background-color: #000000;
}
</style>
Fixed: using rgb() notation
<style>
.banner {
background-color: rgb(0, 0, 0);
}
</style>
Fixed: using rgba() for semi-transparency
<style>
.banner {
background-color: rgba(0, 0, 0, 0.5);
}
</style>
Fixed: using hsl() notation
<style>
.banner {
background-color: hsl(210, 50%, 40%);
}
</style>
Fixed: using transparent
<style>
.banner {
background-color: transparent;
}
</style>
The type attribute is specific to the <input> element, where it determines the kind of input control rendered — such as text, checkbox, email, or number. The <textarea> element serves a single, distinct purpose: providing a multi-line plain-text editing area. Because it doesn’t have multiple modes of operation, the HTML specification does not define a type attribute for it.
This error commonly occurs when developers confuse <textarea> with <input>, or when refactoring a single-line <input type="text"> into a multi-line <textarea> without removing the now-invalid type attribute. It can also appear when using templating systems or frameworks that apply attributes generically across different form elements.
While browsers will typically ignore the unrecognized type attribute on a <textarea>, keeping it in your markup causes W3C validation errors and can lead to confusion for other developers reading the code. Invalid attributes may also interfere with CSS attribute selectors (e.g., textarea[type="text"] is a selector targeting invalid markup), accessibility tools, or automated testing systems that rely on well-formed HTML.
To fix this issue, remove the type attribute from the <textarea> element. If you need to differentiate between multiple textareas, use id, name, or class attributes instead. If you actually need a single-line text input, use <input type="text"> rather than <textarea>.
Examples
Incorrect: type attribute on <textarea>
<label for="comment">Your comment:</label>
<textarea type="text" id="comment" name="comment" rows="4" cols="50"></textarea>
The type="text" attribute is not valid on <textarea> and will trigger a validation error.
Correct: <textarea> without type
<label for="comment">Your comment:</label>
<textarea id="comment" name="comment" rows="4" cols="50"></textarea>
Simply removing the type attribute resolves the issue. The <textarea> element inherently provides a multi-line text input, so no type is needed.
Correct: Using <input> when a single-line field is intended
If you intended a single-line text field, use <input> instead:
<label for="username">Username:</label>
<input type="text" id="username" name="username">
The type attribute is valid and expected on <input> elements, where it controls the type of input control rendered.
The text-overflow CSS property controls how overflowed content that is not displayed is signaled to users. It applies when an element’s overflow is hidden (e.g., overflow: hidden) and the content exceeds the element’s box. The property accepts specific values, and using anything outside the allowed set — such as a misspelled keyword, an unquoted string, or a made-up value — will trigger this validation error.
Accepted values
The text-overflow property accepts the following values:
- clip — Truncates the text at the edge of the content area. Characters may be clipped mid-glyph. This is the default.
- ellipsis — Displays an ellipsis character (…) to indicate clipped text.
- A custom <string> — A quoted string to display at the clipping point (e.g., " [..]"). Note that browser support for custom strings is limited.
- Global CSS values — inherit, initial, revert, revert-layer, and unset.
The property can take one or two values. If one value is given, it specifies the overflow behavior for the end of the line (the right end for left-to-right text, the left end for right-to-left text). If two values are given, the first controls the left end of the line and the second controls the right end. Two-value syntax has limited browser support.
Common mistakes that trigger this error include:
- Misspelling ellipsis (e.g., elipsis, ellipses).
- Using a value from a different property (e.g., hidden, scroll, auto).
- Using an unquoted custom string instead of a properly quoted one.
- Using a numeric or length value (e.g., 10px), which is not valid for this property.
Why this matters
Invalid CSS values are ignored by browsers, which means the property will fall back to its default (clip) instead of behaving as you intended. This can lead to text being abruptly cut off without any visual indicator, harming readability and user experience. Fixing validation errors also ensures your stylesheets are clean, predictable, and maintainable.
Examples
Incorrect — misspelled keyword
/* "elipsis" is not a valid text-overflow value */
.truncated {
overflow: hidden;
white-space: nowrap;
text-overflow: elipsis;
}
Incorrect — value from another property
/* "hidden" is an overflow value, not a text-overflow value */
.truncated {
overflow: hidden;
white-space: nowrap;
text-overflow: hidden;
}
Incorrect — unquoted custom string
/* Custom strings must be quoted */
.truncated {
overflow: hidden;
white-space: nowrap;
text-overflow: [more];
}
Correct — using ellipsis
.truncated {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Correct — using clip (the default)
.truncated {
overflow: hidden;
white-space: nowrap;
text-overflow: clip;
}
Correct — using a quoted custom string
.truncated {
overflow: hidden;
white-space: nowrap;
text-overflow: " [..]";
}
Correct — two-value syntax
/* Left end uses ellipsis, right end uses a custom string */
.truncated {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis " [..]";
}
Note that text-overflow on its own does not force overflow to occur. To make text actually truncate, you typically need overflow: hidden (or another non-visible overflow value) and white-space: nowrap on the element. The text-overflow property only controls how the clipped content is signaled visually.
The max-width property sets the maximum width an element can grow to, preventing the computed value of width from exceeding the specified limit. While many CSS sizing properties accept auto as a value (for example, width: auto and margin: auto are perfectly valid), the max-width property does not. This is a common mistake because developers often assume auto is universally accepted across similar properties.
When a browser encounters max-width: auto, it will typically ignore the invalid declaration and fall back to the default value of none. While the page may still render as expected in some browsers, relying on this behavior is unreliable and non-standard. Writing valid CSS ensures consistent rendering across all browsers and makes your stylesheets easier to maintain and debug.
If your intent is to remove a maximum width constraint (effectively making max-width have no effect), use none — this is the default value. If you want the element to size itself based on its content, use max-content, min-content, or fit-content. If you need to reset the property to its initial value, use initial (which resolves to none).
Valid values for max-width
The max-width property accepts the following types of values:
- none — No limit on the element’s width (the default).
- Length values — Such as 500px, 3.5em, 20rem, 80ch.
- Percentage values — Such as 75%, relative to the containing block’s width.
- Keyword values — max-content, min-content, fit-content, or fit-content(<length>).
- Global values — inherit, initial, revert, unset.
Examples
❌ Incorrect: using auto with max-width
<div style="max-width: auto;">
This container has an invalid max-width value.
</div>
This triggers the validation error because auto is not a valid max-width value.
✅ Fixed: using none to remove the constraint
If you want no maximum width limit (the most likely intent when writing auto), use none:
<div style="max-width: none;">
This container has no maximum width constraint.
</div>
✅ Fixed: using a specific length or percentage
If you want to cap the element’s width at a specific size:
<div style="max-width: 600px;">
This container will not grow beyond 600 pixels.
</div>
<div style="max-width: 80%;">
This container will not exceed 80% of its parent's width.
</div>
✅ Fixed: using intrinsic sizing keywords
If you want the element’s maximum width to be based on its content:
<div style="max-width: max-content;">
This container's max width is determined by its content.
</div>
The text-transform CSS property controls the capitalization of text within an element. It’s commonly used to enforce consistent text casing — for example, making headings appear in all uppercase or ensuring navigation links are lowercase — without changing the actual content in the HTML. When the validator encounters a value it doesn’t recognize for this property, it flags it as invalid.
This error can occur for several reasons:
- Typos — writing upppercase instead of uppercase, or Capitalize instead of capitalize (CSS values are case-sensitive in validation contexts).
- Incorrect values — using values from other properties, like bold, italic, or center, which don’t apply to text-transform.
- Non-standard values — using browser-specific or experimental values that aren’t part of the CSS specification.
- Wrong property — confusing text-transform with text-decoration, text-align, or font-variant, and using their values here instead.
Fixing this matters because invalid CSS can lead to unpredictable rendering across browsers. While most browsers will simply ignore an invalid declaration, your intended styling won’t be applied, potentially breaking your design. Keeping your CSS valid also improves maintainability and ensures forward compatibility.
Valid values for text-transform
| Value | Effect |
|---|---|
| none | No capitalization change (default) |
| capitalize | First letter of each word is uppercased |
| uppercase | All characters are converted to uppercase |
| lowercase | All characters are converted to lowercase |
| full-width | Forces characters into a full-width form (useful for CJK typography) |
| full-size-kana | Converts small kana characters to full-size equivalents |
Examples
Incorrect — invalid value
In this example, bold is not a valid text-transform value. It likely belongs on the font-weight property instead.
<p style="text-transform: bold;">Welcome to our site</p>
Similarly, a simple typo will trigger this error:
<p style="text-transform: uppercse;">Welcome to our site</p>
Correct — using valid values
<p style="text-transform: uppercase;">Welcome to our site</p>
<p style="text-transform: capitalize;">Welcome to our site</p>
Correct — separating concerns with the right properties
If you intended to make text bold and uppercase, use the appropriate property for each effect:
<p style="font-weight: bold; text-transform: uppercase;">Welcome to our site</p>
Correct — using text-transform in a stylesheet
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Text Transform Example</title>
<style>
.heading {
text-transform: uppercase;
}
.name {
text-transform: capitalize;
}
.code-snippet {
text-transform: none;
}
</style>
</head>
<body>
<h1 class="heading">site navigation</h1>
<p class="name">john doe</p>
<code class="code-snippet">myVariable</code>
</body>
</html>
If you’re unsure which value you need, uppercase and capitalize are the most commonly used. Use none when you need to override a text-transform rule inherited from a parent element.
Ready to validate your sites?
Start your free trial today.