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.
CSS custom properties (variables) used in the flex shorthand are not recognized by the W3C CSS validator, even though they work correctly in all modern browsers. This is a known limitation of the validator, not a bug in your code.
The W3C CSS validator performs static analysis and cannot resolve var() expressions at validation time. It doesn't know that --flex-grow will eventually hold a valid value like 1 or 0, so it flags the declaration as invalid. This affects many CSS properties when custom properties are used, not just flex.
You have a few options. You can safely ignore this specific warning since the code is valid per the CSS specification. Alternatively, you can restructure your CSS to apply the variable to a more specific property like flex-grow instead of the shorthand, which sometimes avoids the validator complaint.
HTML Examples
Before: Using var() in the flex shorthand
<style>
:root{
--flex-grow:1;
}
.item{
flex:var(--flex-grow);
}
</style>
<divstyle="display: flex;">
<divclass="item">Content</div>
</div>
After: Using var() on individual flex properties
<style>
:root{
--flex-grow:1;
}
.item{
flex-grow:var(--flex-grow);
flex-shrink:1;
flex-basis:0%;
}
</style>
<divstyle="display: flex;">
<divclass="item">Content</div>
</div>
Both versions produce the same result in browsers. The second approach uses individual flex-grow, flex-shrink, and flex-basis properties, which may reduce validator noise. That said, this is a false positive from the validator — your original code is perfectly valid CSS.
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 asstretchin 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
<divstyle="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
<divstyle="display: flex;align-items: stretch;">
<p>Item one</p>
<p>Item two</p>
</div>
Fixed: using center to center items
<divstyle="display: flex;align-items: center;">
<p>Item one</p>
<p>Item two</p>
</div>
Fixed: using flex-start to align items to the top
<divstyle="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:
<divstyle="display: flex;align-items: center;">
<p>Centered item</p>
<pstyle="align-self: auto;">Also centered (defers to parent)</p>
<pstyle="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,
marginaccepts one to four values, so a fifth value is invalid. Thecolorproperty accepts only a single color value, so writing two colors is an error. - Unrecognized values: A keyword is misspelled (e.g.,
blockyinstead ofblock) 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 likefontcan 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 beinherit),trasparent(should betransparent), andcentre(should becenter). - 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(), andclamp(). - 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 -->
<pstyle="color: red blue;">Hello</p>
<pstyle="margin:10px20px5px0px15px;">Hello</p>
<!-- ✅ Valid: correct number of values -->
<pstyle="color: red;">Hello</p>
<pstyle="margin:10px20px5px0px;">Hello</p>
Unrecognized keyword value
A typo or non-existent keyword triggers the error:
<!-- ❌ Invalid: "blocky" is not a valid display value -->
<divstyle="display: blocky;">Content</div>
<!-- ✅ Valid: correct keyword -->
<divstyle="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() -->
<pstyle="color:rgb(255000.5);">Hello</p>
<!-- ✅ Valid: use the correct modern syntax with a slash for alpha -->
<pstyle="color:rgb(25500/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-spacingis 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()orisFinite()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
0ornormal.Fix the root cause. Determine why the calculation produces
NaN— common causes include missing data attributes,undefinedvariables, or parsing non-numeric strings.
Examples
❌ Invalid: NaN concatenated with a unit
This is what the rendered HTML looks like when the bug occurs:
<pstyle="letter-spacing:NaNrem">Spaced text</p>
The JavaScript that likely produced it:
// Bug: getAttribute returns null if data-spacing is missing
letspacing=parseFloat(element.getAttribute('data-spacing'));
element.style.letterSpacing=spacing+'rem';// "NaNrem" if attribute is missing
✅ Fixed: Validate the value before applying it
letraw=parseFloat(element.getAttribute('data-spacing'));
letspacing=Number.isFinite(raw)?raw:0.1;// fallback to 0.1
element.style.letterSpacing=spacing+'rem';
This produces valid inline CSS:
<pstyle="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>
<pclass="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 -->
<pstyle="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 —
autoorinherit, 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
<divstyle="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
<divstyle="margin-top:10px;">Content</div>
Correct: using zero without a unit
<divstyle="margin-top:0;">Content</div>
Correct: using a keyword value
<divstyle="margin-top: auto;">Content</div>
Incorrect in a stylesheet
<style>
.box{
margin-top: px;
}
</style>
<divclass="box">Content</div>
Correct in a stylesheet
<style>
.box{
margin-top:16px;
}
</style>
<divclass="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: -->
<divstyle="margin-top: px;">Content</div>
Ensure the variable has a valid numeric value so the rendered CSS is complete:
<divstyle="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
validateattribute 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
validateattribute. Validation is on by default. - If you want form validation disabled — replace
validatewithnovalidate.
Examples
Incorrect: using the invalid validate attribute
<formvalidateaction="/submit">
<labelfor="email">Email:</label>
<inputtype="email"id="email"name="email"required>
<buttontype="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:
<formaction="/submit">
<labelfor="email">Email:</label>
<inputtype="email"id="email"name="email"required>
<buttontype="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:
<formnovalidateaction="/submit">
<labelfor="city">City:</label>
<inputtype="text"id="city"name="city"required>
<buttontype="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:
<formaction="/submit">
<labelfor="name">Name:</label>
<inputtype="text"id="name"name="name"required>
<buttontype="submit">Submit</button>
<buttontype="submit"formnovalidateformaction="/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
pxto something like10px,1.5em, or20%. - Use
0without a unit if you want zero margin:margin-bottom: 0is valid and preferred overmargin-bottom: 0px. - Use a keyword value if appropriate:
margin-bottomalso acceptsauto,inherit,initial,revert, andunset. - 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
<divstyle="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
<divstyle="margin-bottom:10px;">Content</div>
Correct: zero margin (no unit needed)
<divstyle="margin-bottom:0;">Content</div>
Correct: using a keyword value
<divstyle="margin-bottom: auto;">Content</div>
Incorrect in a stylesheet
<htmllang="en">
<head>
<title>Example</title>
<style>
.card{
margin-bottom: px;
}
</style>
</head>
<body>
<divclass="card">Content</div>
</body>
</html>
Fixed stylesheet
<htmllang="en">
<head>
<title>Example</title>
<style>
.card{
margin-bottom:16px;
}
</style>
</head>
<body>
<divclass="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
0or255— numbers alone aren't colors, even if you intended black or white. - Misspelled color keywords like
grreninstead ofgreen, ortrasparentinstead oftransparent. - 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 usingrgbawith only three arguments. - Invalid units or strings like
background-color: 10pxorbackground-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)orrgb(255 0 0 / 0.5) - HSL/HSLA:
hsl(120, 100%, 50%)orhsl(120 100% 50% / 0.5) - The keyword
inherit,initial,unset, orrevert
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>
<labelfor="comment">Your comment:</label>
<textareatype="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
<labelfor="comment">Your comment:</label>
<textareaid="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:
<labelfor="username">Username:</label>
<inputtype="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, andunset.
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, orfit-content(<length>). - Global values —
inherit,initial,revert,unset.
Examples
❌ Incorrect: using auto with max-width
<divstyle="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:
<divstyle="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:
<divstyle="max-width:600px;">
This container will not grow beyond 600 pixels.
</div>
<divstyle="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:
<divstyle="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
upppercaseinstead ofuppercase, orCapitalizeinstead ofcapitalize(CSS values are case-sensitive in validation contexts). - Incorrect values — using values from other properties, like
bold,italic, orcenter, which don't apply totext-transform. - Non-standard values — using browser-specific or experimental values that aren't part of the CSS specification.
- Wrong property — confusing
text-transformwithtext-decoration,text-align, orfont-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.
<pstyle="text-transform: bold;">Welcome to our site</p>
Similarly, a simple typo will trigger this error:
<pstyle="text-transform: uppercse;">Welcome to our site</p>
Correct — using valid values
<pstyle="text-transform: uppercase;">Welcome to our site</p>
<pstyle="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:
<pstyle="font-weight: bold;text-transform: uppercase;">Welcome to our site</p>
Correct — using text-transform in a stylesheet
<!DOCTYPE html>
<htmllang="en">
<head>
<metacharset="utf-8">
<title>Text Transform Example</title>
<style>
.heading{
text-transform: uppercase;
}
.name{
text-transform: capitalize;
}
.code-snippet{
text-transform: none;
}
</style>
</head>
<body>
<h1class="heading">site navigation</h1>
<pclass="name">john doe</p>
<codeclass="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.
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 theframeborder="0"attribute (thoughframeborderis also obsolete — CSS is preferred). - Blend the background: Set
background: transparent;and add theallowtransparencyattribute 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
<iframesrc="widget.html"seamless></iframe>
✅ Fixed: Attribute removed, CSS used for styling
<iframesrc="widget.html"style="border: none;"></iframe>
✅ Fixed: Using a CSS class for cleaner markup
<style>
.seamless-iframe{
border: none;
width:100%;
background: transparent;
}
</style>
<iframesrc="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:
<divid="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
pxto something like10px,1.5em, or20%. - Use
0without a unit if you want zero padding — writingpadding-bottom: 0is valid and preferred over0px. - 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
<divstyle="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
<divstyle="padding-bottom:10px;">Content</div>
Correct: zero padding (no unit needed)
<divstyle="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.datasetAPI is specifically designed to work withdata-*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
<spancurrency="USD">49.99</span>
This triggers the validation error because currency is not a recognized attribute for <span>.
✅ Fixed: Using a data-currency attribute
<spandata-currency="USD">49.99</span>
The data-currency attribute is valid HTML. In JavaScript, you can access its value like this:
constspan=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:
<spanclass="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:
<spanitemscopeitemtype="https://schema.org/MonetaryAmount">
<metaitemprop="currency"content="USD">
<spanitemprop="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
langattribute 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
langfor 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>
<htmlisolang="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>
<htmllang="pt">
<head>
<title>Minha Página</title>
</head>
<body>
<p>Olá, mundo!</p>
</body>
</html>
✅ Correct: Using a regional language subtag
<!DOCTYPE html>
<htmllang="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— Englishes— Spanishfr— Frenchde— Germanpt— Portuguesezh— Chineseja— Japanesear— Arabicko— Koreanru— 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
normlorNormalinstead ofnormal(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., confusing1.5with1.5 emwith a space). - Malformed numbers — typos like
1..5or24ppx. - Using unsupported keywords — values like
auto,thin, orlargeare not valid forline-height. - Negative values —
line-heightdoes 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 -->
<pstyle="line-height: norml;">Text with an invalid line-height.</p>
<!-- Invalid unit -->
<pstyle="line-height:1.5x;">Text with an unrecognized unit.</p>
<!-- Malformed number -->
<pstyle="line-height:1..5;">Text with a typo in the number.</p>
<!-- Unsupported keyword -->
<pstyle="line-height: auto;">Auto is not valid for line-height.</p>
<!-- Negative value -->
<pstyle="line-height:-1.5;">Negative values are not allowed.</p>
✅ Correct: valid line-height values
<!-- Keyword -->
<pstyle="line-height: normal;">Browser default line height.</p>
<!-- Unitless number (recommended) -->
<pstyle="line-height:1.5;">1.5 times the font size.</p>
<!-- Length with px -->
<pstyle="line-height:24px;">Fixed 24px line height.</p>
<!-- Length with em -->
<pstyle="line-height:1.5em;">1.5em line height.</p>
<!-- Percentage -->
<pstyle="line-height:150%;">150% of the font size.</p>
Full document example
<!DOCTYPE html>
<htmllang="en">
<head>
<title>Valid line-height Example</title>
</head>
<body>
<h1style="line-height:1.2;">A Heading with Tight Spacing</h1>
<pstyle="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, or0.1cm. The value must not be negative. - Keywords — exactly three are defined:
thin,medium, andthick. These map to implementation-defined sizes but are guaranteed to maintain the relationshipthin ≤ 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: 2instead ofborder-width: 2px. The only unitless length allowed in CSS is0. - Misspelled or invented keywords — using
large,small,normal, ornoneinstead ofthin,medium, orthick. - Wrong value type — accidentally using a color name, percentage, or other non-length value.
- Typos in units — writing
5xpinstead of5px.
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>
<divclass="box">Content</div>
Fixed: using a valid keyword
<style>
.box{
border-style: solid;
border-width: thick;
}
</style>
<divclass="box">Content</div>
Invalid: missing unit on a number
<style>
.alert{
border: solid;
border-width:3;/* unitless number is not valid */
}
</style>
<divclass="alert">Warning</div>
Fixed: adding a proper unit
<style>
.alert{
border: solid;
border-width:3px;
}
</style>
<divclass="alert">Warning</div>
Invalid: using a percentage
<style>
.panel{
border-style: solid;
border-width:5%;/* percentages are not valid for border-width */
}
</style>
<divclass="panel">Panel</div>
Fixed: using a length value instead
<style>
.panel{
border-style: solid;
border-width:0.3em;
}
</style>
<divclass="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>
<divclass="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 subscriptsuper— aligns as a superscripttext-top— aligns with the top of the parent's fonttext-bottom— aligns with the bottom of the parent's fontmiddle— aligns the middle of the element with the baseline plus half the x-height of the parenttop— aligns the top of the element with the top of the tallest element on the linebottom— 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 <imgsrc="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 <imgsrc="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 <imgsrc="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>
<tdclass="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>
<tdclass="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 <spanstyle="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
<divstyle="margin-left: px;">Content</div>
The browser cannot interpret px alone and will ignore the declaration entirely.
Correct: number with a unit
<divstyle="margin-left:10px;">Content</div>
Correct: zero margin (no unit needed)
<divstyle="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;" -->
<divstyle="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:
<divstyle="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);.
left is not a valid value for the align-items CSS property.
The align-items property controls how flex or grid items are aligned along the cross axis of their container. Its valid values include stretch, flex-start, flex-end, center, baseline, start, end, self-start, and self-end.
The value left is not recognized because align-items works on the cross axis (typically vertical), not the inline/horizontal axis. If you want to align items to the start, use flex-start or start instead.
If you're actually trying to align content horizontally to the left, you likely want the justify-content property (which controls the main axis) or text-align: left on the container.
How to Fix
Incorrect:
<divstyle="display: flex;align-items: left;">
<p>Hello</p>
</div>
Fixed — aligning items to the start of the cross axis:
<divstyle="display: flex;align-items: flex-start;">
<p>Hello</p>
</div>
Fixed — aligning items horizontally to the left (main axis):
<divstyle="display: flex;justify-content: flex-start;">
<p>Hello</p>
</div>
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-Typeheader — The HTTPContent-Typeheader can override the in-document charset declaration. If your server sendsContent-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-1252only 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>
<htmllang="en">
<head>
<metacharset="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
<metahttp-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>
<htmllang="en">
<head>
<metacharset="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
<metahttp-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: 10instead ofborder-radius: 10px. CSS requires explicit units for all non-zero length values. - Invalid keywords: Using a keyword like
border-radius: largethat isn't part of the CSS specification. - Negative values: The
border-radiusproperty does not accept negative lengths or percentages. - Unresolvable
var()references: The W3C validator performs static analysis and cannot evaluate CSS custom properties. If you usevar(--my-radius)in an inlinestyleattribute, 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 asborder-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
0as 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 flagvar()usage). - Use valid units such as
px,em,rem,%,vw, etc.
Examples
Invalid: missing unit on a non-zero value
<divstyle="border-radius:10;"></div>
Fixed: adding the correct unit
<divstyle="border-radius:10px;"></div>
Invalid: negative value
<divstyle="border-radius:-5px;"></div>
Fixed: using a non-negative value
<divstyle="border-radius:5px;"></div>
Invalid: unrecognized keyword
<divstyle="border-radius: round;"></div>
Fixed: using a valid percentage for a circular shape
<divstyle="border-radius:50%;"></div>
Invalid: var() in inline style that the validator cannot resolve
<divstyle="border-radius:var(--my-radius);"></div>
Fixed: defining the custom property in a stylesheet
<!DOCTYPE html>
<htmllang="en">
<head>
<title>Border Radius Example</title>
<style>
:root{
--my-radius:8px;
}
.rounded{
border-radius:var(--my-radius);
}
</style>
</head>
<body>
<divclass="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:
<divstyle="border-radius:8px;"></div>
Valid shorthand with elliptical radii
The / syntax lets you define horizontal and vertical radii separately:
<divstyle="border-radius:10px20px/5px15px;"></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:
<pstyle="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:
<pstyle="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>
<pclass="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:
<divstyle="font-size: initial;">Uses the property's initial value</div>
<divstyle="font-size: inherit;">Inherits from the parent element</div>
<divstyle="font-size: unset;">Resets to inherited or initial value</div>
<divstyle="font-size: revert;">Reverts to the user-agent default</div>
<divstyle="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-alignwithvertical-align: Usingmiddle,top, orbottom— these arevertical-alignvalues, nottext-alignvalues. - Typos: Writing
cetnerinstead ofcenter, orrigthinstead ofright. - 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-startorspace-betweenwithtext-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:
<pstyle="text-align: middle;">This text will fail validation.</p>
Fix: Replace middle with center:
<pstyle="text-align: center;">This text is properly centered.</p>
Invalid: typo in the value
<h2style="text-align: cetner;">Heading</h2>
Fix: Correct the spelling:
<h2style="text-align: center;">Heading</h2>
Invalid: using a non-existent value
<divstyle="text-align: auto;">Some content</div>
Fix: Choose a valid alignment value:
<divstyle="text-align: left;">Some content</div>
Invalid: using a vertical alignment value
<pstyle="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:
<pstyle="text-align: left;">Paragraph text</p>
Valid examples showing all common values
<pstyle="text-align: left;">Left-aligned text.</p>
<pstyle="text-align: right;">Right-aligned text.</p>
<pstyle="text-align: center;">Centered text.</p>
<pstyle="text-align: justify;">Justified text stretches to fill the full width of its container.</p>
<pstyle="text-align: start;">Start-aligned (respects text direction).</p>
<pstyle="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.
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
Pro Trial
Full Pro access. Cancel anytime.
Start Pro Trial →Join teams across 40+ countries