HTML Guide for media
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.
The media attribute on a <link> element specifies the media for which the linked resource is intended, using a valid media query. The value indicated is not a valid media query, which leads to a parse error.
Explanation
The media attribute is used to define what type of device the linked stylesheet should be applied to. Examples include common media types like screen, print, or all, as well as more complex media queries, such as (max-width: 600px) for responsive designs.
Correct Usage
-
Media Type Only:
You can specify general media types such as screen, print, or all.
<link rel="stylesheet" href="styles.css" media="screen">
-
Media Query:
For more precise control, use a media query to target specific conditions.
<link rel="stylesheet" href="styles.css" media="(max-width: 600px)">
The media attribute on the link element cannot use the deprecated value projection; only valid CSS media types should be specified.
The media attribute specifies what media/device the linked resource is designed for, using a media query or a list of valid media types. In modern HTML and CSS, commonly accepted values include all, print, and screen.
The value projection was intended for projectors but has been deprecated and is no longer recognized by browsers or the HTML standard. To ensure validity and compatibility, remove projection and use only accepted types such as screen and/or print.
Incorrect example (with deprecated value):
<link rel="stylesheet" href="style.css" media="screen, projection">
Correct examples:
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="style.css" media="screen, print">
If you intend your stylesheet for screens and print, you can use both screen, print; for only screens, use just screen. If the stylesheet should apply to all devices, you can omit the media attribute or use all:
<link rel="stylesheet" href="style.css">
or
<link rel="stylesheet" href="style.css" media="all">
The media attribute on a <link> element has not been recognized.
This attribute specified what media the linked resource is optimized for. As an example, the following will link a general stylesheet, and a specific one for printing:
<head>
<link rel="stylesheet" type="text/css" href="general.css">
<link rel="stylesheet" type="text/css" href="print.css" media="print">
</head>
Valid values for this attribute include:
- all. Default, used for all media.
- print. Used for printers and print previews.
- screen. Used for computer, tablets or smartphone screens.
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">
sizes only accepts a valid media condition list (e.g., (min-width: 600px) 50vw, 100vw); malformed media conditions or missing length values trigger this parse error.
Detailed explanation
- Element: source in a picture or audio/video context. For responsive images, use attributes srcset, optional media, and optional sizes.
-
Attribute: sizes applies only when srcset contains width descriptors (e.g., 320w, 640w). It is a comma-separated list of:
- One or more media conditions followed by a length (e.g., (min-width: 800px) 50vw)
- A final fallback length with no media condition (e.g., 100vw)
Common parse errors:
- Missing parentheses around conditions: min-width: 600px → (min-width: 600px)
- Using invalid units or tokens: 50 (needs a length like 50vw or 50rem)
- Missing length after a condition: (min-width: 800px)
- Trailing commas or malformed separators
- Using sizes while srcset uses pixel density descriptors (1x, 2x); sizes is ignored for x-descriptors and may confuse validators
- Valid media condition syntax mirrors CSS media queries without the @media keyword. Use logical operators and, or, not per CSS Media Queries spec, and ensure spaces and colons are correct.
HTML examples
-
Correct responsive image with width descriptors and sizes
<picture> <source type="image/webp" srcset="hero-480.webp 480w, hero-800.webp 800w, hero-1200.webp 1200w" sizes="(min-width: 1200px) 1200px, (min-width: 800px) 800px, 100vw"> <img src="hero-800.jpg" srcset="hero-480.jpg 480w, hero-800.jpg 800w, hero-1200.jpg 1200w" sizes="(min-width: 1200px) 1200px, (min-width: 800px) 800px, 100vw" alt="Hero image"> </picture>
-
Using viewport width units for simpler sizing
<img src="photo-640.jpg" srcset="photo-320.jpg 320w, photo-640.jpg 640w, photo-1024.jpg 1024w" sizes="(min-width: 900px) 50vw, 100vw" alt="Sample photo">
-
Correct when using pixel density descriptors (omit sizes)
<img src="avatar@1x.jpg" srcset="avatar@1x.jpg 1x, avatar@2x.jpg 2x" alt="User avatar">
Fixing common mistakes
-
Add parentheses and a length:
<img src="img-800.jpg" srcset="img-480.jpg 480w, img-800.jpg 800w" sizes="(min-width: 600px) 50vw, 100vw" alt="Example">
-
Remove stray comma and ensure final fallback:
<img src="banner-800.jpg" srcset="banner-400.jpg 400w, banner-800.jpg 800w" sizes="(min-width: 700px) 60vw, 100vw" alt="Banner">
-
Minimal valid document example
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Valid sizes Attribute</title> </head> <body> <img src="pic-800.jpg" srcset="pic-400.jpg 400w, pic-800.jpg 800w" sizes="(min-width: 600px) 50vw, 100vw" alt="Picture"> </body> </html>