References

Beginner-friendly references for web development, with live, editable examples.

The HTML media attribute

Attribute
In short

The HTML media attribute holds a media query that decides when a stylesheet, image source or theme color applies. Its syntax matches CSS @media, as in print or (max-width: 600px). The attribute goes on <link>, <style>, <source> and a theme-color <meta>.

Overview

The HTML media attribute says which media or conditions a resource is meant for. A stylesheet with media="print" styles only printed pages, and a <source> with media="(max-width: 600px)" inside a <picture> is used only while the viewport is 600 pixels wide or less.

On a <link> that loads a stylesheet, or on a <style>, the styles apply only while the query matches. On a hyperlink, such as a link with rel="alternate", media only advises which media the linked document was designed for.

On a <meta> with name="theme-color", media picks a color for a condition such as (prefers-color-scheme: dark), and no other meta name allows it. Firefox doesn't support theme-color. Desktop Chrome and Edge use it only in installed web apps, and so does Safari from version 26.

Write the value as a media query list, the same text that would follow @media in CSS. A comma means or, so print, (max-width: 600px) matches in either case. An empty value matches everything, and a link or style element without media counts as all.

A misspelled feature makes its query false. A query such as (min-widht: 600px) is treated as not all, but the other queries in the same list still apply, so (min-widht: 600px), screen matches on any screen.

Syntax

<link rel="stylesheet" href="print.css" media="print">
<picture>
  <source srcset="banner-wide.jpg" media="(min-width: 800px)">
  <img src="banner-narrow.jpg" alt="Summer sale banner">
</picture>

Values

Value
A media query list, such as print or (min-width: 600px).

Example

Live example
<p>Pick a query for the source and see which image the picture shows.</p>
<p><label for="q">media on the source</label>
<select id="q">
  <option>(min-width: 380px)</option>
  <option>(max-width: 379px)</option>
  <option>print</option>
  <option>print, (min-width: 380px)</option>
  <option>(prefers-color-scheme: dark)</option>
  <option value="(min-widht: 380px)">(min-widht: 380px) with a typo</option>
</select></p>
<picture>
  <source id="src" media="(min-width: 380px)" srcset="data:image/svg+xml,%3Csvg%20xmlns='http%3A//www.w3.org/2000/svg'%20width='240'%20height='50'%3E%3Crect%20width='240'%20height='50'%20fill='%23cfe2ff'/%3E%3Ctext%20x='120'%20y='32'%20font-family='sans-serif'%20font-size='18'%20text-anchor='middle'%3EFrom%20the%20source%3C/text%3E%3C/svg%3E">
  <img id="pic" src="data:image/svg+xml,%3Csvg%20xmlns='http%3A//www.w3.org/2000/svg'%20width='240'%20height='50'%3E%3Crect%20width='240'%20height='50'%20fill='%23ffe3c4'/%3E%3Ctext%20x='120'%20y='32'%20font-family='sans-serif'%20font-size='18'%20text-anchor='middle'%3EFrom%20the%20img%3C/text%3E%3C/svg%3E" alt="Store banner" width="240" height="50">
</picture>
<p id="msg" role="status"></p>
<script>
const q = document.getElementById('q');
const src = document.getElementById('src');
const pic = document.getElementById('pic');
const msg = document.getElementById('msg');
function report() {
  const fromSource = pic.currentSrc.includes('source');
  const state = matchMedia(src.media).matches ? ' matches' : " doesn't match";
  msg.textContent = src.media + state + ' in this ' + innerWidth + 'px frame, so the ' + (fromSource ? 'source image is used.' : 'img is used.');
}
q.addEventListener('change', function () {
  src.media = q.value;
  setTimeout(report, 150);
});
pic.addEventListener('load', report);
report();
</script>

More Examples

Best practices

  • Test each new media query with matchMedia() at a size where it should match. The validator.nu checker doesn't flag a misspelled feature, so a typo shows up only as a false result.
  • List picture sources from the most specific condition to the least. The browser takes the first source whose media matches, so a (min-width: 600px) source placed above a (min-width: 1200px) one keeps the larger image from ever loading.
  • Use media on picture sources for art direction, such as a tighter crop for small screens. For sharper copies on high-density screens, put srcset on the img instead, so browsers can pick lighter files in data-saving modes.
  • Pair two <meta name="theme-color"> tags with different media values, one for light and one for dark. Each media value must be unique, and the first tag that matches and holds a valid color wins.
  • Add media or type to a picture source whenever another source, or an img with srcset, follows it. Such a source needs one of the two to be valid HTML, and a value of all doesn't count.

Frequently asked questions

Does HTML have a media tag?
No, HTML has no media tag, since media is an attribute you add to other elements. The elements HTML calls media elements are audio and video.
How is the media attribute different from @media in CSS?
The media attribute puts a condition on a whole element, while @media wraps rules inside a stylesheet. Inside a linked stylesheet, @media blocks can narrow the stylesheet's reach further.
Which elements accept the media attribute?
Link, style, source and meta accept media, and meta needs name=theme-color for it. The a and area elements don't take it, and validator.nu flags it there.
Does a stylesheet with media set to print still download?
Yes, Chrome and Firefox both download a stylesheet even when its media doesn't match. Only a stylesheet whose media matches can block rendering or scripts, so a print stylesheet doesn't hold up rendering on screen.
Does media react when the window is resized?
For stylesheets and picture sources, yes, media is checked again whenever the window or device changes. On a video or audio source, it's evaluated only once, when the element picks its file.