Как показать разные картинки на разных экранах
Короткий ответ
Оберните <img> в <picture> и перед ним добавьте <source> с медиазапросом. Измените ширину окна, чтобы увидеть смену кадра:
<picture>
<source media="(max-width: 500px)" srcset="/media/photo-200x200.jpg">
<img src="/media/photo-600x200.jpg" alt="A flower" style="max-width: 100%; height: auto;">
</picture>Браузер идёт по <source> сверху вниз и берёт первый подходящий. Если не подошёл ни один, показывается файл из <img>. На узком экране широкий баннер превратился бы в полоску, поэтому там удобнее квадратный кадр.
Картинка для тёмной темы
В media подходит любой медиазапрос, например тема системы:
<picture>
<source media="(prefers-color-scheme: dark)" srcset="/media/photo-200x200.jpg">
<img src="/media/photo-400x250.jpg" alt="A flower" width="200">
</picture>Современные форматы
Тот же приём отдаёт WebP или AVIF браузерам, которые их понимают, а остальным — JPEG. Вместо media указывают атрибут type:
<picture>
<source srcset="photo.avif" type="image/avif">
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" alt="A flower" width="400" height="250">
</picture>Файлы в новых форматах при том же качестве весят заметно меньше.
Частая ошибка
Стили, размеры и alt задают элементу <picture> или <source>. Они ни на что не влияют: <picture> лишь выбирает адрес файла, а показывает картинку всегда <img>. Всё оформление — ему.
Функции из этого ответа
- <picture> — Контейнер для нескольких вариантов картинки: браузер выбирает подходящий `<source>` или берёт `<img>`.
- <source> — Один из вариантов файла для `<video>`, `<audio>` или `<picture>`.
- <img> — Картинка.
- srcset — Несколько файлов одной картинки разного размера: браузер выбирает подходящий для экрана.
- @media — Применяет правила только при заданных условиях — ширине окна, теме системы и других.