Атрибут src (от английского source, «источник») прописывают в теге, чтобы указать адрес файла, который браузер должен загрузить и вставить в страницу: картинки, скрипта, видео, звука или другой страницы. Закрывающей части у самого атрибута нет, он записывается внутри открывающего тега в виде src="адрес". А вот нужен ли закрывающий тег, зависит от элемента: у <img>, <source>, <track>, <embed> и <input> его нет, а у <script>, <iframe>, <video> и <audio> он обязателен.
От href атрибут отличается тем, что ничего не открывает по щелчку: файл подставляется прямо в страницу, и посетитель видит его без перехода. Про переходы по ссылкам подробно написано на странице атрибута href. Здесь разберём, какие теги понимают src, как правильно писать путь, что произойдёт при пустом значении или опечатке и как адрес файла читать и менять из JavaScript.
<img src="photo.jpg" alt="Кот на окне">
<script src="app.js"></script>
<iframe src="map.html" title="Карта"></iframe>
В этой статье
- Что такое атрибут src в HTML и как он работает
- Для каких тегов нужен src: img, script, iframe, video, audio и другие
- Что писать в src: относительный, абсолютный и корневой путь
- Пробелы, регистр, кириллица и решётка в адресе src
- Обязателен ли src: что будет у каждого тега без атрибута
- Пустой src и опечатка scr: что происходит в браузере
- Что будет, если файл по src не найден: события error и load
- Атрибут src у script и iframe: особые случаи
- Как менять src через JavaScript: свойство src и getAttribute
- Частые ошибки в атрибуте src
- Шпаргалка по атрибуту src
Что такое атрибут src в HTML и как он работает
Встретив src, браузер делает три шага: достраивает адрес до полного, отправляет за файлом запрос и, когда файл пришёл, показывает его или выполняет, смотря какой это тег. Пока файл загружается, страница его не ждёт: остальной текст выводится сразу, а место под картинку или видео заполняется позже. Значение атрибута всегда адрес, а не сам файл и не его содержимое.
Ниже тот случай, который знают все, - картинка. Выберите файл, и браузер подставит его в тег img. Меняется только значение src, остальная запись остаётся прежней.
<img src="circle.svg" alt="Синий круг">
<img src="square.svg" alt="Оранжевый квадрат">
<img src="triangle.svg" alt="Зелёный треугольник">
Пример: как src выбирает, какой файл показать
В демонстрации вместо настоящих файлов подставлены встроенные картинки, поэтому адрес в строке кода условный. На своём сайте в src пишут путь к файлу.
Подробнее про сам тег картинки, его размеры и запасной текст - на странице <img> и в уроке Изображения: img и атрибуты alt, src.
Для каких тегов нужен src: img, script, iframe, video, audio и другие
В современном HTML src есть не у всех тегов, а у девяти элементов, которые что-то загружают в страницу. У каждого из них файл выполняет свою работу, и это видно по таблице.
| Тег | Что загружается | Закрывающий тег | Пример записи |
|---|---|---|---|
<img> | Картинка | нет | <img src="cat.jpg" alt="Кот"> |
<script> | Файл со скриптом | да | <script src="app.js"></script> |
<iframe> | Другая страница во фрейме | да | <iframe src="map.html" title="Карта"></iframe> |
<video> | Видео | да | <video src="clip.webm" controls></video> |
<audio> | Звук | да | <audio src="beep.wav" controls></audio> |
<source> | Вариант файла для video или audio | нет | <source src="clip.webm" type="video/webm"> |
<track> | Файл субтитров для video и audio | нет | <track src="ru.vtt" kind="subtitles" srclang="ru" default> |
<embed> | Внешний файл в отведённой области | нет | <embed src="doc.pdf" type="application/pdf"> |
<input> | Картинка на кнопке отправки, только при type="image" | нет | <input type="image" src="go.png" alt="Отправить"> |
Обратите внимание на тег <input>: src у него работает только в сочетании с type="image". У обычного текстового поля атрибут пропускается без ошибки, и никакого запроса за файлом не будет. Ещё одна особенность - <source> внутри <picture>: там src не используют вовсе, а пишут srcset.
<video controls>
<source src="clip.webm" type="video/webm">
<source src="clip.mp4" type="video/mp4">
</video>
<picture>
<source srcset="wide.webp" type="image/webp">
<img src="wide.jpg" alt="Пейзаж">
</picture>
Если у video или audio задан собственный src, то вложенные <source> браузер не просматривает: выигрывает атрибут самого тега.
Где вместо src пишут другой атрибут
Частая причина «не грузится» - атрибут вписан тегу, который его не знает. В таблице теги, которые просят адрес другим способом.
| Тег | Какой атрибут нужен | Пример записи |
|---|---|---|
a | href - адрес перехода | <a href="page.html">Страница</a> |
link | href - адрес файла стилей и других ресурсов | <link rel="stylesheet" href="style.css"> |
<object> | data - адрес встраиваемого файла | <object data="doc.pdf" type="application/pdf"></object> |
<source> внутри <picture> | srcset - список файлов для разных экранов | <source srcset="wide.webp" type="image/webp"> |
form | action - адрес, куда уходят данные | <form action="/send" method="post"> |
Если вы впишете src тегу a или link, ошибки не будет, но и файла не будет: у этих элементов такого свойства просто нет. Для устаревших тегов <frame> и <bgsound> src в своё время был основным атрибутом, но писать их в новых страницах не нужно: фрейм заменяет <iframe>, а фоновую музыку - <audio>.
Пример: девять тегов с одним и тем же атрибутом
В демонстрации выберите тег: он создаётся заново, и браузер загружает для него файл, который указан в src. У каждого тега результат свой: картинка рисуется, скрипт выполняется, фрейм открывает страницу, плееры получают файл.
Файлы встроены в демонстрацию, поэтому адреса в строке кода условные. Кнопка «track» показывает субтитры: нажмите воспроизведение, и строки появятся внизу кадра.
Что писать в src: относительный, абсолютный и корневой путь
Значением src служит URL, то есть адрес. Браузер сравнивает его с адресом страницы, на которой он написан, и по этому сравнению решает, откуда брать файл. Поэтому одна и та же запись на странице из корня сайта и на странице из вложенной папки может указывать на разные файлы.
| Вид адреса | Пример записи | Откуда будет взят файл |
|---|---|---|
| Относительный, от папки страницы | src="photo.png" | https://example.ru/blog/photo.png |
| Относительный, во вложенную папку | src="img/photo.png" | https://example.ru/blog/img/photo.png |
| Относительный, на уровень выше | src="../photo.png" | https://example.ru/photo.png |
| Корневой, от корня сайта | src="/photo.png" | https://example.ru/photo.png |
| Абсолютный, с адресом сайта | src="https://example.ru/img/photo.png" | Ровно по написанному адресу |
| Без протокола | src="//cdn.example.ru/photo.png" | Тот же протокол, что у страницы, другой сайт |
| Встроенные данные | src="data:image/gif;base64,R0lGOD..." | Файл целиком записан в атрибуте, запроса нет |
| Временная ссылка из JavaScript | src="blob:https://example.ru/3f2a..." | Файл из памяти страницы |
Разберём на примере папок сайта. Страница лежит в папке blog, а картинки - в двух разных местах.
site/
index.html
photo.png <- /photo.png
img/
cat.png <- /img/cat.png
blog/
post.html <- страница, где пишем тег
photo.png <- /blog/photo.png
Со страницы post.html запись src="photo.png" приведёт к файлу blog/photo.png, а src="/photo.png" - к файлу в корне. Чтобы достать img/cat.png из вложенной папки, подойдёт либо ../img/cat.png, либо корневой путь /img/cat.png. Корневой путь проще, потому что не зависит от того, на каком уровне лежит страница. Об относительных и абсолютных адресах в целом рассказано в уроке Абсолютные и относительные ссылки.
Все относительные адреса можно сдвинуть разом тегом <base>: если в нём указан href="/sub/", то src="photo.png" будет искать файл в папке /sub/, где бы ни лежала сама страница. Если картинки вдруг «уехали» на всех страницах сразу, проверьте, нет ли в head такого тега.
Проверить, за каким адресом пошёл браузер, можно без догадок. Откройте инструменты разработчика клавишей F12, перейдите на вкладку «Сеть» и перезагрузите страницу: в списке будут все запросы, а файлы, которые не нашлись, подсвечены красным с кодом 404.
Пример: как браузер достраивает адрес
Выберите страницу, впишите значение src или нажмите готовый вариант. Демонстрация покажет, что записано в атрибуте, какой полный адрес получится и какой путь уйдёт на сервер.
Расчёт в демонстрации выполняет сам браузер, никакие файлы по этим адресам не запрашиваются.
Пробелы, регистр, кириллица и решётка в адресе src
Адрес в src - не просто название файла, а URL, а у URL свои правила. Именно из-за них картинка, которая прекрасно открывается с жёсткого диска, после выгрузки на сайт показывает значок битой картинки. Ниже шесть записей, которые чаще всего приводят к путанице.
<img src=" photo.png ">
<img src="my photo.png">
<img src="картинка.png">
<img src="Photo.png">
<img src="a#b.png">
<img src="photo.png?v=2">
- Пробелы по краям браузер отбрасывает, и файл находится. Но писать их незачем.
- Пробел внутри названия превращается в
%20. Файл найдётся, если на сервере он называется с пробелом, однако адрес выглядит неряшливо. Лучше назвать файлmy-photo.png. - Кириллица работает, но в запросе буквы превращаются в длинные последовательности вида
%D0%BA. Такой адрес неудобно читать и копировать, поэтому файлы называют латиницей. - Регистр зависит от сервера. На компьютере с Windows
Photo.pngиphoto.pngобычно считаются одним файлом, на сервере с Linux - двумя разными. Запись, которая работала дома, на сайте даст 404. Выход один: всегда писать названия строчными буквами. - Решётка отделяет якорь, а якорь на сервер не отправляется. Из
a#b.pngсервер получит запрос на файлa, и картинка не загрузится. Решётку в названии файла не используют. - Вопросительный знак начинает параметры. Файл остаётся тем же, а параметр
?v=2нужен, чтобы заставить браузер скачать обновлённую версию вместо старой из кэша.
Пример: какой адрес браузер отправляет на сервер
Нажмите «Файлы на компьютере с Windows» и «Сервер с Linux», чтобы увидеть, как меняется результат для Photo.png. Остальные карточки от переключателя не зависят.
Обязателен ли src: что будет у каждого тега без атрибута
Ответ зависит от тега, и общего правила «src нужен всегда» нет. У <img> его считают обязательным, потому что без него нечего показывать. У <script> атрибут нужен только когда код лежит в отдельном файле. Для <source> внутри <video> и <track> внутри <video> нужен свой адрес, а у самих <video> и <audio> его можно заменить вложенными <source>.
Правила записаны в описании тега img в стандарте HTML. На практике src пишут у картинки всегда, даже когда есть srcset: он служит запасным вариантом для браузеров, которые список не поняли.
| Тег | Что будет без src | Что делать |
|---|---|---|
<img> | Запрос не уходит, вместо картинки показан текст из alt | Всегда писать src и alt |
<input> с type="image" | Кнопка превращается в надпись из alt | Писать src и alt |
<video> | Пустой плеер без файла | Указать src или вложить <source> |
<audio> | Пустой плеер без файла | Указать src или вложить <source> |
<iframe> | Пустая белая область без запроса | Указать src или srcdoc |
<script> | Выполняется только код внутри тега, а если его нет, не происходит ничего | Нужен либо src, либо код внутри |
Для сравнения в демонстрации слева каждый тег с рабочим src, справа - тот же тег без него.
<img src="circle.svg" alt="Синий круг">
<img alt="Синий круг">
<input type="image" src="circle.svg" alt="Синий круг">
<input type="image" alt="Синий круг">
<script src="app.js"></script>
<script></script>
Пример: шесть тегов с src и без него
Слева тег с адресом файла, справа тот же тег без src. Файлы в демонстрации встроенные, поэтому записи в коде выше условные.
Пустой src и опечатка scr: что происходит в браузере
Две ошибки выглядят похоже, но ведут себя по-разному. Пустое значение - это атрибут, который есть, но ничего не содержит: src="". Опечатка - атрибут с другим названием, например scr: для браузера это чужой атрибут, и настоящего src у тега просто нет.
В старых руководствах пишут, что пустой src заставляет браузер повторно запросить саму страницу. В современных браузерах этого не происходит: у тега <img> с пустым src запроса нет вообще, в журнале сервера остаётся один запрос - самой страницы. Картинка, как и без атрибута, показывает текст из alt. У <iframe> с пустым src открывается пустая страница about:blank, у <script> пустой src пропускается, и скрипты ниже по странице выполняются, а у <video> пустой src даёт ошибку источника с кодом 4.
<img src="circle.svg" alt="Синий круг">
<img src="" alt="Синий круг">
<img alt="Синий круг">
<img scr="circle.svg" alt="Синий круг">
Различить случаи можно в JavaScript. У пустого src метод getAttribute("src") вернёт пустую строку, а у отсутствующего атрибута и у опечатки - null. Свойство img.src у пустого атрибута вернёт адрес самой страницы (браузер достроил «ничего» до полного адреса), а у отсутствующего - пустую строку. Подробнее об этой разнице в разделе про JavaScript ниже.
Пример: четыре варианта записи src
Под каждой картинкой выведены значения, которые прочитал сам браузер. Во всех трёх сломанных вариантах свойство complete равно true, хотя загружать нечего.
Что будет, если файл по src не найден: события error и load
Когда адрес записан верно, но файла по нему нет (его удалили, переименовали или сервер вернул 404), браузер сообщает об этом событием. Какое событие придёт и придёт ли вообще, зависит от тега. Это важно, если вы хотите подставить запасную картинку или показать сообщение об ошибке.
| Тег | Событие | Кому приходит |
|---|---|---|
<img> | error | Самой картинке |
<script> | error | Тегу script, остальные скрипты работают дальше |
<input> с type="image" | error | Самому полю |
<audio> | error | Самому audio |
<source> | error | Тегу source, а не video |
<track> | error | Тегу track, если у него есть default |
<iframe> | только load | Фрейму: страница с ошибкой тоже считается загруженной |
<embed> | никакого | Событий нет, браузер молча оставляет пустое место |
Для картинки событие можно перехватить прямо в разметке и подставить запасную. Строка this.onerror=null нужна, чтобы при ошибке в самой запасной картинке браузер не ушёл в бесконечный цикл.
<img src="circle.svg" alt="Синий круг"
onerror="this.onerror=null; this.src='stub.svg'">
Пример: какое событие приходит при пропавшем файле
Выберите тег: ему подставляется адрес файла, которого уже нет. Результат покажет, какое событие сработало. Ниже отдельная проба с запасной картинкой.
Недоступный файл в демонстрации - это временная ссылка, которую создали и сразу отозвали. Ходить за ним на сервер не нужно, поэтому демонстрация работает без интернета.
Атрибут src у script и iframe: особые случаи
У этих двух тегов src меняет поведение сильнее, чем у остальных, потому что рядом с ним может оказаться другое содержимое.
script: src и код внутри тега
Если у <script> есть src, то выполняется только файл, а код, записанный внутри тега, игнорируется. Он игнорируется и тогда, когда файл не загрузился: запасного запуска не будет. Нужны оба действия - пишите два тега. Скрипт, созданный из JavaScript через document.createElement("script"), по умолчанию асинхронный (async равен true), то есть не ждёт предыдущих скриптов.
<script src="app.js">
console.log("Этот код не выполнится");
</script>
<script src="app.js"></script>
<script>
console.log("А этот выполнится");
</script>
Пример: что выполнится у script с src и кодом внутри
Отметьте нужные галочки и нажмите кнопку: внешний файл и код внутри тега запускаются независимо друг от друга, но в одном теге вместе работать не будут.
Скрипт с чужого сайта, например подключённый с CDN, получает полный доступ к вашей странице. Поэтому у такого тега добавляют integrity с контрольной суммой файла и crossorigin: браузер сверит файл с суммой и откажется выполнять, если его подменили.
iframe: src и srcdoc
У <iframe> есть второй способ задать содержимое - srcdoc, в который HTML вписывают прямо в атрибут. Если указаны оба, выигрывает srcdoc, а src браузер не загружает. Такая запись чаще появляется случайно и сбивает с толку. Про вставку внешнего содержимого во фрейм есть урок iframe: встраивание внешнего контента.
<iframe src="page-a.html"></iframe>
<iframe srcdoc="<p>Страница B</p>"></iframe>
<iframe src="page-a.html" srcdoc="<p>Страница B</p>"></iframe>
Пример: что откроется во фрейме, если указаны и src, и srcdoc
Страница A загружена по src, страница B записана в srcdoc. Третья кнопка показывает, что при обоих атрибутах открывается B.
Чужие страницы во фрейме лучше ограничивать атрибутом sandbox: без него встроенная страница получает больше возможностей, чем нужно для простого показа.
Как менять src через JavaScript: свойство src и getAttribute
У элементов с атрибутом src есть одноимённое свойство, и читать его можно двумя способами, которые возвращают разное. element.getAttribute("src") вернёт значение ровно так, как оно написано в разметке: photo.png. Свойство element.src вернёт уже полный адрес: https://example.ru/blog/photo.png. Для сравнения с путём из разметки берут getAttribute, для запроса к серверу - свойство.
const img = document.querySelector('img');
img.getAttribute('src'); // "photo.png"
img.src; // "https://example.ru/blog/photo.png"
img.src = 'other.png'; // браузер загрузит другой файл
img.removeAttribute('src');
- Присвоение нового значения запускает новую загрузку. Присвоение того же значения тоже запускает её, и событие
loadприходит снова. - После
removeAttribute("src")методgetAttributeвозвращаетnull, а размеры картинки в пикселях равны нулю: показывать нечего. - Свойство
srcесть не у всех тегов. Уaего нет:a.setAttribute("src", "x.png")запишет атрибут, но никакой загрузки не начнётся. - Объект
new Image()загружает файл, не попадая в страницу. Так картинку подгружают заранее, чтобы потом показать мгновенно.
Пример: что происходит при смене src из JavaScript
Счётчик «load» растёт при каждой загрузке, в том числе при повторном присвоении того же значения. После removeAttribute атрибут читается как null.
Ещё один приём - отложенная загрузка. Адрес картинки записывают сначала в data-src, а в src переносят, когда картинка нужна: до этого момента браузер файл не запрашивает. Сегодня для большинства случаев достаточно атрибута loading="lazy", но подход с data-src пригодится, когда загрузку нужно запустить по своему условию, например по щелчку.
<img data-src="circle.svg" alt="Синий круг">
<script>
const img = document.querySelector('img');
img.src = img.dataset.src; // только теперь пойдёт запрос
</script>
Пример: картинка, которая загружается по кнопке
Пока в src пусто, браузер файл не запрашивает. Кнопка переписывает адрес из data-src в src, и загрузка начинается.
Частые ошибки в атрибуте src
Большинство проблем с src сводится к неверному пути или к атрибуту не на своём месте. В таблице ошибки, которые встречаются чаще всего, и способ исправить каждую.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
src="C:\Users\me\photo.png" | Работает только на вашем компьютере: у посетителей такого пути нет | Положить файл в папку сайта и указать путь от страницы или от корня |
src="Photo.png" | Файл лежит как photo.png: на Linux-сервере будет 404 | Совпадать с названием файла до буквы, лучше всё писать строчными |
src="photo" | Адрес без расширения указывает на другой файл, которого нет | Писать полное название: photo.png |
src="images/photo.png" на странице в папке blog | Браузер ищет blog/images/photo.png, а файл лежит в /images/ | Корневой путь /images/photo.png или ../images/photo.png |
src="my photo.png", src="картинка.png" | Файл находится, но адрес превращается в %20 и %D0%BA | Называть файлы латиницей через дефис |
src="a#b.png" | Сервер получает запрос на a, всё после решётки отбрасывается | Убрать решётку из названия файла |
src="" | Запроса нет, показан текст из alt или пустая область | Указать адрес или удалить атрибут |
scr="photo.png" | Опечатка: настоящего src у тега нет | Исправить на src, проверить валидатором |
<a src="page.html"> | Переход не работает: у a нет такого атрибута | Использовать href |
<input src="go.png"> без type="image" | Атрибут не действует, картинки нет | Добавить type="image" |
<script src="app.js">код</script> | Выполняется только файл, код внутри игнорируется | Разнести на два тега script |
<source src="wide.webp"> внутри picture | src там игнорируется, браузер берёт картинку из img | Писать srcset |
src="https://site.ru/gallery/photo-page" | Адрес страницы вместо адреса файла: вместо картинки приходит HTML | Брать прямой адрес файла с расширением |
Шпаргалка по атрибуту src
Всё главное из статьи в одной таблице: что нужно сделать и как это записать.
| Задача | Как записать | Пример записи |
|---|---|---|
| Вставить картинку | Адрес файла в src, текст в alt | <img src="cat.jpg" alt="Кот"> |
| Подключить скрипт | src и закрывающий тег, код внутри не писать | <script src="app.js"></script> |
| Показать другую страницу | src у iframe | <iframe src="map.html" title="Карта"></iframe> |
| Видео и звук | src у плеера или вложенные source | <video src="clip.webm" controls></video> |
| Субтитры | src у track и default | <track src="ru.vtt" kind="subtitles" srclang="ru" default> |
| Картинка на кнопке формы | type="image" и src | <input type="image" src="go.png" alt="Отправить"> |
| Файл в той же папке | Просто название | src="photo.png" |
| Файл из корня сайта | Путь с косой чертой в начале | src="/img/photo.png" |
| Файл на другом сайте | Полный адрес | src="https://example.ru/photo.png" |
| Запасная картинка при ошибке | Событие error | onerror="this.onerror=null; this.src='stub.svg'" |
| Прочитать адрес | getAttribute("src") или свойство src | img.getAttribute("src") |
| Загрузить позже | Адрес в data-src, перенос в src по условию | img.src = img.dataset.src |