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 CSS cursor property controls the appearance of the mouse pointer when it hovers over an element. The value hand was introduced by early versions of Internet Explorer (IE 5.5 and earlier) as a proprietary extension to show a pointing-hand cursor over clickable elements. However, this value was never part of any CSS specification, and no other browser adopted it. The W3C-standard equivalent is pointer, which has been supported by all browsers — including Internet Explorer 6 and later — for over two decades.
When the W3C validator encounters cursor: hand, it flags it as an invalid value because hand does not exist in the CSS specification's list of accepted cursor values. While some legacy browsers may still interpret it, modern browsers will simply ignore the invalid declaration, meaning your clickable elements won't display the expected hand cursor for many users.
Beyond validation, using non-standard CSS values can cause inconsistent behavior across browsers and platforms. The pointer value is universally supported and is the correct way to signal that an element is interactive, such as a link, button, or any custom clickable region.
To fix this issue, replace every instance of cursor: hand with cursor: pointer in your stylesheets. If you need to support extremely old versions of Internet Explorer (IE 5.5 or earlier), you can declare both values — the browser will use whichever it recognizes — though this is almost never necessary today.
Examples
Invalid CSS
The value hand is not recognized by the CSS specification and will trigger a validation error:
.clickable{
cursor: hand;
}
Valid CSS
Use the standard pointer value instead:
.clickable{
cursor: pointer;
}
Using it in context with HTML
<style>
.card{
padding:16px;
border:1px solid #ccc;
cursor: pointer;
}
</style>
<divclass="card">
Click me to view details
</div>
Legacy fallback (rarely needed)
If for some reason you must support IE 5.5 or earlier alongside modern browsers, you can provide both declarations. The browser will apply the last value it understands:
.clickable{
cursor: hand;
cursor: pointer;
}
Note that this fallback pattern will still produce a validation warning for the hand value. In practice, there is virtually no reason to support browsers this old, so using cursor: pointer alone is the recommended approach.
Common cursor values
For reference, here are some of the most frequently used valid cursor values defined in the CSS specification:
auto— the browser determines the cursor based on context (default behavior)default— the platform's default cursor, typically an arrowpointer— a pointing hand, indicating a link or clickable elementtext— an I-beam, indicating selectable textmove— indicates something can be movednot-allowed— indicates an action is not permittedgrab/grabbing— indicates a draggable elementcrosshair— a precise selection cursorwait— indicates the program is busyhelp— indicates help is available
The full list of accepted values is defined in the CSS Basic User Interface Module specification.
The device-width and device-height media features (including their min- and max- prefixed versions) were originally designed to query the physical dimensions of a device's screen. In practice, this caused significant problems. On high-DPI (Retina) displays, max-device-width could report unexpected values depending on the device pixel ratio. When users resized their browser window, these features didn't respond because the physical screen size never changed. And with browser zoom, the layout could break because the query still referenced the fixed device dimensions rather than the actual available space.
The Media Queries Level 4 specification formally deprecated these features. Modern browsers still support them for backward compatibility, but they should not be used in new code. The W3C validator raises this warning to encourage migration to the current standard.
The viewport-based equivalents — width, min-width, and max-width — respond to the browser's layout viewport. This means they correctly adapt when the user resizes the window, zooms the page, or views the page in a split-screen mode. They also behave consistently across devices regardless of pixel density.
If your existing code uses max-device-width or min-device-width, the fix is straightforward: drop the word device from the feature name. For example, max-device-width: 768px becomes max-width: 768px. If you were relying on device dimensions to detect high-DPI screens, use the resolution media feature instead (e.g., min-resolution: 2dppx), which is the standards-compliant replacement for vendor-prefixed features like -webkit-min-device-pixel-ratio.
When choosing breakpoint values, prefer content-driven breakpoints — values where your layout actually needs to adapt — rather than targeting specific device widths. This produces more resilient designs that work well on any screen size.
Examples
Deprecated usage triggering the warning
The max-device-width media feature in the <style> block triggers the validator warning:
<!doctype html>
<htmllang="en">
<head>
<title>Deprecated Media Feature</title>
<style>
/* Deprecated: queries the physical device screen */
@mediaonly screen and(max-device-width:480px){
body{
background: pink;
}
}
</style>
</head>
<body>
<p>This page uses a deprecated media feature.</p>
</body>
</html>
The same warning appears if the deprecated feature is used in a <link> element's media attribute:
<linkrel="stylesheet"href="mobile.css"media="(max-device-width: 480px)">
Fixed example using viewport-based queries
Replace max-device-width with max-width to query the viewport instead:
<!doctype html>
<htmllang="en">
<head>
<title>Viewport-Based Media Query</title>
<style>
/* Correct: responds to the viewport width */
@media(max-width:480px){
body{
background: pink;
}
}
</style>
</head>
<body>
<p>This page uses a modern media feature.</p>
</body>
</html>
And for the <link> element:
<linkrel="stylesheet"href="mobile.css"media="(max-width: 480px)">
Replacing device pixel ratio queries
If you were using device-width features alongside -webkit-min-device-pixel-ratio to target high-DPI screens, switch to the standard resolution feature:
<style>
/* Deprecated approach */
@media(-webkit-min-device-pixel-ratio:2){
.logo{
background-image:url("logo@2x.png");
}
}
/* Standards-compliant replacement */
@media(min-resolution:2dppx){
.logo{
background-image:url("logo@2x.png");
}
}
</style>
Quick reference of replacements
| Deprecated feature | Modern replacement |
|---|---|
max-device-width | max-width |
min-device-width | min-width |
max-device-height | max-height |
min-device-height | min-height |
-webkit-min-device-pixel-ratio: 2 | min-resolution: 2dppx |
The min-device-width and max-device-width media features were originally designed to query the physical screen dimensions of a device. However, these features have been deprecated in Media Queries Level 4 and Level 5 because they are unreliable in modern browsing contexts. The physical screen size is a poor proxy for the actual available layout space — it doesn't account for browser chrome, split-screen modes, zoom levels, or the fact that many modern devices report abstract pixel values that don't correspond to physical hardware pixels in a straightforward way.
The viewport-based alternatives — min-width and max-width — respond to the layout viewport, which is the actual space your content is rendered into. This makes them far more useful for responsive design. When a user zooms in, the layout viewport shrinks, and min-width/max-width queries respond accordingly. With min-device-width, zooming has no effect on the query result, which can lead to layouts that don't adapt when they should.
Beyond practical concerns, using deprecated features means your CSS may behave inconsistently across browsers in the future, as support could be removed entirely. Validators flag this to encourage migration to the modern, standards-compliant approach.
How to fix it
The fix is a straightforward replacement:
min-device-width→min-widthmax-device-width→max-width
If your original query also included the screen keyword solely to pair with device-width targeting, you can safely drop it — min-width and max-width apply across all media types and the screen qualifier is rarely necessary in modern CSS.
If you were using min-device-width to detect high-density or Retina displays (a common pattern in older code), the correct modern approach is to use the resolution media feature instead, such as min-resolution: 2dppx.
Examples
Deprecated usage (triggers warning)
<!doctype html>
<htmllang="en">
<head>
<title>Deprecated media feature</title>
<style>
@media screen and(min-device-width:768px){
.sidebar{display: block;}
}
@media screen and(max-device-width:480px){
.sidebar{display: none;}
}
</style>
</head>
<body>
<asideclass="sidebar">Sidebar content</aside>
</body>
</html>
Both min-device-width and max-device-width are deprecated and will produce validation warnings.
Fixed example using viewport-based queries
<!doctype html>
<htmllang="en">
<head>
<title>Viewport-based media queries</title>
<style>
@media(min-width:768px){
.sidebar{display: block;}
}
@media(max-width:480px){
.sidebar{display: none;}
}
</style>
</head>
<body>
<asideclass="sidebar">Sidebar content</aside>
</body>
</html>
Replacing device-width with resolution for pixel density
Older code sometimes used min-device-width in combination with -webkit-min-device-pixel-ratio to target high-density screens. The modern equivalent uses the resolution media feature:
<!doctype html>
<htmllang="en">
<head>
<title>Resolution media query</title>
<style>
/* Deprecated approach */
/* @media screen and (min-device-width: 768px) and (-webkit-min-device-pixel-ratio: 2) { .hero { background-image: url("hero@2x.jpg"); } } */
@media screen and (min-device-width: 768px) and (-webkit-min-device-pixel-ratio: 2) {
.hero { background-image: url("hero@2x.jpg"); }
}
*/
/* Modern approach */
@media(min-width:768px)and(min-resolution:2dppx){
.hero{background-image:url("hero@2x.jpg");}
}
</style>
</head>
<body>
<divclass="hero">Hero section</div>
</body>
</html>
The min-resolution: 2dppx query cleanly replaces vendor-prefixed pixel ratio queries and works alongside the standard min-width viewport query.
The CSS display property controls how an element generates boxes in the layout. It determines whether an element behaves as a block-level or inline-level element and defines the layout model for its children (e.g., flow, flexbox, or grid). Because display is fundamental to page layout, using an invalid value means the browser will ignore the declaration entirely, potentially causing unexpected rendering.
Common causes of this error include:
- Typos — writing
dipslay: block,display: blok, ordisplay: flxinstead of the correct keywords. - Confusing values from other properties — using values like
center,hidden,absolute, orrelative, which belong to properties liketext-align,visibility, orposition, notdisplay. - Invented or outdated values — using non-standard or deprecated values that browsers don't recognize, such as
display: box(an old prefixed flexbox syntax without the prefix). - Missing vendor prefixes — some older syntaxes like
-webkit-flexwere valid in certain browsers but are not standard CSS values.
The valid values for display include: block, inline, inline-block, flex, inline-flex, grid, inline-grid, flow-root, none, contents, table, table-row, table-cell, table-caption, table-column, table-column-group, table-footer-group, table-header-group, table-row-group, list-item, and the multi-keyword syntax like block flow, block flex, or inline grid.
Using invalid CSS values is a problem because browsers silently discard declarations they don't understand. This means your intended layout won't be applied, and debugging can be difficult since no visible error appears in the browser. Validating your CSS catches these mistakes early.
Examples
Invalid: typo in the display value
<divstyle="display: flx;">
<p>This container was meant to be a flex container.</p>
</div>
Fixed: correct flex value
<divstyle="display: flex;">
<p>This container is now a flex container.</p>
</div>
Invalid: using a value from another property
<navstyle="display: center;">
<ahref="/">Home</a>
</nav>
The value center does not belong to display. If the goal is to center content, use a valid display value combined with appropriate alignment properties.
Fixed: using flex with centering
<navstyle="display: flex;justify-content: center;">
<ahref="/">Home</a>
</nav>
Invalid: using a position value instead of a display value
<divstyle="display: absolute;">
<p>Overlay content</p>
</div>
Fixed: using the correct property
<divstyle="position: absolute;display: block;">
<p>Overlay content</p>
</div>
Invalid: using a non-standard value
<ulstyle="display: box;">
<li>Item 1</li>
<li>Item 2</li>
</ul>
Fixed: using the standard flexbox value
<ulstyle="display: flex;">
<li>Item 1</li>
<li>Item 2</li>
</ul>
The CSS fill property does not accept linear-gradient() as a valid value.
The fill property is used primarily with SVG elements to define the color that fills the interior of a shape. It accepts simple color values like named colors, hex codes, rgb(), hsl(), currentColor, none, or a reference to an SVG paint server using url().
CSS gradients such as linear-gradient() are classified as <image> values, not <color> values, so they cannot be used directly with fill. This is different from properties like background or background-image, which do accept gradient values.
If you need a gradient fill on an SVG element, you should define a <linearGradient> inside an SVG <defs> block and reference it with url().
How to fix it
Invalid: Using linear-gradient() with fill:
<svgwidth="100"height="100">
<rectwidth="100"height="100"style="fill:linear-gradient(to right, red, blue);"/>
</svg>
Valid: Using an SVG <linearGradient> definition:
<svgwidth="100"height="100">
<defs>
<linearGradientid="myGradient"x1="0"y1="0"x2="1"y2="0">
<stopoffset="0%"stop-color="red"/>
<stopoffset="100%"stop-color="blue"/>
</linearGradient>
</defs>
<rectwidth="100"height="100"fill="url(#myGradient)"/>
</svg>
The x1, y1, x2, and y2 attributes on <linearGradient> control the direction of the gradient. In this example, x1="0" x2="1" creates a left-to-right gradient, equivalent to to right in CSS.
An invalid value was passed to the drop-shadow() function inside the CSS filter property.
The drop-shadow() function accepts a shadow definition similar to box-shadow, but with some restrictions. It takes two or three length values (offset-x, offset-y, and an optional blur-radius), plus an optional color. Unlike box-shadow, it does not accept a spread-radius value or the inset keyword.
The correct syntax is:
filter: drop-shadow(offset-x offset-y blur-radius color);
Each parameter has specific requirements:
offset-xandoffset-yare required length values (e.g.,2px,0.5em).blur-radiusis optional and must be a non-negative length. Negative values are not allowed.coloris optional. If omitted, the browser uses the element'scolorproperty value.
Common mistakes that trigger this error include adding a spread-radius (a fourth length value), using the inset keyword, or passing a malformed color value.
Examples
This is invalid because drop-shadow() does not support a spread-radius (the 5px fourth length value):
<divstyle="filter:drop-shadow(4px4px10px5px red);">
Shadow content
</div>
Remove the spread-radius to fix it:
<divstyle="filter:drop-shadow(4px4px10px red);">
Shadow content
</div>
The CSS filter property accepts a specific set of filter functions defined in the CSS Filter Effects Module. When the validator encounters a value it doesn't recognize — such as the legacy IE progid:DXImageTransform.Microsoft. syntax, a made-up function name, or an incorrectly formatted value — it flags it as invalid.
The standard filter functions are: blur(), brightness(), contrast(), drop-shadow(), grayscale(), hue-rotate(), invert(), opacity(), saturate(), sepia(), and url() (for referencing SVG filters). The property also accepts the keyword none. Any value outside this set will trigger the validation error.
Why this matters
Using non-standard filter values creates several problems:
- Browser compatibility: Legacy or proprietary filter syntax (such as Microsoft's
filter: alpha(opacity=50)orfilter: FlipH) only works in old versions of Internet Explorer and is ignored by all modern browsers. - Standards compliance: Invalid CSS can cause parsers to discard the entire declaration or even the surrounding rule block, potentially breaking other styles.
- Future-proofing: Non-standard values may stop working entirely as browsers drop legacy support, leaving your design broken with no fallback.
How to fix it
- Identify the invalid value in the error message.
- Determine what visual effect you're trying to achieve.
- Replace the invalid value with the corresponding standard CSS
filterfunction. - If you're using legacy IE opacity filters, switch to the standard
opacityproperty instead.
Examples
❌ Invalid: Legacy Microsoft filter syntax
<style>
.overlay{
filter:alpha(opacity=50);
}
</style>
✅ Fixed: Use standard opacity property
<style>
.overlay{
opacity:0.5;
}
</style>
❌ Invalid: Misspelled or non-existent filter function
<style>
.photo{
filter:gray();
}
</style>
✅ Fixed: Use the correct grayscale() function
<style>
.photo{
filter:grayscale(100%);
}
</style>
❌ Invalid: Vendor-prefixed or proprietary value
<style>
.card{
filter: progid:DXImageTransform.Microsoft.Blur(pixelradius=5);
}
</style>
✅ Fixed: Use the standard blur() function
<style>
.card{
filter:blur(5px);
}
</style>
❌ Invalid: Bare value without a function
<style>
.image{
filter:50%;
}
</style>
✅ Fixed: Wrap the value in the appropriate function
<style>
.image{
filter:brightness(50%);
}
</style>
Combining multiple filters
You can chain multiple standard filter functions in a single declaration by separating them with spaces:
<style>
.hero-image{
filter:contrast(120%)brightness(90%)blur(1px);
}
</style>
If none of the built-in filter functions achieve the effect you need, you can reference a custom SVG filter using the url() function, which is also a valid filter value:
<svgxmlns="http://www.w3.org/2000/svg"class="visually-hidden">
<filterid="custom-effect">
<feColorMatrixtype="matrix"values="0.3 0.3 0.3 0 0 0.3 0.3 0.3 0 0 0.3 0.3 0.3 0 0 0 0 0 1 0"/>
0.3 0.3 0.3 0 0
0.3 0.3 0.3 0 0
0 0 0 1 0
</filter>
</svg>
<style>
.filtered{
filter: url(#custom-effect);
}
</style>
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 correct value is nowrap (without a hyphen), not no-wrap.
The flex-wrap CSS property controls whether flex items are forced onto a single line or can wrap onto multiple lines. It accepts three values: nowrap (the default), wrap, and wrap-reverse. A common mistake is writing no-wrap with a hyphen, likely because the white-space CSS property uses nowrap and no-wrap interchangeably in some contexts, or simply because it looks more natural in English. However, for flex-wrap, only the unhyphenated nowrap is valid.
HTML Example With the Issue
<divstyle="display: flex;flex-wrap: no-wrap;">
<p>Item 1</p>
<p>Item 2</p>
</div>
Fixed HTML Example
<divstyle="display: flex;flex-wrap: nowrap;">
<p>Item 1</p>
<p>Item 2</p>
</div>
font-display controls how a font face is displayed based on whether and when it has been downloaded and is ready to use. Its accepted values — auto, block, swap, fallback, and optional — determine the behavior during the font-loading timeline (block period, swap period, and failure period). Because it governs the loading behavior of a font face definition, it only makes sense within a @font-face rule, not as a property applied to an HTML element.
When you place font-display inside a regular selector like body or .heading, the CSS validator correctly flags it as an unknown property. Browsers will silently ignore it, meaning your intended font-loading strategy won't take effect. Users may experience a flash of invisible text (FOIT) or other unwanted behavior because the browser falls back to its default font-display strategy.
Why this matters
- Font-loading performance: Without a valid
font-displaydescriptor in your@font-facerule, you lose control over how the browser handles text rendering while custom fonts load. Usingfont-display: swap, for example, ensures text remains visible with a fallback font until the custom font is ready — a key web performance best practice. - Standards compliance: The CSS Fonts Module Level 4 specification defines
font-displayexclusively as a@font-facedescriptor. Using it elsewhere produces invalid CSS. - Silent failure: Browsers won't throw visible errors — they simply ignore the invalid property, which can make it difficult to diagnose why your font-loading behavior isn't working as expected.
How to fix it
- Remove
font-displayfrom any regular CSS rule (selectors likebody,h1,.class, etc.). - Add
font-displayinside the@font-faceat-rule where you define your custom font. - If you're loading fonts via a third-party service (like Google Fonts), you can often append a
&display=swapparameter to the font URL instead of writing your own@font-faceblock.
Examples
❌ Incorrect: font-display used as a CSS property
body{
font-family:"Open Sans", sans-serif;
font-display: swap;
}
This triggers the validator error because font-display is not a valid CSS property for element selectors.
✅ Correct: font-display used inside @font-face
@font-face{
font-family:"Open Sans";
src:url("/fonts/open-sans.woff2")format("woff2"),
url("/fonts/open-sans.woff")format("woff");
font-display: swap;
}
body{
font-family:"Open Sans", sans-serif;
}
Here, font-display: swap is correctly placed inside the @font-face rule, telling the browser to immediately render text with a fallback font and then swap in "Open Sans" once it finishes loading.
✅ Correct: Using display=swap with Google Fonts
If you use Google Fonts, you don't need to write your own @font-face block. Instead, add the display parameter to the URL:
<linkrel="stylesheet"href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap">
Google Fonts will generate the @font-face rules with font-display: swap included automatically.
❌ Incorrect: font-display in a class selector
.heading{
font-family:"Roboto", sans-serif;
font-display: optional;
}
✅ Correct: Separate the descriptor from the styling rule
@font-face{
font-family:"Roboto";
src:url("/fonts/roboto.woff2")format("woff2");
font-display: optional;
}
.heading{
font-family:"Roboto", sans-serif;
}
The font-display: optional descriptor now correctly lives in the @font-face block, where it tells the browser to use the custom font only if it's already cached — otherwise, stick with the fallback. The .heading rule simply references the font family by name.
A CSS syntax error in your font-family declaration is using an invalid character or operator where the validator expects a comma-separated list of font names.
The font-family property expects font names separated by commas. A common mistake is using operators like +, =, or / between font names, or copying malformed font names from URLs (like Google Fonts link URLs where + replaces spaces). Font names with spaces must be wrapped in quotes.
For example, font-family: Open+Sans is invalid because + is not a valid CSS operator in this context. The correct form is font-family: "Open Sans". Similarly, using font-family: Arial / Helvetica is invalid — a comma should separate fallback fonts.
Invalid Example
<pstyle="font-family: Open+Sans, sans-serif;">Hello</p>
Fixed Example
<pstyle="font-family:'Open Sans', sans-serif;">Hello</p>
Double-check that your font names use commas as separators, quotes around names with spaces, and no stray characters like +, /, or =.
The font-size property sets the size of text and expects a valid CSS value — either a keyword (like small, medium, large), a numeric value with a unit (like 16px, 1.2em, 100%), or 0 (which needs no unit). When the validator reports that "px" is not a valid font-size value, it means the property received the string px alone, without the required number preceding it.
This issue commonly arises in a few scenarios:
- Typos or accidental deletion: The number was removed during editing, leaving just the unit behind.
- Template or CMS output: A dynamic value (e.g., from a variable or database field) resolved to empty, producing something like
font-size: px;. - Preprocessor errors: A Sass, Less, or other CSS preprocessor variable was undefined or empty, resulting in a bare unit in the compiled CSS.
While most browsers will simply ignore the invalid declaration and fall back to an inherited or default font size, this creates unpredictable rendering. The text may appear at an unexpected size, and the behavior may differ across browsers. Invalid CSS also causes W3C validation failures, which can signal deeper problems in your code or build pipeline.
How to Fix It
- Check for a missing number: Look at the
font-sizedeclaration flagged by the validator and add the intended numeric value before the unit. - Inspect dynamic values: If the value comes from a variable, template engine, or CMS field, ensure it outputs a complete value (e.g.,
16or16px) rather than an empty string. - Use a fallback: When generating CSS dynamically, consider providing a fallback value in case the variable is empty.
Examples
❌ Incorrect: Bare unit with no number
<pstyle="font-size: px;">This text has an invalid font size.</p>
The validator will report that "px" is not a valid font-size value because no number precedes the unit.
✅ Correct: Numeric value with unit
<pstyle="font-size:16px;">This text has a valid font size.</p>
❌ Incorrect: Empty value from a template variable
This is a common pattern in templating systems that can produce invalid CSS:
<pstyle="font-size: px;">Dynamic content here.</p>
When the template variable resolves to an empty string, only px remains.
✅ Correct: Using a keyword value
If you don't need a specific pixel size, CSS keywords are another valid option:
<pstyle="font-size: medium;">This uses a keyword font size.</p>
✅ Correct: Using other valid units
The font-size property accepts many unit types. All of these are valid:
<style>
.example-em{font-size:1.2em;}
.example-rem{font-size:1rem;}
.example-percent{font-size:120%;}
.example-px{font-size:14px;}
.example-keyword{font-size: large;}
</style>
✅ Correct: Full document example
<!DOCTYPE html>
<htmllang="en">
<head>
<title>Font Size Example</title>
<style>
p{
font-size:16px;
}
</style>
</head>
<body>
<p>This paragraph has a valid font size of 16px.</p>
</body>
</html>
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 font-size property defines the size of text in CSS and accepts a specific set of value types. When the W3C validator reports that a value "is not a font-size value," it means the value you provided doesn't match any of the accepted formats. Browsers may attempt to ignore or guess what you meant, but this leads to unpredictable rendering across different browsers and devices.
This error commonly occurs for a few reasons:
- Missing units on numeric values. Writing
font-size: 16instead offont-size: 16px. In CSS, unitless numbers (other than0) are not valid lengths. - Typos in units or keywords. For example,
font-size: 16xp,font-size: 1.2erm, orfont-size: lage. - Using values from the wrong property. For example,
font-size: bold(which belongs tofont-weight) orfont-size: center. - Invalid or unsupported syntax. For example,
font-size: 16 px(with a space between the number and unit) orfont-size: auto(which is not valid for this property).
Valid font-size value types
| Type | Examples | Notes |
|---|---|---|
| Absolute keywords | xx-small, x-small, small, medium, large, x-large, xx-large, xxx-large | Browser-defined sizes |
| Relative keywords | smaller, larger | Relative to the parent element's font size |
| Length units | 16px, 1.2em, 0.9rem, 12pt, 1vw | Must include a unit (except 0) |
| Percentages | 100%, 120%, 80% | Relative to the parent element's font size |
| Math functions | calc(1rem + 2px), clamp(1rem, 2vw, 3rem) | CSS math expressions that resolve to a length |
Examples
Incorrect: missing unit on a number
<pstyle="font-size:16;">This triggers a validation error.</p>
The value 16 is not valid because it lacks a CSS unit. Browsers may ignore this declaration entirely, leaving the text at its default or inherited size.
Correct: number with a valid unit
<pstyle="font-size:16px;">This text has a valid font size.</p>
Incorrect: typo in the unit
<pstyle="font-size:1.2erm;">Typo in the unit.</p>
Correct: proper em unit
<pstyle="font-size:1.2em;">Correct em unit.</p>
Incorrect: value from the wrong property
<pstyle="font-size: bold;">Bold is not a font-size value.</p>
Correct: using a valid keyword
<pstyle="font-size: large;">Using a valid size keyword.</p>
Incorrect: space between number and unit
<pstyle="font-size:16 px;">Space before the unit is invalid.</p>
Correct: no space between number and unit
<pstyle="font-size:16px;">No space between number and unit.</p>
Full document example
<!DOCTYPE html>
<htmllang="en">
<head>
<title>Font Size Example</title>
<style>
.heading{
font-size:2rem;
}
.body-text{
font-size:1em;
}
.small-print{
font-size:80%;
}
.responsive{
font-size:clamp(1rem,2.5vw,2rem);
}
</style>
</head>
<body>
<h1class="heading">Valid heading size</h1>
<pclass="body-text">Body text at 1em.</p>
<pclass="small-print">Small print at 80%.</p>
<pclass="responsive">Responsive text using clamp().</p>
</body>
</html>
To resolve this validation error, review every font-size declaration in your CSS or inline styles. Make sure each value is either a recognized keyword, a number immediately followed by a valid unit, a percentage, or a supported CSS function like calc(). If you intended 0, that is the one numeric value that does not require a unit — font-size: 0 is valid, though rarely useful in practice.
The 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-stretchwithfont-weight: You intended to make text bold but accidentally used the wrong property. - Typo or copy-paste error in the
fontshorthand: 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 like700). - If you want wider or narrower characters, use
font-stretchwith a valid value likecondensedorexpanded. - If you need both, apply each property separately or use the
fontshorthand correctly.
Examples
Incorrect: Using bold with font-stretch
This triggers the validation error because bold is not a valid font-stretch value:
<pstyle="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:
<pstyle="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:
<pstyle="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>
<pclass="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>
<pclass="condensed">Condensed text</p>
<pclass="normal-width">Normal width text</p>
<pclass="expanded">Expanded text</p>
<pclass="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 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, orobliquewith an angle (e.g.,oblique 10deg)font-weight:normal,bold,bolder,lighter, or numeric values from100to900
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:
<pstyle="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:
<pstyle="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:
<pstyle="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>
<pclass="emphasis">This text is bold (weight 700).</p>
<pclass="light">This text is light (weight 300).</p>
<pclass="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 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-stylewithfont-size: Since both properties start withfont-, it's easy to accidentally typefont-style: 1.2emwhen you meantfont-size: 1.2em. Numeric and length values are not valid forfont-style. - Confusing
font-stylewithfont-weight: Writingfont-style: boldis invalid becauseboldis afont-weightvalue, not afont-stylevalue. - Typos in keyword values: Misspelling a valid keyword, such as
font-style: itallicorfont-style: oblque, will trigger this error. - Using the
obliqueangle syntax incorrectly: Whileobliquecan accept an optional angle (e.g.,oblique 10deg), providing an angle without theobliquekeyword 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 toobliqueif unavailable.oblique— selects the oblique face; optionally accepts an angle value (e.g.,oblique 10deg). The angle defaults to14degif 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:
<pstyle="font-style:1.2em;">This text has an invalid font-style.</p>
Correct: use font-size for size values
<pstyle="font-size:1.2em;">This text has a valid font size.</p>
Incorrect: using bold with font-style
<pstyle="font-style: bold;">This text has an invalid font-style.</p>
Correct: use font-weight for boldness
<pstyle="font-weight: bold;">This text is bold.</p>
Incorrect: misspelled keyword
<pstyle="font-style: itallic;">This text has a typo in font-style.</p>
Correct: properly spelled keyword
<pstyle="font-style: italic;">This text is italic.</p>
Correct: using oblique with an angle
<pstyle="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 |
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 to400),bold(equivalent to700),bolder(relative, one step heavier than the parent),lighter(relative, one step lighter than the parent). - Numeric values: Any number from
1to1000. Historically only multiples of 100 (100through900) were valid, but the CSS Fonts Level 4 specification expanded this to any value in the1–1000range. Note that many validators and older browsers may still only recognize the100–900multiples.
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>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="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>
<pclass="light">This text uses a light font weight (300).</p>
<pclass="regular">This text uses a normal font weight (400).</p>
<pclass="semi-bold">This text uses a semi-bold font weight (600).</p>
<pclass="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.
The CSS font shorthand property has a specific syntax defined in the CSS specification. At minimum, it requires both a font-size and a font-family value. Optionally, you can prepend font-style, font-variant, and font-weight, and you can append a line-height value after the font-size using a slash separator. The full syntax looks like this:
font: [font-style] [font-variant] [font-weight] font-size[/line-height] font-family;
When the W3C validator reports that a value "is not a font-family value," it means the parser reached a point in the font declaration where it expected to find a font family name but instead found something it couldn't interpret as one. This often happens in two scenarios:
- Using
fontwhen you meant a specific property — For example, writingfont: 300when you only intended to set the font weight. The validator tries to parse300as a completefontvalue, and since there's nofont-sizeorfont-family, it fails. - Incomplete
fontshorthand — Providing some values but forgetting the mandatoryfont-familyat the end, such asfont: 300 16pxwithout a family name.
This matters because browsers may ignore an invalid font declaration entirely, causing your text to render with default or inherited styles instead of what you intended. Keeping your CSS valid also ensures consistent behavior across different browsers and helps maintain clean, predictable stylesheets.
How to fix it:
- If you only need to set a single font-related property, use the specific property (
font-weight,font-size,font-style,font-variant, orfont-family) instead of thefontshorthand. - If you want to use the
fontshorthand, make sure you include at leastfont-sizeandfont-family, and that all values appear in the correct order. - Remember that the
fontshorthand resets any omitted font sub-properties to their initial values, so use it deliberately.
Examples
Incorrect: Using font to set only the weight
<pstyle="font:300;">This text has an invalid font declaration.</p>
The validator reports that 300 is not a valid font-family value because the font shorthand expects at least a font-size and font-family.
Correct: Using font-weight directly
<pstyle="font-weight:300;">This text has a light font weight.</p>
Incorrect: Missing font-family in the shorthand
<pstyle="font: italic 30016px;">This is also invalid.</p>
Even though font-style, font-weight, and font-size are all present, the required font-family is missing.
Correct: Complete font shorthand
<pstyle="font: italic 30016px/1.5 'Helvetica', sans-serif;">This is valid.</p>
This includes all components in the correct order: font-style, font-weight, font-size/line-height, and font-family.
Correct: Minimal valid font shorthand
<pstyle="font:16px sans-serif;">Only size and family — the minimum required.</p>
Correct: Using individual properties instead of the shorthand
<pstyle="font-style: italic;font-weight:300;font-size:16px;line-height:1.5;font-family:'Helvetica', sans-serif;">
Each property set individually.
</p>
Using individual properties avoids the pitfalls of the shorthand and gives you explicit control without accidentally resetting other font sub-properties.
The gap property is a shorthand for row-gap and column-gap, used in CSS Grid, Flexbox, and multi-column layouts to define spacing between items or tracks. According to the CSS Box Alignment specification, the accepted values for gap are length values (px, em, rem, %, vh, etc.), the normal keyword, or the calc() function. The keyword auto — while valid for many other CSS properties like margin, width, and grid-template-columns — is simply not part of the gap property's value grammar.
This confusion often arises because developers are accustomed to using auto for spacing in other contexts. For instance, margin: auto is a common centering technique, and auto is widely used in grid track sizing. However, the gap property serves a different purpose: it defines a fixed or computed gutter size between items, and auto has no defined meaning in that context.
Why this matters
- Standards compliance: Using an invalid value means the browser will ignore the entire
gapdeclaration, falling back to the default value ofnormal(which is typically0pxin Grid and Flexbox). This can lead to unexpected layout results where items have no spacing at all. - Cross-browser consistency: While some browsers may be lenient with invalid CSS values, others will strictly discard them. This creates inconsistent layouts across different browsers and versions.
- Maintainability: Invalid CSS values can mask the developer's intent, making it harder for others (or your future self) to understand what spacing was desired.
How to fix it
Replace auto with a valid value for gap:
- A specific length:
gap: 16px;,gap: 1rem;,gap: 0.5em; - A percentage:
gap: 2%; - The
normalkeyword:gap: normal;(resolves to0pxin Flexbox and Grid) - A
calc()expression:gap: calc(1rem + 4px); - Two values for row and column separately:
gap: 16px 24px;
If you were using auto because you wanted the browser to determine the spacing dynamically, consider using a percentage value, a viewport-relative unit (vw, vh), or CSS clamp() for responsive gutters.
Examples
Incorrect: using auto as a gap value
<divstyle="display: grid;grid-template-columns:1fr1fr;gap: auto;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
This triggers the validation error because auto is not a valid gap value. The browser will discard the declaration entirely.
Correct: using a fixed length
<divstyle="display: grid;grid-template-columns:1fr1fr;gap:16px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
Correct: using separate row and column gaps
<divstyle="display: grid;grid-template-columns:1fr1fr;gap:12px24px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
Correct: using a percentage for responsive spacing
<divstyle="display: flex;flex-wrap: wrap;gap:2%;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
Correct: using clamp() for fluid responsive gaps
<divstyle="display: grid;grid-template-columns:1fr1fr;gap:clamp(8px,2vw,32px);">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
This approach gives you a gap that scales with the viewport width, bounded between 8px and 32px — a useful alternative if you were reaching for auto to get flexible spacing behavior.
The grid-column property is a shorthand for grid-column-start and grid-column-end. It defines where a grid item is placed horizontally within a CSS Grid layout. The validator checks that inline style attributes and <style> blocks contain valid CSS, and it will flag any value that doesn't conform to the property's grammar.
Why This Happens
Several kinds of invalid values can trigger this error:
- Using
0as a line number. CSS Grid lines are 1-indexed. Line0does not exist, so values likegrid-column: 0,grid-column: 0 / 3, orgrid-column: span 0are all invalid. - Typos or unrecognized keywords. Values like
grid-column: centerorgrid-column: fullare not valid unless they match named grid lines you've explicitly defined. - Malformed shorthand syntax. Missing the
/separator, using commas instead, or providing too many values will cause a parse error. - Using
spanincorrectly. Thespankeyword must be followed by a positive integer or a named line, e.g.,span 2. Writingspan -1orspan 0is invalid.
Valid Syntax
The grid-column shorthand accepts:
grid-column: <grid-line>/ <grid-line>;
Each <grid-line> can be:
- A positive or negative integer (but not
0) representing a grid line number - A named grid line (e.g.,
content-start) - The
spankeyword followed by a positive integer or a name (e.g.,span 2) auto
If only one value is provided (no /), the end line defaults to auto.
Why It Matters
Invalid CSS values are ignored by browsers, meaning the grid item will fall back to automatic placement. This can cause unexpected layout shifts. Ensuring valid values improves standards compliance, makes your layout predictable across browsers, and prevents silent failures that are hard to debug.
Examples
❌ Invalid: Using 0 as a line number
<divstyle="display: grid;grid-template-columns:repeat(3,1fr);">
<divstyle="grid-column:0/3;">Item</div>
</div>
Grid lines start at 1, so 0 is not a valid line number.
✅ Fixed: Using a valid line number
<divstyle="display: grid;grid-template-columns:repeat(3,1fr);">
<divstyle="grid-column:1/3;">Item</div>
</div>
❌ Invalid: Unrecognized keyword
<divstyle="display: grid;grid-template-columns:repeat(3,1fr);">
<divstyle="grid-column: full;">Item</div>
</div>
The value full is not a valid grid line value unless it's a named line defined in the grid template.
✅ Fixed: Using span to cover all columns
<divstyle="display: grid;grid-template-columns:repeat(3,1fr);">
<divstyle="grid-column:1/-1;">Item</div>
</div>
Using -1 refers to the last grid line, effectively spanning all columns.
❌ Invalid: span 0
<divstyle="display: grid;grid-template-columns:repeat(4,1fr);">
<divstyle="grid-column: span 0;">Item</div>
</div>
The span keyword requires a positive integer. 0 is not valid.
✅ Fixed: Using a positive span value
<divstyle="display: grid;grid-template-columns:repeat(4,1fr);">
<divstyle="grid-column: span 2;">Item</div>
</div>
❌ Invalid: Malformed syntax with a comma
<divstyle="display: grid;grid-template-columns:repeat(3,1fr);">
<divstyle="grid-column:1,3;">Item</div>
</div>
✅ Fixed: Using the / separator
<divstyle="display: grid;grid-template-columns:repeat(3,1fr);">
<divstyle="grid-column:1/3;">Item</div>
</div>
The start and end lines must be separated by a /, not a comma.
Quick Reference of Valid Patterns
| Value | Meaning |
|---|---|
grid-column: 2 | Start at line 2, end at auto |
grid-column: 2 / 5 | Start at line 2, end at line 5 |
grid-column: 1 / -1 | Span from first to last line |
grid-column: span 3 | Span 3 columns from auto-placed start |
grid-column: 2 / span 3 | Start at line 2, span 3 columns |
grid-column: auto / auto | Fully automatic placement |
When in doubt, check that every numeric value is a non-zero integer and that the overall format uses / to separate the start and end values.
The grid-template-columns property defines the column track sizes of a CSS grid container. When the W3C validator reports that a particular value "is not a grid-template-columns value," it means the parser encountered something it cannot interpret as a valid track size or track listing.
This error can be triggered by many common mistakes: a simple typo (like auто instead of auto), using a CSS custom property (the validator may not resolve var() references), forgetting units on a length value (e.g., 100 instead of 100px), using JavaScript-like terms (e.g., undefined or null), or using newer syntax that the validator's CSS parser doesn't yet support.
While browsers are generally forgiving and will simply ignore an invalid grid-template-columns declaration, this means your grid layout silently breaks — the container won't form a grid as intended, and content may stack in a single column. Fixing validation errors ensures your layout works predictably across browsers and makes your stylesheets easier to maintain.
Valid values
The grid-template-columns property accepts these value types:
none— the default; no explicit grid columns are defined.- Length and percentage values —
px,em,rem,%,vh,vw, etc. (e.g.,200px,50%). - The
frunit — distributes remaining space proportionally (e.g.,1fr 2fr). - Keywords —
auto,min-content,max-content. - The
repeat()function — shorthand for repeated track patterns (e.g.,repeat(3, 1fr)). - The
minmax()function — sets a minimum and maximum size for a track (e.g.,minmax(150px, 1fr)). - The
fit-content()function — clamps the track to a given maximum (e.g.,fit-content(300px)). - Named grid lines — defined with square brackets (e.g.,
[sidebar-start] 200px [sidebar-end content-start] 1fr [content-end]). - Any combination of the above.
Common causes
- Typos or made-up keywords — values like
undefined,inherit-grid, or misspelled units. - Missing units — writing
100instead of100px. Thefrunit,px, and all other units are mandatory (only0can be unitless). - Invalid function syntax — missing commas or parentheses in
repeat()orminmax(). - CSS custom properties —
var(--cols)may trigger validator warnings because the validator cannot resolve the variable at parse time. This is typically a false positive.
Examples
Incorrect: invalid keyword
<style>
.grid{
display: grid;
grid-template-columns: undefined;
}
</style>
Incorrect: missing unit on a length
<style>
.grid{
display: grid;
grid-template-columns:2001fr;
}
</style>
Incorrect: malformed repeat() syntax
<style>
.grid{
display: grid;
grid-template-columns:repeat(31fr);
}
</style>
Correct: using fr units
<style>
.grid{
display: grid;
grid-template-columns:1fr2fr;
}
</style>
Correct: mixing lengths, fr, and auto
<style>
.grid{
display: grid;
grid-template-columns:250px1fr auto;
}
</style>
Correct: using repeat() and minmax()
<style>
.grid{
display: grid;
grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
}
</style>
Correct: named grid lines with track sizes
<style>
.grid{
display: grid;
grid-template-columns:[sidebar]240px[content]1fr[aside]200px;
}
</style>
If the validator flags a var() custom property usage and you're confident the variable resolves to a valid value at runtime, the warning can generally be disregarded — this is a known limitation of static CSS validation. For all other cases, double-check spellings, ensure every numeric value (other than 0) has a unit, and verify that function syntax includes the correct commas and parentheses.
The grid-template-rows property defines the size of each row in a CSS grid layout. The W3C validator checks that every value in the declaration conforms to the CSS Grid specification. When you see this error, the validator has encountered something it cannot parse as a valid track size.
Common causes of this error include:
- Typos or invalid units — writing
100 px(with a space),100pixels, or1 frinstead of1fr. - Using values from other properties — for example,
flex,inline, orspace-betweenare not valid row track sizes. - Incorrect function syntax — missing commas in
repeat(), providing wrong arguments tominmax(), or using unsupported functions. - Missing units — writing a bare number like
100instead of100px(zero is the only number that doesn't require a unit). - Using newer syntax not yet recognized — some cutting-edge features like
subgridor themasonryvalue may trigger validation warnings depending on the validator's supported spec level.
The grid-template-rows property accepts these valid value types:
- Length values:
100px,5em,10rem,20vh - Percentages:
50%,33.3% - Flexible lengths:
1fr,2fr - Keywords:
auto,min-content,max-content,none - Functions:
repeat(),minmax(),fit-content() - Named lines:
[row-start] 100px [row-end]
This matters for standards compliance and forward compatibility. While browsers may be lenient and ignore invalid values, relying on that behavior can lead to layouts that silently break. Valid CSS ensures your grid behaves predictably across all browsers.
Examples
Incorrect — invalid values
<style>
/* ERROR: "full" is not a valid track size */
.grid-a{
display: grid;
grid-template-rows: full auto;
}
/* ERROR: space between number and unit */
.grid-b{
display: grid;
grid-template-rows:100 px 200 px;
}
/* ERROR: bare number without a unit */
.grid-c{
display: grid;
grid-template-rows:100200;
}
/* ERROR: missing comma in repeat() */
.grid-d{
display: grid;
grid-template-rows:repeat(31fr);
}
</style>
Correct — valid track sizes
<style>
/* Fixed pixel heights */
.grid-a{
display: grid;
grid-template-rows:100px auto;
}
/* Flexible units */
.grid-b{
display: grid;
grid-template-rows:1fr2fr;
}
/* Repeat function with correct syntax */
.grid-c{
display: grid;
grid-template-rows:repeat(3,1fr);
}
/* Minmax with auto */
.grid-d{
display: grid;
grid-template-rows:minmax(100px,1fr) auto;
}
</style>
Full working example
<!DOCTYPE html>
<htmllang="en">
<head>
<title>Grid template rows example</title>
<style>
.grid-container{
display: grid;
grid-template-rows:80pxminmax(150px,1fr) auto;
gap:8px;
height:400px;
}
.grid-container>div{
background:#e0e0e0;
padding:16px;
}
</style>
</head>
<body>
<divclass="grid-container">
<div>Row 1 — fixed 80px</div>
<div>Row 2 — between 150px and 1fr</div>
<div>Row 3 — auto-sized to content</div>
</div>
</body>
</html>
Using fit-content() and named lines
<style>
.grid{
display: grid;
grid-template-rows:[header]fit-content(100px)[main]1fr[footer] auto;
}
</style>
If your value looks correct but the validator still flags it, check whether you're using a very new CSS feature like subgrid or masonry. These may not yet be recognized by the validator even if some browsers support them. In that case, the warning can be acknowledged while keeping the value intentionally.
The height CSS property defines the height of an element's content area. According to CSS specifications, it accepts several value types: length values (like px, em, rem, vh, cm), percentages (%), and keywords such as auto, min-content, max-content, and fit-content. When the validator encounters a value that doesn't belong to any of these accepted types, it reports a type incompatibility error.
This error commonly occurs in a few scenarios:
- Missing units on numeric values. In CSS, a bare number like
100is not a valid length. The only exception is0, which doesn't require a unit because zero is the same in any unit system. Writingheight: 100;instead ofheight: 100px;is invalid CSS. - Unrecognized keywords. Using a word that isn't a valid CSS keyword for
height, such asbig,small, orfull, will trigger this error. These are not part of the CSS specification for theheightproperty. - Values from the wrong property. Sometimes values valid for other properties get mistakenly used with
height. For example,height: bold;orheight: block;are type mismatches because those keywords belong tofont-weightanddisplay, respectively. - Typos or syntax errors. A stray character, misspelled unit (e.g.,
100xpinstead of100px), or malformedcalc()expression can also cause this error.
While modern browsers often try to recover from invalid CSS by ignoring the offending declaration, this means the height rule silently has no effect, which can lead to unexpected layout behavior. Writing valid CSS ensures your styles work predictably across all browsers and avoids hard-to-debug rendering issues.
How to Fix It
- Add a valid unit to any bare numeric value. Use
px,em,rem,vh,%, or another valid CSS length unit. - Use only recognized keywords for
height:auto,min-content,max-content,fit-content, orfit-content(<length>). - Check for typos in both the value and the unit.
- Validate
calc()expressions to ensure the types inside are compatible (e.g., you can't add a length and a color).
Examples
Incorrect: Missing unit on a numeric value
<style>
.box{
height:100;/* invalid — no unit specified */
}
</style>
Incorrect: Unrecognized keyword
<style>
.box{
height: big;/* invalid — "big" is not a CSS keyword for height */
}
</style>
Incorrect: Misspelled unit
<style>
.box{
height:250xp;/* invalid — "xp" is not a recognized unit */
}
</style>
Correct: Valid length values, percentages, and keywords
<style>
.fixed{
height:200px;
}
.relative{
height:70%;
}
.viewport{
height:100vh;
}
.flexible{
height: auto;
}
.zero{
height:0;
}
.intrinsic{
height: min-content;
}
.calculated{
height:calc(100vh-60px);
}
</style>
Correct: Using height in context
<divstyle="height:300px;">
<pstyle="height:50%;">
This paragraph is 150px tall because its parent has a defined height.
</p>
</div>
Keep in mind that percentage-based height values only work when the parent element has a defined height. If the parent's height is auto, a child with height: 50% will behave as if it were set to auto as well. When in doubt, use an absolute length like px or a viewport unit like vh, or set height: auto to let the content determine the element's size.
The W3C validator checks inline styles and embedded stylesheets for valid CSS. When it encounters a height declaration with multiple values or an unrecognized value, it flags the error because height is not a shorthand property — it only accepts one value at a time. This differs from properties like margin or padding, which accept multiple values to target different sides of an element.
This error commonly occurs when you:
- Accidentally provide two values, perhaps confusing
heightwith a shorthand property (e.g.,height: 100px 50px;). - Include a typo or invalid unit (e.g.,
height: 100ppx;orheight: 100pixels;). - Use a CSS function incorrectly (e.g.,
height: calc(100% 20px);— missing the operator). - Copy a value meant for another property, such as pasting a
grid-template-rowsvalue intoheight.
Browsers may silently ignore invalid height declarations, causing your element to fall back to its default sizing (auto). This can lead to unexpected layout behavior that's difficult to debug. Keeping your CSS valid ensures consistent rendering across browsers and helps catch mistakes early.
Valid values for height
The height property accepts exactly one of the following:
- Length values:
100px,10em,5rem,20vh, etc. - Percentage values:
50%,100% - Keyword values:
auto,max-content,min-content,fit-content(200px) - Global values:
inherit,initial,revert,unset - Calc expressions:
calc(100% - 20px),calc(50vh + 2rem)
Examples
Incorrect: too many values
<style>
.box{
height:100px50px;/* Error: height only accepts one value */
}
</style>
<divclass="box">Content</div>
Incorrect: unrecognized value
<style>
.box{
height:100pixels;/* Error: "pixels" is not a valid unit */
}
</style>
<divclass="box">Content</div>
Incorrect: malformed calc() expression
<style>
.box{
height:calc(100%20px);/* Error: missing operator between values */
}
</style>
<divclass="box">Content</div>
Correct: single length value
<style>
.box{
height:100px;
}
</style>
<divclass="box">Content</div>
Correct: percentage value
<style>
.box{
height:50%;
}
</style>
<divclass="box">Content</div>
Correct: calc() with proper operator
<style>
.box{
height:calc(100%-20px);
}
</style>
<divclass="box">Content</div>
Correct: keyword value
<style>
.box{
height: auto;
}
</style>
<divclass="box">Content</div>
If you need to set both width and height, remember they are separate properties and must be declared individually. If you were trying to set a minimum and maximum height, use min-height and max-height as distinct declarations instead of combining values into a single height property.
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