HTML Guides for video
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 controlslist attribute was proposed to give developers a way to hint to the browser which default media controls to show or hide. It accepts values like nodownload, nofullscreen, and noremoteplayback, allowing you to selectively disable specific buttons in the browser’s built-in media player UI. For example, controlslist="nodownload" hides the download button on the video player.
However, this attribute was never adopted into the WHATWG HTML Living Standard or any W3C specification. It remains a Chromium-specific feature, meaning it only works in browsers like Chrome and Edge. Firefox, Safari, and other non-Chromium browsers simply ignore it. Because it’s not part of any standard, the W3C HTML Validator rightfully reports it as an invalid attribute.
While using controlslist won’t break your page — browsers that don’t recognize it will silently ignore it — relying on non-standard attributes has downsides:
- Standards compliance: Your HTML won’t validate, which can mask other real issues in validation reports.
- Browser compatibility: The behavior only works in Chromium-based browsers, giving an inconsistent experience across browsers.
- Future uncertainty: Non-standard attributes can be removed or changed without notice.
To fix this, you have a few options. The simplest is to remove the attribute entirely if the customization isn’t critical. If you need fine-grained control over media player buttons, the most robust approach is to build custom media controls using JavaScript and the HTMLMediaElement API. For the specific case of disabling remote playback, there is a standardized attribute — disableremoteplayback — that you can use instead.
Examples
❌ Invalid: Using the non-standard controlslist attribute
<video src="video.mp4" controls controlslist="nodownload nofullscreen"></video>
The validator will report: Attribute “controlslist” not allowed on element “video” at this point.
✅ Valid: Removing the attribute
<video src="video.mp4" controls></video>
The simplest fix is to remove controlslist and accept the browser’s default controls.
✅ Valid: Using custom controls with JavaScript
<video id="my-video" src="video.mp4"></video>
<div class="custom-controls">
<button id="play-btn">Play</button>
<input id="seek-bar" type="range" min="0" max="100" value="0">
<button id="fullscreen-btn">Fullscreen</button>
</div>
<script>
const video = document.getElementById("my-video");
document.getElementById("play-btn").addEventListener("click", () => {
video.paused ? video.play() : video.pause();
});
</script>
By omitting the controls attribute and building your own UI, you have full control over which buttons appear — across all browsers.
✅ Valid: Using disableremoteplayback for that specific need
<video src="video.mp4" controls disableremoteplayback></video>
If your goal was specifically controlslist="noremoteplayback", the standardized disableremoteplayback attribute achieves the same result and is valid HTML.
Audio element
The same issue and solutions apply to the <audio> element:
<!-- ❌ Invalid -->
<audio src="song.mp3" controls controlslist="nodownload"></audio>
<!-- ✅ Valid -->
<audio src="song.mp3" controls></audio>
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 attribute on <video> (and <img>, <canvas>, etc.) as a “valid non-negative integer,” which means it must consist only of digits like "640" or "1280". Values like "auto", "100%", or "50vw" are not permitted in the HTML attribute itself — these are CSS concepts, not valid HTML attribute values.
This matters for several reasons. First, browsers use the width and height HTML attributes to reserve the correct amount of space in the layout before the video loads, which prevents content layout shift (CLS). When the value is invalid, the browser may ignore it entirely, leading to layout jumps as the page loads. Second, invalid attributes can cause unpredictable rendering behavior across different browsers. Third, standards compliance ensures your markup is future-proof and works reliably with assistive technologies.
A common reason developers set width="auto" is to make the video responsive. The correct way to achieve this is through CSS rather than through the HTML attribute. You can still set width and height attributes with valid integers to define the video’s intrinsic aspect ratio (which helps the browser reserve space), and then override the display size with CSS.
How to Fix
- Replace "auto" with a valid integer that represents the desired pixel width.
- If you need responsive sizing, remove the width attribute or keep it for aspect ratio hinting, and use CSS to control the rendered size.
Examples
❌ Invalid: Using "auto" as the width attribute
<video width="auto" height="360" controls>
<source src="video.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
This triggers the error because "auto" is not a non-negative integer.
✅ Fixed: Specifying a valid pixel value
<video width="640" height="360" controls>
<source src="video.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
The width and height attributes use plain integers — no units, no keywords. The browser interprets these as pixels.
✅ Fixed: Responsive video using CSS
If you want the video to scale fluidly with its container, use CSS instead of the HTML attribute:
<style>
.responsive-video {
width: 100%;
height: auto;
}
</style>
<video class="responsive-video" controls>
<source src="video.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
In CSS, width: 100% and height: auto are perfectly valid and will make the video scale to fill its container while maintaining its aspect ratio.
✅ Best practice: Combine HTML attributes with CSS
For the best of both worlds — layout stability and responsive sizing — provide width and height attributes for aspect ratio hinting, then override with CSS:
<style>
.responsive-video {
max-width: 100%;
height: auto;
}
</style>
<video class="responsive-video" width="640" height="360" controls>
<source src="video.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Here, the width="640" and height="360" attributes tell the browser the video’s intrinsic 16:9 aspect ratio, so it can reserve the right amount of space before the video loads. The CSS max-width: 100% ensures the video never exceeds its container, and height: auto keeps the aspect ratio intact. This approach minimizes layout shift while remaining fully responsive.
An empty value for the poster attribute on a video element is not valid; the attribute must contain a non-empty URL.
The poster attribute specifies an image to show before the user plays the video. According to the HTML living standard and W3C specifications, if the poster attribute is present, it must have a non-empty value that is a valid URL to an image resource. Using poster="" is invalid and triggers validator errors.
If you do not want to show any poster image, simply omit the poster attribute altogether. If you want to show an image, provide a valid image URL as the value.
Valid examples:
Video without a poster (omit the attribute):
<video controls>
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Video with a poster image:
<video controls poster="thumbnail.jpg">
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Invalid (causes error):
<video controls poster="">
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Always either use a valid URL in the poster attribute or omit it entirely to ensure HTML validity.
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.
Spaces in the poster attribute value are not valid in URLs and must be percent-encoded as %20.
The poster attribute on the video element specifies an image to show until the user plays or seeks the video. Attribute values that represent URLs (such as in src, href, or poster) must use valid URI syntax, meaning spaces are not allowed. Spaces must be replaced with %20, or you can use a path that avoids spaces entirely.
Example — Incorrect:
<video controls poster="/img/video images/snapshot.png">
<source src="/videos/sample.mp4" type="video/mp4">
</video>
Example — Fixed with percent-encoding:
<video controls poster="/img/video%20images/snapshot.png">
<source src="/videos/sample.mp4" type="video/mp4">
</video>
Example — Fixed by removing spaces from the folder name:
<video controls poster="/img/video-images/snapshot.png">
<source src="/videos/sample.mp4" type="video/mp4">
</video>
Always encode any space in URLs as %20 or avoid spaces in file and folder names.
The HTML specification defines the width attribute on <video> as a “valid non-negative integer,” which means it must consist only of digits (e.g., 640). It cannot include units like px, em, or %. When you write something like width="100%", the validator expects a digit character but encounters the % sign, producing this error.
This is a common mistake because CSS allows percentage values for width, and some older HTML elements (like <table>) historically accepted percentage values in their width attributes. However, the <video> element follows the modern HTML specification, which restricts width to pixel integers only.
Why this matters
- Standards compliance: Browsers may interpret invalid attribute values unpredictably. While most modern browsers might ignore the % and attempt to parse the number, this behavior is not guaranteed.
- Responsive design intent is lost: Even if a browser tries to handle width="100%", it may treat it as width="100" (100 CSS pixels), which is almost certainly not what you intended.
- Accessibility and consistency: Valid markup ensures assistive technologies and all browsers render your content as expected.
How to fix it
If you need a fixed pixel width, set the width attribute to a plain integer. If you need a responsive or percentage-based width, remove the width attribute entirely and use CSS.
Examples
❌ Invalid: percentage value in the width attribute
<video controls width="100%">
<source src="/media/video.mp4" type="video/mp4">
</video>
✅ Fixed: using a pixel integer for a fixed width
<video controls width="640" height="360">
<source src="/media/video.mp4" type="video/mp4">
</video>
✅ Fixed: using CSS for a percentage-based width
<video controls style="width: 100%;">
<source src="/media/video.mp4" type="video/mp4">
</video>
✅ Fixed: using an external stylesheet for responsive video
<style>
.responsive-video {
width: 100%;
max-width: 800px;
height: auto;
}
</style>
<video controls class="responsive-video">
<source src="/media/video.mp4" type="video/mp4">
</video>
The CSS approach is generally preferred for responsive layouts because it gives you much more control — you can combine width, max-width, and height: auto to create a video that scales proportionally within its container. The width and height HTML attributes are best used when you want to specify the video’s intrinsic dimensions in pixels, which also helps the browser reserve the correct amount of space before the video loads, reducing layout shifts.
Ready to validate your sites?
Start your free trial today.