HTML Guide
A <source>
element inside a <picture>
that is followed by another <source>
or an <img>
with srcset
must include a media
and/or type
attribute.
The <source>
element is used inside <picture>
for responsive images, allowing different resources to be loaded based on conditions such as viewport width (media
) or image format (type
). According to the HTML standard, when multiple <source>
elements are present (or a following <img>
with srcset
), each <source>
must provide a media
and/or type
attribute so the browser can choose the appropriate resource based on those hints.
Without media
or type
, the browser cannot distinguish when to use each source, which can lead to validation errors and unexpected rendering behavior.
Incorrect example (causes the validator error):
<picture>
<source srcset="image1.webp">
<source srcset="image2.jpg">
<img alt="" src="fallback.jpg" srcset="fallback2x.jpg 2x">
</picture>
Correct examples (fixing the error):
<picture>
<source srcset="image1.webp" type="image/webp">
<source srcset="image2.jpg" type="image/jpeg">
<img alt="" src="fallback.jpg" srcset="fallback2x.jpg 2x">
</picture>
or
<picture>
<source srcset="image-small.jpg" media="(max-width: 600px)">
<source srcset="image-large.jpg" media="(min-width: 601px)">
<img alt="" src="fallback.jpg" srcset="fallback2x.jpg 2x">
</picture>
By specifying the media
and/or type
attributes for each <source>
, you satisfy the HTML standard and resolve the W3C validator issue.
Learn more:
Related W3C validator issues
All values in the srcset attribute must include a width descriptor (such as 300w) when the sizes attribute is present.
The srcset attribute is used to provide multiple image sources for responsive images. Each image candidate string in srcset must specify the image’s width (e.g., 600w) or pixel density (e.g., 2x). When you use a sizes attribute, all srcset candidates must use width descriptors (w).
Example of incorrect usage:
<img
src="/img/pic1.jpg"
srcset="/img/pic1.jpg"
sizes="(max-width: 600px) 100vw, 600px"
alt=""
>
This example is invalid because the srcset value does not include a width descriptor.
Corrected usage with width descriptors:
<img
src="/img/pic1.jpg"
srcset="/img/pic1.jpg 600w"
sizes="(max-width: 600px) 100vw, 600px"
alt=""
>
If you have multiple image sizes, include each with its corresponding width:
<img
src="/img/pic1.jpg"
srcset="
/img/pic1_small.jpg 300w,
/img/pic1.jpg 600w
"
sizes="(max-width: 600px) 100vw, 600px"
alt=""
>
Always match each image URL in srcset with a width (w) or pixel density (x) descriptor if appropriate for your layout.
The srcset property on img elements, when used, requires at least one value. This property is a string which identifies one or more image candidate strings, separated using commas (,) each specifying image resources to use under given circumstances.
Each image candidate string contains an image URL and an optional width or pixel density descriptor that indicates the conditions under which that candidate should be used instead of the image specified by the src property.
Example:
<img
src="/img/cat-200px.png"
alt="Cat"
srcset="
/img/cat-200px.png 1x,
/img/cat-400px.png 2x
">
The srcset attribute requires a width descriptor (w) or pixel density descriptor (x) for each image candidate when the sizes attribute is present.
When using the sizes attribute on an img element, each entry in srcset must include either a width descriptor (e.g., 860w) or a pixel density descriptor (e.g., 2x). This tells browsers how to select the most appropriate image source for the current viewport or display density. Omitting the descriptor leads to HTML validation errors and unexpected image selection.
Correct usage with width descriptors:
<img
alt=""
sizes="(min-width:568px) 140px"
srcset="photo.png?w=860&q=90 860w"
src="photo.png?w=860&q=90">
Correct usage with pixel density descriptors (if sizes is removed):
<img
alt=""
srcset="photo.png?w=860&q=90 2x"
src="photo.png?w=860&q=90">
Key points:
- With sizes, use width descriptors (e.g., 860w).
- Without sizes, you may use pixel density descriptors (e.g., 2x).
- Always use either px or w units in the sizes attribute values; do not use w.
The srcset property on source elements, when used, requires at least one value.
The <source> HTML element specifies multiple media resources for the <picture>, the <audio> element, or the <video> element. It is a void element, meaning that it has no content and does not have a closing tag. It is commonly used to offer the same media content in multiple file formats in order to provide compatibility with a broad range of browsers given their differing support for image file formats and media file formats.
The srcset attribute is required if the source element’s parent is a <picture> element, but not allowed if the source element’s parent is an <audio> or <video> element.
The combination of type="module" and defer is not allowed. The type="module" attribute itself implies that the script should be executed in a deferred way, hence using the defer attribute is unnecessary and invalid.
Steps to Fix the Issue:
- Remove the defer Attribute: When you use type="module", you should not include the defer attribute since module scripts defer automatically.
Incorrect Code:
<script type="module" defer src="example.js"></script>
Corrected Code:
<script type="module" src="example.js"></script>
The <script> tag allows authors to include dynamic scripts and data blocks in their documents. When the src is present, this tag accepts a type attribute which must be either:
- an empty string
- text/javascript (that’s the default, so it can be omitted)
- module
Examples:
<!-- This is valid, without a type it defaults to JavaScript -->
<script src="app.js"></script>
<!-- This is valid, but will warn that it can be omitted -->
<script type="text/javascript" src="app.js"></script>
<!-- An empty attribute is valid, but will warn that it can be omitted -->
<script type="" src="app.js"></script>
<!-- The module keyword is also valid as a type -->
<script type="module" src="app.js"></script>
<!-- Any other type is invalid -->
<script type="wrong" src="app.js"></script>
<script type="text/html" src="app.js"></script>
<script type="image/jpeg" src="app.js"></script>
<img> tags, used to include images on a document, require an alt attribute to describe the contents of the image. This is essential for users that cannot see the image (like screen reader users), or as an alternate text when the image cannot be displayed. Example:
<img src="photo.jpg" alt="Person holding a cat" />
When an img element has an empty alt attribute, its role is implicitly decorative, so it must not specify a role attribute.
The <textarea> element does not have a type attribute.
The HTML <textarea> element represents a multi-line plain-text editing control, and is useful when you want to allow users to enter a sizeable amount of free-form text, for example a comment on a review or feedback form.
A start tag for <img> has been found inside a <noscript> section within the <head>, where it’s not allowed. Consider moving it to the <body> section.
The HTML <noscript> element defines a section of HTML to be inserted if a script type on the page is unsupported or if scripting is currently turned off in the browser.
When JavaScript is disabled, the content inside <noscript> will be used instead, so this content must fit within its parent section. As an <img> tag is not allowed inside <head>, this will raise an issue. Instead, consider moving the <noscript> part to the <body> section.
This issue is often related to 3rd party tracking pixels like the Facebook or LinkedIn conversion tracking pixels. For example, the Facebook pixel instructions tell you to insert it like this:
<html>
<head>
<script>
...some script...
</script>
<noscript>
<img src="..." />
</noscript>
</head>
<body>
...
</body>
</html>
Instead, consider moving the <noscript> part inside the <body>, where the <img> makes sense to be inserted:
<html>
<head>
<script>
...some script...
</script>
</head>
<body>
...
<noscript>
<img src="..." />
</noscript>
</body>
</html>