HTML Guides for height
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 <table> element in HTML supports a limited set of attributes — primarily global attributes like class, id, and style. The height attribute was never part of the HTML standard for tables (unlike width, which was valid in HTML 4 but has since been deprecated). Despite this, many browsers historically accepted height on <table> as a non-standard extension, which led to its widespread but incorrect use.
Because height is not a recognized attribute on <table>, using it means your markup is invalid and may behave inconsistently across browsers. Some browsers might honor it, others might ignore it entirely, and future browser versions could change their behavior at any time. Relying on non-standard attributes makes your code fragile and harder to maintain.
The fix is straightforward: remove the height attribute from the <table> element and use CSS to set the desired height. You can apply the CSS inline via the style attribute, or better yet, use an external or internal stylesheet with a class or ID selector.
Examples
❌ Invalid: height attribute on <table>
<table height="300">
<tr>
<td>Name</td>
<td>Score</td>
</tr>
<tr>
<td>Alice</td>
<td>95</td>
</tr>
</table>
This triggers the validator error: Attribute “height” not allowed on element “table” at this point.
✅ Fixed: Using inline CSS
<table style="height: 300px;">
<tr>
<td>Name</td>
<td>Score</td>
</tr>
<tr>
<td>Alice</td>
<td>95</td>
</tr>
</table>
✅ Fixed: Using a CSS class (preferred)
<style>
.tall-table {
height: 300px;
}
</style>
<table class="tall-table">
<tr>
<td>Name</td>
<td>Score</td>
</tr>
<tr>
<td>Alice</td>
<td>95</td>
</tr>
</table>
Using a class keeps your HTML clean and makes it easy to adjust the styling later without touching the markup. Note that min-height is often a better choice than height for tables, since table content can naturally grow beyond a fixed height, and min-height ensures the table is at least a certain size without clipping content.
The HTML specification defines the height attribute on <img> as a “valid non-negative integer,” which means it must consist only of digits — no units, no percentage signs. When you write height="100%", the validator expects a digit character but encounters %, producing this error. The same rule applies to the width attribute.
This matters for several reasons. First, browsers use the width and height attributes to reserve the correct amount of space for an image before it loads, which prevents layout shifts (a key performance metric known as Cumulative Layout Shift). When the value contains invalid characters like %, browsers may ignore the attribute entirely or interpret it unpredictably, undermining this layout reservation. Second, invalid HTML can cause inconsistent rendering across different browsers and assistive technologies. Third, the percentage-based sizing you likely intended simply isn’t supported through HTML attributes — it requires CSS.
The fix depends on what you’re trying to achieve:
- Fixed dimensions: Replace the percentage with a plain integer representing the image’s intrinsic or desired pixel size (e.g., height="300").
- Responsive or percentage-based sizing: Remove the height attribute (or set it to the image’s intrinsic pixel dimensions) and use CSS to control how the image scales within its container.
It’s a good practice to always include both width and height attributes with the image’s actual intrinsic dimensions, then use CSS to override the display size. This gives browsers the aspect ratio information they need to reserve space while still allowing flexible layouts.
Examples
Incorrect: percentage value in the height attribute
This triggers the validation error because % is not a valid digit:
<img src="photo.jpg" width="100%" height="100%" alt="A landscape photo">
Fixed: using integer pixel values
Specify the image’s intrinsic dimensions as plain numbers:
<img src="photo.jpg" width="800" height="600" alt="A landscape photo">
Fixed: combining HTML attributes with CSS for responsive sizing
Set the intrinsic dimensions in HTML for layout stability, then use CSS to make the image responsive:
<style>
.responsive-img {
width: 100%;
height: auto;
}
</style>
<img
src="photo.jpg"
width="800"
height="600"
class="responsive-img"
alt="A landscape photo">
With this approach, the browser knows the image’s aspect ratio (800×600) and reserves the appropriate space, while CSS ensures the image scales fluidly to fill its container. The height: auto rule maintains the correct aspect ratio as the width changes.
Fixed: filling a container with CSS only
If you don’t know the image’s intrinsic dimensions and simply want it to fill a container, you can omit the HTML attributes and rely entirely on CSS:
<style>
.image-container {
width: 300px;
height: 200px;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
<div class="image-container">
<img src="photo.jpg" alt="A landscape photo">
</div>
The object-fit: cover property ensures the image fills the container without distortion, cropping as needed. Note that omitting width and height attributes means the browser cannot reserve space before the image loads, so this approach may cause layout shifts. Where possible, prefer including the intrinsic dimensions as shown in the previous example.
The HTML specification defines the height attribute on media elements like <video> as accepting only a valid non-negative integer. This means the attribute value must consist solely of digits (e.g., "360"), with no units, keywords, or other characters. When you write height="auto", the validator expects to find a digit as the first character but encounters the letter "a", which produces the error.
The value "auto" is a valid concept in CSS, where height: auto tells the browser to calculate the element’s height automatically based on its intrinsic aspect ratio or content. However, HTML attributes and CSS properties follow different rules. The height HTML attribute is a simple pixel dimension hint — it doesn’t understand CSS keywords. Mixing CSS values into HTML attributes is a common mistake, and while browsers may silently ignore the invalid value, it leads to unpredictable behavior: the video may render without any height hint, potentially causing layout shifts as the browser discovers the video’s actual dimensions during loading.
Providing a valid height attribute matters for layout stability. When the browser knows the video’s dimensions before the media loads, it can reserve the correct amount of space in the page layout, preventing content from jumping around. This improves the user experience and contributes to better Core Web Vitals scores (specifically Cumulative Layout Shift). It also ensures your HTML is standards-compliant and accessible to assistive technologies that may rely on well-formed markup.
How to Fix
You have two approaches:
- Use a numeric value — Replace "auto" with an integer that represents the video’s height in pixels.
- Use CSS instead — Remove the height attribute from the HTML and apply height: auto (or any other value) via CSS. This is ideal when you want the video to scale responsively.
If you want the video to maintain its aspect ratio while scaling, the CSS approach is generally preferred for responsive designs. You can combine a width attribute (or CSS width) with CSS height: auto to let the browser calculate the correct height from the video’s intrinsic aspect ratio.
Examples
❌ Invalid: Using “auto” in the HTML attribute
<video width="640" height="auto" controls>
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
This triggers the validation error because "auto" is not a non-negative integer.
✅ Fixed: Using a numeric height value
<video width="640" height="360" controls>
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
The height attribute is now a valid integer. The browser reserves a 640×360 pixel area for the video before it loads.
✅ Fixed: Using CSS for responsive sizing
<video width="640" controls style="height: auto; max-width: 100%;">
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Here the height HTML attribute is removed entirely. CSS height: auto ensures the video scales proportionally, and max-width: 100% prevents it from overflowing its container. This is a common pattern for responsive video.
✅ Fixed: Using both attributes with CSS override
<video width="640" height="360" controls style="width: 100%; height: auto;">
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
This approach provides the best of both worlds: the width and height HTML attributes give the browser an aspect ratio hint (preventing layout shifts), while the CSS makes the video responsive. Modern browsers use the attribute values to calculate the correct aspect ratio even when CSS overrides the actual rendered size.
The HTML specification defines the width and height attributes on <img> as accepting only valid non-negative integers — a sequence of one or more digits (0–9) with no letters, units, or symbols. These attributes tell the browser the intrinsic dimensions of the image in pixels, which helps it allocate the correct space in the layout before the image loads, preventing content layout shift (CLS).
When you set height="auto" or width="50%", the validator expects a digit as the first character but instead encounters a letter or symbol, producing the error: “Bad value ‘auto’ for attribute ‘height’ on element ‘img’: Expected a digit but saw ‘a’ instead.”
This matters for several reasons:
- Standards compliance: Browsers may silently ignore invalid attribute values, meaning your intended sizing won’t take effect and you’ll get default behavior without any visible warning to users.
- Layout stability: Valid width and height attributes allow the browser to calculate the image’s aspect ratio before it loads, reserving the correct amount of space and preventing layout shifts. Invalid values defeat this mechanism.
- Predictability: Relying on browser error recovery for invalid markup leads to inconsistent behavior across different browsers and versions.
To fix this, you have two options:
- Use plain integers in the width and height attributes to specify pixel dimensions (e.g., width="600" height="400").
- Use CSS for any non-pixel or dynamic sizing like auto, percentages, max-width, viewport units, etc.
A best practice is to set the width and height attributes to the image’s actual intrinsic pixel dimensions (to preserve aspect ratio and prevent layout shift), then use CSS to control the rendered size responsively.
Examples
Invalid: using “auto” or units in attributes
<!-- "auto" is not a valid integer -->
<img src="photo.jpg" alt="A cat sitting on a windowsill" height="auto" width="auto">
<!-- Percentage is not a valid integer -->
<img src="banner.jpg" alt="Site banner" width="100%">
<!-- Units like "px" are not allowed -->
<img src="icon.png" alt="Settings icon" width="32px" height="32px">
Valid: using plain integers in attributes
<!-- Correct: plain integers representing pixels -->
<img src="photo.jpg" alt="A cat sitting on a windowsill" width="800" height="600">
<img src="icon.png" alt="Settings icon" width="32" height="32">
Valid: using CSS for responsive or dynamic sizing
When you need behavior like auto, percentages, or max-width, use CSS instead:
<!-- Use attributes for intrinsic size, CSS for responsive behavior -->
<img
src="photo.jpg"
alt="A cat sitting on a windowsill"
width="800"
height="600"
style="max-width: 100%; height: auto;">
This approach gives you the best of both worlds: the browser knows the image’s aspect ratio from the attributes (preventing layout shift), while CSS ensures it scales responsively within its container.
Valid: using a CSS class for reusability
<style>
.responsive-img {
max-width: 100%;
height: auto;
}
</style>
<img
src="photo.jpg"
alt="A cat sitting on a windowsill"
width="800"
height="600"
class="responsive-img">
The HTML specification defines that the width and height attributes on <iframe> elements must contain a valid non-negative integer — that is, a string of one or more digits representing a number zero or greater (e.g., "0", "300", "600"). When one of these attributes is set to an empty string (width="" or height=""), the validator raises this error because an empty string cannot be parsed as a valid integer.
This commonly happens when a CMS, template engine, or JavaScript framework outputs an <iframe> with a dynamic dimension value that ends up being blank. It can also occur when developers remove the value but leave the attribute in place, or when copy-pasting embed code and accidentally clearing the value.
While most browsers will fall back to their default iframe dimensions (typically 300×150 pixels) when they encounter an empty value, relying on this behavior is not standards-compliant. Invalid attribute values can cause unpredictable rendering across different browsers, interfere with layout calculations, and make your markup harder to maintain. Assistive technologies may also have trouble determining the intended dimensions of the iframe.
How to fix it
You have a few options:
- Set a valid integer value. If you know the desired dimensions, specify them directly as non-negative integers. The values represent pixels.
- Remove the attribute entirely. If you don’t need to set dimensions via HTML attributes, remove the empty width or height attribute. The browser will apply its default size, or you can control sizing with CSS.
- Use CSS instead. For responsive designs or more flexible sizing, remove the HTML attributes and use CSS properties like width, height, max-width, or aspect-ratio.
Note that these attributes accept only plain integers — no units, no percentages, and no decimal points. For example, width="600" is valid, but width="600px" or width="100%" is not.
Examples
❌ Invalid: empty string values
<iframe src="https://example.com" width="" height=""></iframe>
Both width and height are set to empty strings, which are not valid non-negative integers.
✅ Fixed: specify valid integer values
<iframe src="https://example.com" width="600" height="400"></iframe>
✅ Fixed: remove the empty attributes
<iframe src="https://example.com"></iframe>
The browser will use its default dimensions (typically 300×150 pixels).
✅ Fixed: remove attributes and use CSS for sizing
<iframe src="https://example.com" style="width: 100%; height: 400px;"></iframe>
This approach is especially useful for responsive layouts where a fixed pixel width in HTML doesn’t make sense.
✅ Fixed: responsive iframe with CSS aspect ratio
<iframe
src="https://example.com/video"
style="width: 100%; aspect-ratio: 16 / 9; border: none;">
</iframe>
Using aspect-ratio in CSS lets the iframe scale responsively while maintaining its proportions, without needing width or height attributes at all.
The HTML specification requires that the width and height attributes on <img> elements, when present, contain a string representing a non-negative integer — that is, a sequence of one or more ASCII digits like "0", "150", or "1920". An empty string ("") does not satisfy this requirement, so the W3C validator flags it as an error.
This issue commonly arises when:
- A CMS or templating engine outputs width="" or height="" because no dimension value was configured.
- JavaScript dynamically sets img.setAttribute("width", "") instead of removing the attribute.
- A developer adds the attributes as placeholders intending to fill them in later but forgets to do so.
Why it matters
Providing valid width and height attributes is one of the most effective ways to prevent Cumulative Layout Shift (CLS). Browsers use these values to calculate the image’s aspect ratio and reserve the correct amount of space before the image loads. When the values are empty strings, the browser cannot determine the aspect ratio, so no space is reserved — leading to layout shifts as images load in, which hurts both user experience and Core Web Vitals scores.
Beyond performance, invalid attribute values can cause unpredictable rendering behavior across browsers. Some browsers may ignore the attribute, others may interpret the empty string as 0, collapsing the image to zero pixels in that dimension. Standards-compliant HTML also improves accessibility by ensuring assistive technologies can parse the document reliably.
Examples
❌ Invalid: empty string values
<img src="photo.jpg" alt="A sunset over the ocean" width="" height="">
Both width and height are set to empty strings, which is not valid.
✅ Fixed: provide actual dimensions
<img src="photo.jpg" alt="A sunset over the ocean" width="800" height="600">
Replace the empty strings with the image’s actual pixel dimensions. These values should reflect the image’s intrinsic (natural) size. CSS can still be used to scale the image visually — the browser will use the width and height ratio to reserve the correct space.
✅ Fixed: remove the attributes entirely
<img src="photo.jpg" alt="A sunset over the ocean">
If you don’t know the dimensions or prefer to handle sizing purely through CSS, remove the attributes altogether. An absent attribute is valid; an empty one is not.
❌ Invalid: only one attribute is empty
<img src="banner.jpg" alt="Promotional banner" width="1200" height="">
Even if only one attribute has an empty value, the validation error will be triggered for that attribute.
✅ Fixed: both attributes with valid values
<img src="banner.jpg" alt="Promotional banner" width="1200" height="400">
Fixing dynamic/template-generated markup
If a template language is outputting empty attributes, use a conditional to omit them when no value is available. For example, in a template:
<!-- Instead of always outputting the attributes: -->
<img src="photo.jpg" alt="Description" width="" height="">
<!-- Conditionally include them only when values exist: -->
<img src="photo.jpg" alt="Description" width="800" height="600">
If you’re setting dimensions via JavaScript, remove the attribute rather than setting it to an empty string:
// ❌ Don't do this
img.setAttribute("width", "");
// ✅ Do this instead
img.removeAttribute("width");
// ✅ Or set a valid value
img.setAttribute("width", "800");
A note on values
The width and height attributes only accept non-negative integers — whole numbers without units, decimals, or percentage signs. Values like "100px", "50%", or "3.5" are also invalid. Use plain integers like "100" or "600". If you need responsive sizing with percentages or other CSS units, apply those through CSS styles instead.
Remove the unit; height on embed expects a non-negative integer (pixels) or a valid CSS length only when set via CSS, not the HTML attribute.
Detailed explanation
The embed element supports the presentational attributes width and height as unsigned integers representing CSS pixels. In HTML, the height attribute must be a number without a unit, for example 650. Supplying 650px violates the attribute’s value syntax and triggers the validator error.
If you want to use units or other CSS lengths (e.g., px, em, %, vh), set them with CSS via the style attribute or a stylesheet using the height property, not the HTML attribute.
HTML examples
Example reproducing the issue
<!DOCTYPE html>
<html lang="en">
<head>
<title>Embed height invalid</title>
</head>
<body>
<embed src="file.pdf" type="application/pdf" width="800" height="650px">
</body>
</html>
Corrected example (HTML attribute as integer)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Embed height fixed</title>
</head>
<body>
<embed src="file.pdf" type="application/pdf" width="800" height="650">
</body>
</html>
Alternative corrected example (use CSS units)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Embed height via CSS</title>
<style>
.viewer { width: 800px; height: 650px; }
</style>
</head>
<body>
<embed class="viewer" src="file.pdf" type="application/pdf">
</body>
</html>
The height attribute on <iframe> is defined in the HTML specification as a “valid non-negative integer.” This means the value must be a string of one or more digit characters (0 through 9) and nothing else. Unlike CSS properties, this attribute does not accept units like px or %, nor does it accept decimal values like 315.5. Even invisible characters such as leading or trailing spaces will trigger this validation error because the parser expects a digit and encounters something else.
This matters for several reasons. While browsers are generally forgiving and may still render the iframe correctly despite an invalid value, relying on error recovery behavior is fragile and may not work consistently across all browsers or future versions. Invalid attribute values can also cause unexpected results in automated tools, screen readers, and other user agents that parse HTML strictly. Writing valid, standards-compliant markup ensures predictable behavior everywhere.
Common causes of this error include:
- Adding CSS units to the attribute value (e.g., height="315px")
- Using percentages (e.g., height="100%")
- Decimal values (e.g., height="315.5")
- Whitespace before or after the number (e.g., height=" 315" or height="315 ")
- Copy-paste artifacts introducing hidden characters
If you need percentage-based or decimal sizing, use CSS instead of the HTML attribute. The height attribute only accepts whole pixel values.
Examples
❌ Invalid: Using px unit in the attribute
<iframe width="560" height="315px" src="https://example.com/video"></iframe>
The validator sees the p character after 315 and reports the error.
❌ Invalid: Using a percentage
<iframe width="100%" height="100%" src="https://example.com/video"></iframe>
Percentage values are not allowed in the height attribute.
❌ Invalid: Decimal value
<iframe width="560" height="315.5" src="https://example.com/video"></iframe>
The decimal point is not a digit, so the validator rejects it.
❌ Invalid: Leading or trailing whitespace
<iframe width="560" height=" 315 " src="https://example.com/video"></iframe>
The space before 315 is encountered where a digit is expected.
✅ Valid: Digits only
<iframe width="560" height="315" src="https://example.com/video"></iframe>
The value 315 contains only digits and is a valid non-negative integer.
✅ Valid: Using CSS for percentage-based sizing
If you need the iframe to scale responsively, remove the height attribute and use CSS instead:
<iframe
width="560"
height="315"
src="https://example.com/video"
style="width: 100%; height: 100%;"
></iframe>
Or better yet, apply styles through a stylesheet:
<style>
.responsive-iframe {
width: 100%;
height: 400px;
}
</style>
<iframe class="responsive-iframe" src="https://example.com/video"></iframe>
This keeps the HTML attributes valid while giving you full control over sizing through CSS, including support for units like %, vh, em, and calc().
The height attribute on <video> is defined in the HTML specification as a “valid non-negative integer.” This means it must be a string of digits (e.g., "480") with no units, no decimal points, and no percentage signs. When you write something like height="50%", the W3C validator rejects it because % is not a digit character and percentage values are not part of the attribute’s allowed syntax.
This same rule applies to the width attribute on <video>, as well as the width and height attributes on <img>, <canvas>, and other elements that accept pixel dimensions. The integer you provide represents a size in CSS pixels, so height="480" means 480 CSS pixels — no unit suffix is needed or allowed.
Why this matters
- Standards compliance: The HTML living standard explicitly defines these attributes as non-negative integers. Using percentages violates the spec and produces a validation error.
- Browser behavior: While some browsers may attempt to interpret a percentage value, the behavior is undefined and inconsistent. You cannot rely on it working correctly across all browsers and versions.
- Layout stability: Providing valid width and height integer values helps browsers reserve the correct aspect ratio for the video before it loads, reducing cumulative layout shift (CLS). Invalid values undermine this benefit.
How to fix it
- Replace the percentage value with a plain integer representing the desired pixel height.
- If you need percentage-based or responsive sizing, remove the percentage from the HTML attribute and use CSS instead. CSS width and height properties fully support percentage values, viewport units, and other flexible sizing methods.
- Always keep integer width and height attributes on the element when possible, even if you also use CSS for responsive sizing. This provides an intrinsic aspect ratio hint to the browser.
Examples
❌ Invalid: percentage value in the height attribute
<video controls width="100%" height="50%">
<source src="/media/video.webm" type="video/webm">
</video>
The validator reports: Bad value “50%” for attribute “height” on element “video”: Expected a digit but saw “%” instead. The same error applies to the width="100%" attribute.
✅ Fixed: integer values for intrinsic dimensions
<video controls width="640" height="480">
<source src="/media/video.webm" type="video/webm">
</video>
Both width and height use plain integers representing CSS pixels. This is valid and gives the browser an aspect ratio hint (4:3 in this case).
✅ Fixed: responsive sizing with CSS
If you need the video to scale as a percentage of its container, use CSS for the sizing while keeping valid integer attributes for the aspect ratio:
<video controls width="640" height="360" style="width: 100%; height: auto;">
<source src="/media/video.webm" type="video/webm">
</video>
Here, width="640" and height="360" tell the browser the video’s intrinsic aspect ratio (16:9), while the inline style (or an external stylesheet) makes the video fill 100% of its container width and scale its height proportionally. This approach is both valid HTML and fully responsive.
✅ Fixed: using a CSS class for responsive video
<style>
.responsive-video {
width: 100%;
max-width: 800px;
height: auto;
}
</style>
<video controls width="800" height="450" class="responsive-video">
<source src="/media/video.webm" type="video/webm">
</video>
This keeps the HTML valid, provides an aspect ratio hint, and achieves flexible, percentage-based sizing entirely through CSS.
According to the HTML specification, the width and height attributes on <iframe> elements accept only a valid non-negative integer — a string of one or more ASCII digits (0–9) with no decimal points, spaces, or unit suffixes like px. This is different from CSS, where properties like width and height accept decimal values and units. The HTML attributes represent dimensions in CSS pixels implicitly, so only bare whole numbers are allowed.
When the W3C validator reports “Expected a digit but saw ‘.’ instead”, it means it was parsing the attribute value character by character and encountered a period (.) where only digits are valid. This typically happens when authors copy computed or fractional values from design tools, JavaScript calculations, or CSS into HTML attributes.
Why this matters
- Standards compliance: Browsers may handle invalid attribute values inconsistently. While most modern browsers will parse and truncate decimal values gracefully, the behavior is not guaranteed and falls outside the specification.
- Predictable rendering: Relying on how browsers handle malformed values can lead to subtle differences across browser engines. Using valid integers ensures consistent behavior everywhere.
- Code quality: Clean, valid markup is easier to maintain and signals professionalism, which matters especially for shared codebases and collaborative projects.
How to fix it
- Round the value to the nearest whole number. Use standard rounding rules: round up if the decimal portion is .5 or greater, round down otherwise.
- Remove any decimal point and trailing digits from the attribute value.
- If you need precise, fractional dimensions, use CSS instead of HTML attributes. CSS width and height properties accept decimal values with units (e.g., 602.88px).
Examples
❌ Invalid: decimal values in width and height
<iframe src="example.html" height="602.88" width="800.2"></iframe>
The validator will flag both attributes because 602.88 and 800.2 contain a . character.
✅ Fixed: whole number values
<iframe src="example.html" height="603" width="800"></iframe>
The decimal values have been rounded to the nearest integer: 602.88 becomes 603, and 800.2 becomes 800.
✅ Alternative: use CSS for precise dimensions
If you need exact fractional dimensions, move the sizing to CSS and remove the HTML attributes entirely:
<iframe src="example.html" style="height: 602.88px; width: 800.2px;"></iframe>
Or, better yet, use an external stylesheet:
<iframe src="example.html" class="content-frame"></iframe>
.content-frame {
width: 800.2px;
height: 602.88px;
}
❌ Invalid: other non-digit characters
This error can also appear if you include units in the attribute value:
<iframe src="example.html" width="800px" height="600px"></iframe>
✅ Fixed: remove the units
<iframe src="example.html" width="800" height="600"></iframe>
The same rule applies to the <img>, <video>, <canvas>, and other elements that accept width and height as HTML attributes — they all expect valid non-negative integers without decimals or units.
According to the HTML specification, the width and height attributes on img elements accept only valid non-negative integers. A valid non-negative integer consists of one or more ASCII digits (0–9) with no other characters — no decimal points, no spaces, no units like px. When the validator encounters a value such as 602.88, it parses the digits 602 successfully, then hits the . character where it expects another digit or the end of the value, triggering the error.
This issue commonly arises when dimension values are generated programmatically — for example, when a CMS, image processing tool, or JavaScript calculation produces floating-point numbers and outputs them directly into the HTML. It can also happen when copying dimension values from CSS or design tools that work in sub-pixel units.
Why this matters
- Standards compliance: The HTML specification is explicit that these attributes take integer values. Using decimals produces invalid markup.
- Unpredictable rendering: Browsers may handle the malformed value in different ways — some might truncate at the decimal point, others might ignore the attribute entirely. This can lead to layout shifts or incorrectly sized images.
- Layout stability: The width and height attributes are used by browsers to calculate the aspect ratio of an image before it loads, which helps prevent Cumulative Layout Shift (CLS). Invalid values can undermine this behavior, causing content to jump around as images load.
How to fix it
- Round to the nearest integer. If your value is 602.88, round it to 603. If it’s 800.2, round to 800.
- Remove the decimal point entirely. The value must contain only digits.
- Do not include units. Values like 800px are also invalid; use just 800.
- Fix the source of the values. If your CMS or build tool generates these attributes, update the logic to output integers (e.g., using Math.round() in JavaScript or round() in PHP/Python).
Examples
❌ Incorrect: decimal values in width and height
<img src="photo.jpg" alt="A golden retriever" height="602.88" width="800.2">
The validator reports errors for both attributes because . is not a valid character in a non-negative integer.
✅ Correct: whole number values
<img src="photo.jpg" alt="A golden retriever" height="603" width="800">
Both values are valid non-negative integers with no decimal points.
❌ Incorrect: trailing decimal point with no fractional part
<img src="banner.png" alt="Sale banner" width="1200." height="400.">
Even a trailing . with nothing after it is invalid — the parser still encounters an unexpected character.
✅ Correct: clean integer values
<img src="banner.png" alt="Sale banner" width="1200" height="400">
Using CSS for sub-pixel precision
If you genuinely need sub-pixel sizing (which is rare for images), use CSS instead of HTML attributes. CSS width and height properties do accept decimal values:
<img src="icon.svg" alt="Settings icon" style="width: 24.5px; height: 24.5px;">
However, keep in mind that you should still provide integer width and height HTML attributes for aspect ratio hinting, and then override with CSS if sub-pixel precision is needed:
<img
src="icon.svg"
alt="Settings icon"
width="25"
height="25"
style="width: 24.5px; height: 24.5px;">
This approach gives you valid HTML, proper aspect ratio hints for layout stability, and the precise sizing you need.
Attribute values for width and height on the object element must be a valid integer (pixels), not a percentage.
In HTML5, the width and height attributes for the <object> element must be specified in pixels as an integer value, such as height="500". Using percentage values like height="100%" is not allowed in the attribute according to the HTML living standard and will trigger a validation error. To set a percentage height, use the CSS width and height properties instead.
Correct usage (pixels via attribute):
<object data="example.pdf" type="application/pdf" width="600" height="400"></object>
Correct usage (percentage via CSS):
<object data="example.pdf" type="application/pdf" style="width: 100%; height: 100%;"></object>
Example of a full valid HTML document using CSS for 100% height:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Object Height Example</title>
<style>
html, body {
height: 100%;
margin: 0;
}
object {
height: 100%;
width: 100%;
display: block;
}
</style>
</head>
<body>
<object data="example.pdf" type="application/pdf"></object>
</body>
</html>
In HTML, the width and height attributes on elements like <img> and <iframe> are defined as accepting only valid non-negative integers. According to the HTML specification, the value is implicitly in CSS pixels, so appending px or any other unit is both unnecessary and invalid. The parser expects every character in the value to be a digit (0–9), and when it encounters a letter like p, it reports the error.
This is a common mistake, especially for developers who frequently work with CSS, where px units are required. In HTML attributes, however, the convention is different — the pixel unit is implied, and adding it creates a malformed value. Browsers may still attempt to parse the number by ignoring the trailing characters, but this behavior is not guaranteed and should not be relied upon.
Getting these attributes right matters for several reasons:
- Standards compliance ensures your markup is predictable and portable across all browsers and user agents.
- Layout stability depends on the browser correctly reading width and height to reserve space for images and iframes before they load, preventing cumulative layout shift (CLS). A malformed value could cause the browser to fall back to default sizing or ignore the attribute entirely.
- Accessibility tools and screen readers may use these attributes to convey information about embedded content, and invalid values could interfere with that process.
If you need to set dimensions using units other than pixels (such as percentages or viewport units), use CSS instead of HTML attributes.
Examples
❌ Invalid: using px in the attribute value
<img src="cat.jpg" alt="A cat sitting on a windowsill" width="225px" height="100px">
The validator reports an error because 225px and 100px contain the non-digit characters px.
✅ Valid: plain integers without units
<img src="cat.jpg" alt="A cat sitting on a windowsill" width="225" height="100">
❌ Invalid: using percentage in the attribute value
<iframe src="embed.html" width="100%" height="400px" title="Embedded content"></iframe>
Both 100% and 400px are invalid because they contain non-digit characters.
✅ Valid: plain integers on an <iframe>
<iframe src="embed.html" width="800" height="400" title="Embedded content"></iframe>
✅ Using CSS when you need non-pixel units
If you need percentage-based or responsive sizing, apply it through CSS rather than HTML attributes:
<iframe src="embed.html" style="width: 100%; height: 400px;" title="Embedded content"></iframe>
Or better yet, use an external stylesheet:
<style>
.responsive-frame {
width: 100%;
height: 400px;
}
</style>
<iframe src="embed.html" class="responsive-frame" title="Embedded content"></iframe>
Quick reference of invalid vs. valid values
| Invalid value | Problem | Valid alternative |
|---|---|---|
| 225px | Contains px | 225 |
| 100% | Contains % | Use CSS instead |
| 20em | Contains em | Use CSS instead |
| auto | Not a number | Use CSS instead |
| 10.5 | Decimal point | 10 or 11 |
The fix is straightforward: strip any unit suffixes from width and height HTML attributes and provide plain integer values. For anything beyond simple pixel dimensions, move your sizing logic to CSS.
The height CSS property defines the height of an element’s content area. According to CSS specifications, it accepts several value types: length values (like px, em, rem, vh, cm), percentages (%), and keywords such as auto, min-content, max-content, and fit-content. When the validator encounters a value that doesn’t belong to any of these accepted types, it reports a type incompatibility error.
This error commonly occurs in a few scenarios:
- Missing units on numeric values. In CSS, a bare number like 100 is not a valid length. The only exception is 0, which doesn’t require a unit because zero is the same in any unit system. Writing height: 100; instead of height: 100px; is invalid CSS.
- Unrecognized keywords. Using a word that isn’t a valid CSS keyword for height, such as big, small, or full, will trigger this error. These are not part of the CSS specification for the height property.
- Values from the wrong property. Sometimes values valid for other properties get mistakenly used with height. For example, height: bold; or height: block; are type mismatches because those keywords belong to font-weight and display, respectively.
- Typos or syntax errors. A stray character, misspelled unit (e.g., 100xp instead of 100px), or malformed calc() expression can also cause this error.
While modern browsers often try to recover from invalid CSS by ignoring the offending declaration, this means the height rule silently has no effect, which can lead to unexpected layout behavior. Writing valid CSS ensures your styles work predictably across all browsers and avoids hard-to-debug rendering issues.
How to Fix It
- Add a valid unit to any bare numeric value. Use px, em, rem, vh, %, or another valid CSS length unit.
- Use only recognized keywords for height: auto, min-content, max-content, fit-content, or fit-content(<length>).
- Check for typos in both the value and the unit.
- Validate calc() expressions to ensure the types inside are compatible (e.g., you can’t add a length and a color).
Examples
Incorrect: Missing unit on a numeric value
<style>
.box {
height: 100; /* invalid — no unit specified */
}
</style>
Incorrect: Unrecognized keyword
<style>
.box {
height: big; /* invalid — "big" is not a CSS keyword for height */
}
</style>
Incorrect: Misspelled unit
<style>
.box {
height: 250xp; /* invalid — "xp" is not a recognized unit */
}
</style>
Correct: Valid length values, percentages, and keywords
<style>
.fixed {
height: 200px;
}
.relative {
height: 70%;
}
.viewport {
height: 100vh;
}
.flexible {
height: auto;
}
.zero {
height: 0;
}
.intrinsic {
height: min-content;
}
.calculated {
height: calc(100vh - 60px);
}
</style>
Correct: Using height in context
<div style="height: 300px;">
<p style="height: 50%;">
This paragraph is 150px tall because its parent has a defined height.
</p>
</div>
Keep in mind that percentage-based height values only work when the parent element has a defined height. If the parent’s height is auto, a child with height: 50% will behave as if it were set to auto as well. When in doubt, use an absolute length like px or a viewport unit like vh, or set height: auto to let the content determine the element’s size.
The W3C validator checks inline styles and embedded stylesheets for valid CSS. When it encounters a height declaration with multiple values or an unrecognized value, it flags the error because height is not a shorthand property — it only accepts one value at a time. This differs from properties like margin or padding, which accept multiple values to target different sides of an element.
This error commonly occurs when you:
- Accidentally provide two values, perhaps confusing height with a shorthand property (e.g., height: 100px 50px;).
- Include a typo or invalid unit (e.g., height: 100ppx; or height: 100pixels;).
- Use a CSS function incorrectly (e.g., height: calc(100% 20px); — missing the operator).
- Copy a value meant for another property, such as pasting a grid-template-rows value into height.
Browsers may silently ignore invalid height declarations, causing your element to fall back to its default sizing (auto). This can lead to unexpected layout behavior that’s difficult to debug. Keeping your CSS valid ensures consistent rendering across browsers and helps catch mistakes early.
Valid values for height
The height property accepts exactly one of the following:
- Length values: 100px, 10em, 5rem, 20vh, etc.
- Percentage values: 50%, 100%
- Keyword values: auto, max-content, min-content, fit-content(200px)
- Global values: inherit, initial, revert, unset
- Calc expressions: calc(100% - 20px), calc(50vh + 2rem)
Examples
Incorrect: too many values
<style>
.box {
height: 100px 50px; /* Error: height only accepts one value */
}
</style>
<div class="box">Content</div>
Incorrect: unrecognized value
<style>
.box {
height: 100pixels; /* Error: "pixels" is not a valid unit */
}
</style>
<div class="box">Content</div>
Incorrect: malformed calc() expression
<style>
.box {
height: calc(100% 20px); /* Error: missing operator between values */
}
</style>
<div class="box">Content</div>
Correct: single length value
<style>
.box {
height: 100px;
}
</style>
<div class="box">Content</div>
Correct: percentage value
<style>
.box {
height: 50%;
}
</style>
<div class="box">Content</div>
Correct: calc() with proper operator
<style>
.box {
height: calc(100% - 20px);
}
</style>
<div class="box">Content</div>
Correct: keyword value
<style>
.box {
height: auto;
}
</style>
<div class="box">Content</div>
If you need to set both width and height, remember they are separate properties and must be declared individually. If you were trying to set a minimum and maximum height, use min-height and max-height as distinct declarations instead of combining values into a single height property.
Ready to validate your sites?
Start your free trial today.