HTML Guide for img
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.
<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.
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>
The W3C HTML Validator issue you encountered indicates that the value of the height attribute for an <img> element is set to “100%”, which is not allowed in HTML. The height attribute must be a specific digit that represents the height in pixels (e.g., “150”), rather than a percentage or any other unit.
How to Fix the Issue
To resolve this issue, you need to specify a numeric value for the height attribute instead. If you want the image to occupy a certain percentage of the container, use CSS instead of the height attribute.
Example of Incorrect HTML
Here is an example that causes the validation issue:
<img src="image.jpg" height="100%" alt="Example Image">
Corrected HTML Using Pixel Values
To correct the issue, replace the percentage with a pixel value:
<img src="image.jpg" height="200" alt="Example Image">
Alternative: Using CSS for Responsive Design
If you want the image to scale responsively and occupy 100% of the width of its container, consider using CSS:
<style>
.responsive-img {
width: 100%;
height: auto; /* Maintains aspect ratio */
}
</style>
<img src="image.jpg" class="responsive-img" alt="Example Image">
Summary
- Do not use percentage values for the height attribute of <img> tags.
- Use pixel values for fixed dimensions.
- For responsive design, use CSS to set the dimensions instead.
The sizes attribute specifies the size of the image when it is displayed on different devices.
The error message is saying that the value auto is not a valid value for the sizes attribute.
To fix this issue, you need to replace the value auto with a valid size. You can use a width descriptor or a media query to specify the size for different device widths.
Here’s an example of using a width descriptor:
<img src="example.jpg" sizes="(max-width: 600px) 100vw, 50vw" />
This example sets the size of the image to 100% of the viewport width when the device width is less than or equal to 600px, and 50% of the viewport width for larger device widths.
Alternatively, you can remove the sizes attribute altogether and let the browser decide the best size for the image based on the viewport size.
<img src="example.jpg" />
If you do this, the browser will use the default sizes value of 100vw and will scale the image accordingly.
The width attribute on the img element must be a positive integer representing the number of pixels.
The HTML img element’s width and height attributes are expected to specify image dimensions in pixels. According to the HTML Living Standard, these attributes accept only non-negative integers. These integers define the rendered dimension of the image, overriding the actual image size based on its native resolution. The value “auto” is not a valid integer, which leads to the validation error you’ve encountered.
Here is a correct usage example of the img element:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Valid Image Width</title>
</head>
<body>
<img src="example.jpg" alt="Example image" width="200" height="100">
</body>
</html>
In the example above, the width is set to 200, and the height is set to 100. Both values are non-negative integers representing pixel dimensions. If you intend to maintain the image’s aspect ratio while adjusting another dimension, you can omit one of the attributes, and modern browsers will automatically adjust the aspect ratio based on the given dimension.
An empty sizes attribute on an img element is invalid; the attribute must contain a valid value or be omitted.
The sizes attribute specifies the slot width that the browser should use for selecting the appropriate image from those available in srcset. It should only be used when the srcset attribute is present. An empty string is not a valid value—if you do not have any sizes to specify, the attribute should be removed entirely.
Correct usage:
- Remove the empty sizes and srcset attributes if not needed.
- If specifying, provide valid values such as "100vw" or "(max-width: 600px) 100vw, 50vw".
Incorrect example:
<img src="photo.jpg" srcset="photo-small.jpg 480w, photo-large.jpg 1200w" sizes="" alt="">
Corrected example (with a valid sizes value):
<img src="photo.jpg" srcset="photo-small.jpg 480w, photo-large.jpg 1200w" sizes="100vw" alt="">
Square brackets in an img src query string must be percent-encoded to be valid.
The src attribute on img must be a valid URL. In URL query strings, characters like [ and ] are not allowed unescaped per URL syntax. When present (often from frameworks adding array-like params), they must be percent-encoded as [ -> %5B and ] -> %5D. Alternatively, remove brackets from the query or use a server-side/route format that avoids them.
HTML examples
Example causing the validator error
<img src="/images/photo.jpg?size[width]=300&size[height]=200" alt="Sample">
Fixed example using percent-encoding
<img src="/images/photo.jpg?size%5Bwidth%5D=300&size%5Bheight%5D=200" alt="Sample">
Fixed example by avoiding brackets in params
<img src="/images/photo.jpg?size_width=300&size_height=200" alt="Sample">
The src attribute on an <img> element contains an invalid character, that should be properly encoded as a URI percent-encoded character.
The src attribute for <img> tags is required, to define the source of the image, like in this example:
<img src="photo.jpg" alt="wombat" />
Replace square brackets in srcset URLs or percent-encode them.
The img element’s srcset expects valid URLs for each image candidate. According to the URL Standard, unescaped square brackets are not allowed in the path or query of an HTTP(S) URL used in HTML attributes like srcset. They must be either removed, replaced, or percent-encoded.
- Use safe characters in query parameters (e.g., hyphens or underscores instead of brackets).
- If brackets must remain for backend reasons, percent-encode them: [ -> %5B, ] -> %5D.
- Ensure each image candidate follows the URL [whitespace] descriptor pattern (e.g., 2x, 300w) with commas separating candidates.
HTML examples
Example causing the error
<img
src="image.jpg"
srcset="image.jpg?size=[small] 1x, image@2x.jpg?size=[large] 2x"
alt="Sample">
Corrected example (encode brackets)
<img
src="image.jpg"
srcset="image.jpg?size=%5Bsmall%5D 1x, image@2x.jpg?size=%5Blarge%5D 2x"
alt="Sample">
Corrected example (avoid brackets)
<img
src="image.jpg"
srcset="image.jpg?size=small 1x, image@2x.jpg?size=large 2x"
alt="Sample">
srcset contains candidates without a width descriptor while sizes is present, so each candidate must use a width (w) descriptor.
When an img has sizes, every srcset candidate must include a width descriptor like 320w, not a pixel density descriptor like 1x. Mixed descriptors are not allowed in the same srcset. Use either:
- Width descriptors with sizes (e.g., 320w, 640w, 1024w)
- Density descriptors without sizes (e.g., 1x, 2x)
The browser uses sizes to map CSS layout width to the best w candidate. Without sizes, density (x) can be used, but not together with sizes.
HTML examples
Reproduce the issue (invalid: sizes + x descriptors)
<img
src="photo-640.jpg"
srcset="photo-640.jpg 1x, photo-1280.jpg 2x"
sizes="(max-width: 600px) 100vw, 600px"
alt="Sample photo">
Fix using width descriptors with sizes (valid)
<img
src="photo-640.jpg"
srcset="photo-320.jpg 320w, photo-640.jpg 640w, photo-1280.jpg 1280w"
sizes="(max-width: 600px) 100vw, 600px"
alt="Sample photo">
Alternative fix: remove sizes and use density descriptors (valid)
<img
src="photo-640.jpg"
srcset="photo-640.jpg 1x, photo-1280.jpg 2x"
alt="Sample photo">
The attributes width and height of <img> elements expect a non-negative integer, so an empty string is not allowed. Either define the correct dimension, or remove this attribute.
Use role="none" (or remove the role) instead of role="presentation" on an img.
The role attribute maps elements to ARIA roles. For images, the valid way to make an image decorative is to either omit the ARIA role and use an empty alt attribute (alt=""), or use the ARIA role none. In ARIA 1.1, role="none" and role="presentation" are equivalent, but the W3C HTML Validator flags role="presentation" on img because the correct, accessible pattern is an empty alt to hide the image from assistive tech. Use alt="" alone, or pair it with role="none" if you need an explicit ARIA role. If the image conveys meaning, provide a descriptive alt and no role.
HTML Examples
Example that reproduces the issue
<img src="avatar.png" alt="" role="presentation">
Fixed examples
Decorative image (preferred minimal fix):
<img src="avatar.png" alt="">
Informative image:
<img src="chart.png" alt="Quarterly sales trend line chart">
The loading attribute on the img element only accepts the values eager or lazy.
The loading attribute is used to specify lazy loading behavior for images and only accepts the values "lazy" or "eager" (which is the default).
Explanation:
- The loading attribute hints to the browser whether to load the image immediately ("eager"), defer until it reaches a calculated distance from the viewport ("lazy").
- Using values other than "lazy", "eager" results in validation errors and browsers ignore the attribute.
- Never use numeric values or case-variants; always use the lower-case string values above.
Incorrect Example:
<img src="logo.png" alt="Company logo" loading="1">
Correct Example:
<img src="logo.png" alt="Company logo" loading="lazy">
Replace the incorrect value with loading="lazy" or loading="eager", or remove the attribute, to resolve the validator issue.
The sizes attribute for an img element requires valid CSS syntax, and auto is not an acceptable value within that attribute.
The sizes attribute allows you to specify a list of media conditions and corresponding sizes for the images. Each condition determines which size of the image should be displayed at different viewport widths, ensuring responsive image delivery. The syntax for sizes should be a comma-separated list of media queries followed by a value denoting the corresponding width of the image. This width value may be in pixels (px) or as a percentage (vw, vh), but auto is not valid in this context.
Here is a breakdown of a correct sizes attribute usage:
- 50vw: This denotes that the image should take up 50% of the viewport’s width.
- (max-width: 600px) 100vw, 50vw: When the viewport is at most 600 pixels wide, the image should occupy the full width (100vw). Otherwise, it should take 50 percent of the viewport width.
Remove “auto” from your sizes value and provide a valid, contextually correct CSS value.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<title>Responsive Images Example</title>
</head>
<body>
<img
src="image.jpg"
sizes="(max-width: 472px) 100vw, 472px"
srcset="image-small.jpg 300w, image-medium.jpg 600w, image-large.jpg 1000w"
alt="A description of the image"
>
</body>
</html>
In this example, if the viewport width is less than or equal to 472 pixels, the image will take up the entire width (100vw). For larger widths, the srcset specifies different image files for varying resolutions.
sizes contains an invalid media condition; the value must be a comma-separated list of media conditions with corresponding slot sizes, ending with an optional fallback length.
Detailed explanation:
- The sizes attribute on img pairs a media condition with a slot size that represents the layout width of the image for that condition. Syntax: (<media-condition>) <length>[, ...], <length> where the last item can be a bare length fallback.
- A media condition uses the same grammar as CSS media queries. It must be valid CSS, e.g., (min-width: 600px) or (width <= 50rem) and (orientation: landscape). Each condition must be enclosed in parentheses unless using logical operators combining proper conditions.
Common parse errors:
- Missing parentheses: use (min-width: 600px), not min-width: 600px.
- Invalid units or tokens: use px, em, rem, vw, etc.; avoid % in media conditions.
- Missing slot size after a condition: (min-width: 600px) must be followed by a length like 600px.
- Using px only for slot size without units or using percentages: slot size must be a length like 300px, 50vw, not 300.
- Trailing comma or extra commas.
- Misusing comparison syntax: use modern range syntax like (600px <= width <= 1000px) or the traditional form (min-width: 600px) and (max-width: 1000px). Do not write (min-width <= 600px).
- Slot sizes must be lengths: px, em, rem, vw, vh, vmin, vmax, ch. Percentages are not allowed in sizes slot sizes.
- The srcset widths (w descriptors) must correspond to the intrinsic widths of the image candidates, e.g., 400w, 800w. The browser picks one based on sizes.
HTML examples:
-
Correct usage with media conditions and fallback:
<img src="image-800.jpg" srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w" sizes="(min-width: 900px) 50vw, (min-width: 600px) 66vw, 100vw" alt="Decorative pattern">
-
Using range syntax and avoiding common mistakes:
<img src="hero-1600.jpg" srcset="hero-800.jpg 800w, hero-1200.jpg 1200w, hero-1600.jpg 1600w" sizes="(800px <= width < 1200px) 80vw, (width >= 1200px) 50vw, 100vw" alt="Hero banner">
-
Minimal fixed example for a typical error (missing parentheses and slot size): Incorrect:
<img src="pic-800.jpg" srcset="pic-400.jpg 400w, pic-800.jpg 800w" sizes="min-width: 600px, 100vw" alt="Sample">
Correct:
<img src="pic-800.jpg" srcset="pic-400.jpg 400w, pic-800.jpg 800w" sizes="(min-width: 600px) 50vw, 100vw" alt="Sample">
-
Example avoiding invalid tokens and commas:
<img src="avatar-256.png" srcset="avatar-128.png 128w, avatar-256.png 256w" sizes="(orientation: landscape) 30vw, 50vw" alt="User avatar">
The sizes attribute contains an empty source size, probably due to a trailing comma.
According to the HTML standard, the sizes attribute on the img element must contain a valid source size list. Each size is separated by a comma, and there must not be a trailing comma because that would create an empty entry, which is not allowed.
An example of an invalid sizes attribute:
<img
src="image.jpg"
alt=""
sizes="(min-width: 2200px) 100vw, (min-width: 856px) 461px, (min-width: 784px) 615px, "
srcset="image-2200.jpg 2200w, image-856.jpg 856w">
To fix the validation error, remove the trailing comma so the size list does not end with an empty value:
<img
src="image.jpg"
alt=""
sizes="(min-width: 2200px) 100vw, (min-width: 856px) 461px, (min-width: 784px) 615px"
srcset="image-2200.jpg 2200w, image-856.jpg 856w">
Each value in the sizes attribute should be a valid media condition and source size, separated only by commas, with no trailing or empty values.
The sizes attribute on the img element must use CSS length units (such as px, vw, em) and not image width descriptors like w.
The sizes attribute defines the intended display size of the image in CSS length units, which helps the browser select the appropriate image from the srcset. Use units like px (pixels) or vw (viewport width percentage), not w, which is used in the srcset descriptors. The srcset attribute specifies different image resources and their width descriptors (e.g., 860w), while sizes reflects the image’s display size in the layout.
Correct usage:
- sizes="(min-width: 568px) 140px" tells the browser the image will be displayed as 140 pixels wide when the viewport is at least 568 pixels wide.
- srcset="photo.png?w=860&q=90 860w" uses w as the descriptor for the image resource’s width.
HTML example:
<img
alt=""
sizes="(min-width: 568px) 140px"
srcset="photo.png?w=860&q=90 860w"
src="photo.png?w=860&q=90">
Summary:
- Use CSS units like px, vw, etc. in the sizes attribute.
- Use the w descriptor only in srcset, not in sizes.
Invalid sizes syntax in the <img> sizes attribute causes the validator error; each size value must be a valid CSS length with units and optional media condition.
Detailed explanation
The sizes attribute on responsive images (used with srcset) tells the browser how wide the image will be in CSS pixels under certain media conditions so it can choose the best candidate from srcset. It must be a comma-separated list of one or more size descriptors:
- Optional media condition followed by a length: (<media-condition>) <length>
- Or a final fallback length without media condition: <length>
Valid length units include: em, ex, ch, rem, cap, ic, vw, svw, lvw, dvw, vh, svh, lvh, dvh, vi, svi, lvi, dvi, vb, svb, lvb, dvb, vmin, svmin, lvmin, dvmin, vmax, svmax, lvmax, dvmax, cm, mm, q, in, pc, pt, px. Percentages are not allowed in sizes. Bare numbers without units are invalid. The media condition must be valid per CSS Media Queries (e.g., (max-width: 600px)), and each list item must have exactly one length value.
Common mistakes that trigger this error:
- Missing units: sizes="(max-width: 600px) 100" → must be 100px or another unit.
- Using %: sizes="(max-width: 600px) 100%" → percentages are invalid in sizes.
- Multiple lengths per item: sizes="(min-width: 800px) 50vw 400px" → only one length per item.
- Typos in units: 100 pxx, 100vws.
- Missing fallback: while not strictly required if all conditions cover all cases, providing a final fallback length avoids unexpected behavior.
Ensure sizes pairs correctly with srcset; srcset provides image candidates with width descriptors (w), and sizes expresses the slot width the image will occupy.
HTML examples
Correct usage with media conditions and fallback
<img
src="img-400.jpg"
srcset="img-400.jpg 400w, img-800.jpg 800w, img-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 900px) 50vw, 33vw"
alt="Sample image">
Fixing missing units (was 100 -> 100px)
<img
src="avatar-200.jpg"
srcset="avatar-200.jpg 200w, avatar-400.jpg 400w"
sizes="(max-width: 480px) 100vw, 200px"
alt="User avatar">
Avoiding invalid percentages (use vw instead)
<img
src="banner-800.jpg"
srcset="banner-800.jpg 800w, banner-1600.jpg 1600w"
sizes="(max-width: 700px) 100vw, 80vw"
alt="Promotional banner">
Single unconditional size (no media condition)
<img
src="thumb-320.jpg"
srcset="thumb-320.jpg 320w, thumb-640.jpg 640w"
sizes="320px"
alt="Thumbnail">
Correct srcset with sizes alignment
<img
src="photo-640.jpg"
srcset="photo-640.jpg 640w, photo-960.jpg 960w, photo-1280.jpg 1280w"
sizes="(min-width: 1200px) 800px, (min-width: 800px) 60vw, 90vw"
alt="Landscape photo">
If the validator pinpoints a position (Z), check that token for a missing or invalid unit, extra tokens after the length, or malformed media condition.
This error message indicates that there is a backslash (\) used in a URL, which is not a valid character for URL paths.
You’ll need to replace the backslashes with forward slashes (/) in the URL path segments.
Here’s an example of a correct img tag using a valid URL path:
<img src="https://example.com/img/small/photo.png" alt="example image">
Also, make sure that the URL is correct and that the image file actually exists in the specified location.
The src attribute on an element <img> contains a character which is not allowed unless properly encoded.
Special characters needing encoding are: :, /, ?, #, [, ], @, !, $, &, ', (, ), *, +, ,, ;, =, as well as % itself.
For example, this image tag is incorrect because the src attribute contains an the unallowed characters [ and ]:
<img src="image[00].svg" alt="logo">
Instead, this is the properly percent-encoded src attribute, where [ has been replaced with %5B and ] with %5D.
<img src="image%5B00%5D.svg" alt="logo">
Space characters are not allowed in src attributes. Instead, they should be converted to %20. In this example, the first line is invalid and the second is valid:
<img src="https://example.com/?s=some term" alt="description" />
<img src="https://example.com/?s=some%20term" alt="description" />
The src attribute on an element <img> contains a character that is not allowed, and should be encoded.
Some typical examples include the pipe character | that should be replaced by its encoded alternative %7C , and the left square bracket [ that needs to be encoded as %5B.