Тег source в HTML: что это и какие у него атрибуты

Тег source (от английского source, «источник») задаёт один вариант файла для своего родителя: video, audio или picture. Сам он ничего не показывает: браузер читает его атрибуты и решает, брать этот файл или перейти к следующему. Тег пустой, содержимого у него нет, а закрывающий тег не нужен.

Что именно делает source, зависит от родителя. В video и audio работают src и type, и браузер перебирает теги сверху вниз, пока не найдёт файл, который сможет открыть. В picture работают srcset, sizes, media и type, а выбор строится по условиям. Контейнер picture разобран на странице о теге picture, поэтому здесь о нём только то, что нужно для работы самого source.

HTML
<video controls>
  <source src="film.webm" type="video/webm">
  <source src="film.mp4" type="video/mp4">
</video>

Тег source в HTML: что это и где его можно использовать

Сначала о том, в каких родителях тег работает и что у него общего во всех случаях.

Допустимых родителей три: video, audio и picture. В любом другом месте, например в div или в body, тег ничего не выбирает и не загружает, браузер его просто не использует. Все source записывают в начале родителя: в picture до img, в video и audio до track. Такой порядок требует стандарт.

HTML
<picture>
  <source srcset="kot.webp" type="image/webp">
  <img src="kot.jpg" alt="Кот">
</picture>

<audio controls>
  <source src="song.ogg" type="audio/ogg">
  <source src="song.mp3" type="audio/mpeg">
</audio>

<div>
  <source src="film.webm" type="video/webm">
</div>

Пример: где source выбирает файл, а где нет

Результат

Переключайте кнопки: для video, audio и picture браузер показывает выбранный файл, а в div выбирать нечего. Файлы встроены в пример, буква или надпись показывает, какой из них взят.

Тег поддерживается всеми браузерами: по данным справочника MDN, он доступен с июля 2015 года. Подробное описание есть и в стандарте HTML.

Атрибуты src и type у тега source в video и audio

В видео и звуке тег описывает файл двумя атрибутами: адресом и типом.

Атрибут src задаёт адрес файла, и здесь он обязателен: без него source пропускается. Атрибут type сообщает браузеру формат файла в виде MIME-типа, при желании с кодеками после точки с запятой. Если браузер не умеет воспроизводить такой формат, он пропускает тег, не скачивая файл. Без type браузер сначала обратится к файлу, а уже потом поймёт, что открыть его не сможет.

HTML
<video controls>
  <source src="a.mp4"
          type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
  <source src="a.webm"
          type='video/webm; codecs="vp9, opus"'>
</video>
Значение typeЧто за форматПример записи
video/webmВидео в контейнере WebM (VP8, VP9, AV1)src="a.webm" type="video/webm"
video/mp4Видео в контейнере MP4 (чаще всего H.264)src="a.mp4" type="video/mp4"
video/oggВидео в контейнере Ogg (Theora)src="a.ogv" type="video/ogg"
audio/mpegЗвук MP3src="a.mp3" type="audio/mpeg"
audio/oggЗвук в контейнере Ogg (Vorbis, Opus)src="a.ogg" type="audio/ogg"
audio/wavНесжатый звук WAVsrc="a.wav" type="audio/wav"

Чтобы узнать, какие типы понимает браузер, используют метод canPlayType. Он возвращает строку probably («скорее всего играет»), maybe («возможно играет») или пустую строку. Набор форматов зависит от браузера и установленных кодеков, поэтому таблица ниже у каждого читателя получится своей.

JavaScript
const video = document.createElement("video");
console.log(video.canPlayType("video/webm"));
console.log(video.canPlayType('video/mp4; codecs="avc1.42E01E"'));

Пример: что вернёт canPlayType для разных type

Результат

Таблица строится прямо сейчас вашим браузером. Строки с пустым ответом показывают type, из-за которых тег source был бы пропущен.

Заявленный type браузер проверяет только при выборе. После загрузки он определяет формат по самому файлу. Поэтому неверный type не ломает файл, но из-за него браузер может пропустить тег, который подошёл бы.

Порядок тегов source в video и audio: что будет, если файл не открылся

Когда у видео или звука несколько тегов, браузер идёт по ним сверху вниз и останавливается на первом рабочем.

Для каждого source браузер сначала смотрит на атрибуты: нет src, не подходит type или media, тег пропускается без загрузки. Если условия выполнены, он загружает файл. Не нашёлся адрес или формат не удалось разобрать, берётся следующий source. Берётся первый рабочий, остальные не загружаются. В этом главное отличие от picture: там выбор делается один раз по условиям, и если выбранный файл не загрузился, браузер к следующему не переходит.

HTML
<video controls>
  <source src="film.mp4" type="video/mp4">
  <source src="film.webm" type="video/webm">
</video>

Пример: перебор source в video и в picture

Результат

В первых четырёх сценариях строится настоящий video, и под ним видно, какой файл выбран и на каком source сработало событие error. Последний сценарий показывает picture, где перебора нет.

СитуацияЧто делает браузерПример записи
Файл не существует или не открываетсяСобытие error на этом source, потом берётся следующийsrc="broken.webm"
type не подходит браузеруФайл не скачивается, на source всё равно приходит errorsrc="a.webm" type="video/foo"
У video есть свой srcВсе source внутри игнорируются<video src="b.webm">
Не открылся ни один файлУ video нет события error, networkState равен 3, а video.error пустsrc="x.webm" и src="y.webm"

Число networkState, равное 3, означает, что подходящего источника нет. Это единственный признак: страница никак не сообщит, что ролик не показан, пока вы сами не проверите состояние или не подпишетесь на событие error у последнего source.

Атрибут srcset у тега source в picture: дескрипторы x и w

В picture список файлов записывают в srcset, и у каждого файла есть дескриптор: плотность или ширина.

Значение srcset состоит из вариантов через запятую: адрес файла и дескриптор. Дескриптор x означает плотность пикселей экрана: 2x для файла, который нужен экрану с удвоенной плотностью. Запись без дескриптора считается 1x. Chrome берёт ближайший вариант, который не меньше плотности экрана, а если таких нет, самый большой.

HTML
<picture>
  <source srcset="kot-1x.png, kot-2x.png 2x, kot-3x.png 3x">
  <img src="kot-1x.png" alt="Кот">
</picture>

Пример: выбор файла по плотности пикселей

Результат

Кнопки меняют набор вариантов в srcset. Плотность в примере берётся у вашего экрана, а масштаб страницы клавишами Ctrl и плюс её меняет.

Пример записиПлотность 1Плотность 2Плотность 3
srcset="1x.png 1x, 2x.png 2x, 3x.png 3x"1x2x3x
srcset="1x.png 1x, 3x.png 3x"1x3x3x
srcset="2x.png 2x, 3x.png 3x"2x2x3x

Дескриптор w указывает ширину самого файла в пикселях, например 800w. Его записывают вместе с sizes, о котором дальше: без него валидатор сообщит об ошибке, а браузер возьмёт 100vw. Смешивать в одном srcset дескрипторы x и w нельзя, так требует стандарт. Пустой srcset делает тег бесполезным: браузер пропускает такой source и показывает файл из img. Те же правила действуют и у самого img, подробнее о них на странице о теге img.

Атрибут sizes у тега source: как браузер выбирает файл по ширине

Дескриптор w говорит, какой ширины файл, а sizes говорит, какую ширину займёт картинка на странице.

Значение sizes — это список через запятую: условие в скобках и ширина, а в конце ширина без условия. Браузер берёт первую подходящую ширину, умножает её на плотность экрана и выбирает самый маленький файл, у которого w не меньше полученного числа. Если подходящего нет, берётся самый большой. Без sizes считается 100vw, то есть вся ширина окна, даже если картинка на странице уже.

HTML
<picture>
  <source
    srcset="kot-400.jpg 400w,
            kot-800.jpg 800w,
            kot-1200.jpg 1200w"
    sizes="(min-width: 600px) 50vw, 100vw">
  <img src="kot-800.jpg" alt="Кот" width="800" height="600">
</picture>

Пример: выбор файла по ширине окна и sizes

Результат

Ширина окна имитируется скрытой рамкой, поэтому можно проверить окна любой ширины. Плотность пикселей берётся у вашего экрана, и от неё зависит, какой файл будет выбран.

Пример записиМесто под картинкуФайл при окне 800 px, плотность 1
sizes="(min-width: 600px) 50vw, 100vw"400 px400w
sizes не записан800 px (100vw)800w
sizes="300px"300 px400w
sizes="calc(100vw - 200px)"600 px800w

Если значение sizes записано с ошибкой, браузер возвращается к 100vw. Атрибут sizes у img внутри picture в этом случае не помогает: когда source подошёл, ширину берут только из него. При увеличении окна Chrome подгружает более крупный файл без перезагрузки страницы, а обратно на меньший не переключается. Условия для выбора самого source по типу экрана и теме записывают в media, это разобрано на странице о теге picture.

Атрибуты тега source: какие работают в video, audio и picture

У тега семь собственных атрибутов, но каждый из них относится только к одному или двум родителям.

Кроме них допустимы глобальные атрибуты вроде class и id. В таблице видно, какие атрибуты действуют в video и audio, а какие в picture.

АтрибутВ video и audioВ pictureПример записи
srcРаботаетНе действуетsrc="a.webm"
typeРаботаетРаботаетsrcset="a.avif" type="image/avif"
srcsetНе действуетРаботаетsrcset="a-1x.jpg, a-2x.jpg 2x"
sizesНе действуетРаботаетsrcset="a.jpg 800w" sizes="50vw"
mediaРаботает (в Chrome)Работаетsrcset="a.jpg" media="(min-width: 600px)"
widthНе действуетРаботаетsrcset="a.jpg" width="800" height="450"
heightНе действуетРаботаетsrcset="a.jpg" width="800" height="450"

Пример: какие атрибуты source не действуют

Результат

Три кнопки строят тег с атрибутом, который у этого родителя не читается. Выбранный файл показывает, какой source браузер пропустил.

Атрибуты width и height в picture помогают браузеру заранее узнать пропорции выбранного кадра, об этом подробно на странице о теге picture. Стандарт допускает media и в video, и Chrome пропускает там тег с неподходящим условием, но MDN советует использовать его только в picture, поэтому рассчитывать на это не стоит: файл для видео подбирайте по type и порядку.

Тег source в JavaScript: src, srcset и метод load()

Скрипт может создавать теги source и менять их, но браузер реагирует на такие изменения не сразу.

У объекта тега те же свойства, что и атрибуты: src, type, srcset, sizes, media, width и height. Если добавить source в пустой video, браузер сам начнёт выбор. Когда файл уже выбран, смена src у тега ничего не меняет, как и добавление нового тега перед ним. Чтобы выбор прошёл заново, у video вызывают метод load(). Он нужен и после того, как не открылся ни один файл: добавленный позже source сам по себе ничего не запускает.

JavaScript
const video = document.querySelector("video");
const source = video.querySelector("source");

source.src = "film2.webm";
video.load();
console.log(video.currentSrc);

Пример: когда браузер замечает изменение source

Результат

Кнопки по очереди строят пустой video, добавляют тег и меняют его. Журнал под видео запоминает, какой файл был выбран после каждого действия.

В picture всё иначе: если сменить srcset у source, картинка обновится сразу. А вот присвоение img.src игнорируется, пока подходит хоть один source. Узнать выбранный файл можно в свойстве currentSrc: у video и audio оно есть у самого элемента, у picture его читают у вложенного img.

Частые ошибки с тегом source

Большая часть сбоев с этим тегом связана с родителем, порядком и атрибутами, которые у него не читаются.

ОшибкаЧто происходитКак исправить
<div><source src="a.webm"></div>Тег вне video, audio и picture ничего не делаетЗаписать source внутрь нужного родителя
<source src="a.webm"></source>Закрывающий тег для пустого элемента считается ошибкой разметкиПисать только открывающий тег
<source src="a.webp">В picture атрибут src не читается, тег пропущенЗаменить на srcset="a.webp"
<source srcset="a.webm">В video атрибут srcset не читается, тег пропущенЗаменить на src="a.webm"
<source src="a.mp4">Без type браузер сначала обращается к файлу и только потом узнаёт, что не умеет его открытьДобавить type="video/mp4"
<video src="b.webm">Если у video есть src, теги внутри игнорируютсяУбрать src у video и записать файлы тегами
<source srcset="a.jpg 400w, b.jpg 800w">Без sizes считается 100vw, и выбирается файл больше нужногоДобавить sizes с реальной шириной картинки
srcset="a.jpg 1x, b.jpg 800w"Смешаны дескрипторы x и w, стандарт это запрещаетИспользовать один вид дескрипторов
source.src = "b.webm"После выбора файла смена src ничего не меняетВызвать у video метод load()
Ожидание события error у videoКогда не открылись все файлы, у video события нет, оно приходит на каждый sourceСлушать error у последнего source
<img ...><source ...>В picture тег после img игнорируетсяЗаписать все source до img
Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×