The src attribute of the <img> tag tells the browser which image file to load. It takes a URL, either a path relative to the current page or a full address, and with no usable src (and no srcset) nothing is shown. People often write it as “imgsrc”, but there is no such attribute: it is <img src="...">.
This post covers how to write the path correctly, which other attributes to add, how srcset and sizes work, and how to debug an image that does not show up.
Basic syntax
<img src="images/lake.jpg" alt="A lake at sunrise with mist over the water" width="800" height="533">
<img> is a void element: it has no closing tag. Per MDN, src is required unless srcset is present, so at least one of the two must exist. The other attributes in the example are the ones you should add almost every time: alt, width and height.
Writing the src path
Most “image not showing” bugs are path bugs. These are the forms you will use:
| Form | Example | Resolved against |
|---|---|---|
| Relative to the page | images/lake.jpg |
The folder of the current HTML file |
| Parent folder | ../images/lake.jpg |
One folder up from the current page |
| Root-relative | /images/lake.jpg |
The root of the site, whatever the page’s folder |
| Absolute URL | https://example.com/lake.jpg |
Nothing; it is used as is |
If a page lives at /blog/post.html, then images/lake.jpg loads /blog/images/lake.jpg, while /images/lake.jpg loads the file from the site root. Moving a page to another folder breaks the first form but not the second, which is why root-relative paths are popular on larger sites.
Always write the alt attribute
The alt text is shown when the image fails to load, and screen readers read it aloud. Without it, some screen readers announce the file name instead. Rules that cover most cases:
- Describe what the image contributes to the page, not just what it looks like. A chart needs its main takeaway, a button icon needs its action (“Search”).
- Do not start with “image of” or “picture of”; assistive technology already says it is an image.
- For purely decorative images, use an empty value:
alt="". That tells assistive technology to skip it. Leaving the attribute out entirely is different and worse. - If the text next to the image already says the same thing, a short alt or an empty one avoids repetition.
Search engines also use alt text and the surrounding text to understand an image, but write it for the person who cannot see the image first.
Set width and height to avoid layout shift
Without dimensions, the browser does not know how tall the image is until it downloads, so the text below jumps down when the image arrives. Setting width and height as plain integers (no units) lets the browser compute the aspect ratio and reserve the space in advance. Use the image’s real pixel dimensions, then let CSS scale it:
<img src="lake.jpg" alt="Lake at sunrise" width="800" height="533">
img {
max-width: 100%;
height: auto;
}
With height: auto the image keeps its proportions when it shrinks, and the width/height attributes still provide the aspect ratio for the reserved space. A common mistake is to put wrong numbers in the attributes (for example 300×200 for a 3:2 image that is really 4:3); the image then either stretches or the reserved box is the wrong shape.
Responsive images with srcset and sizes
A phone with a 400 px wide layout should not download a 2400 px photo. srcset gives the browser a list of files, and sizes tells it how wide the image will be displayed so it can choose.
<img
src="lake-800.jpg"
srcset="lake-400.jpg 400w, lake-800.jpg 800w, lake-1200.jpg 1200w"
sizes="(min-width: 1000px) 600px, 100vw"
width="1200" height="800"
alt="Lake at sunrise">
How to read it:
- Each
wvalue is the intrinsic pixel width of that file, not a screen width. It must match the real file. sizesis a list of conditions and widths. Here: on viewports 1000 px or wider the image is shown 600 px wide, otherwise it fills the viewport (100vw). The default is100vwif you omit it.- The browser takes the display width, multiplies by the device pixel ratio, and picks a file that is big enough. A 400 px layout on a 2x screen needs about 800 px, so it picks
lake-800.jpg. - With
wdescriptors, browsers that supportsrcsetignoresrc; it is only the fallback for old browsers. - Do not mix
wandxdescriptors in onesrcset.
For fixed-size images such as a logo, use pixel density descriptors instead and skip sizes:
<img src="logo.png" srcset="logo.png 1x, logo@2x.png 2x" width="120" height="40" alt="Company logo">
The browser decides which candidate to download, so you cannot force a particular file. That is intended: it can take connection and user settings into account.
The picture element: art direction and formats
Use <picture> when you want a different crop for different screens (art direction) or want to offer modern formats with a fallback. The inner <img> is still required and carries the alt text.
<picture>
<source media="(min-width: 800px)" srcset="hero-wide.avif" type="image/avif">
<source media="(min-width: 800px)" srcset="hero-wide.jpg">
<source srcset="hero-square.jpg">
<img src="hero-square.jpg" alt="Developer at a desk with two monitors" width="800" height="800">
</picture>
The browser uses the first <source> whose media and type it matches, so order matters. If you only need smaller files for smaller screens, plain srcset on <img> is simpler.
Loading behavior: lazy, decoding and priority
loading="lazy"delays loading until the image is near the viewport. Use it for images below the fold. The default iseager. Always setwidthandheighton lazy images, because an unloaded image has no size and the browser cannot tell when it should load.- Do not lazy-load the main image visible at the top of the page (often the largest element on screen); that delays it. Give it
fetchpriority="high"instead, which is a hint for the browser to fetch it earlier. decoding="async"lets the browser paint other content without waiting for the image to decode. The difference is usually small for ordinary images.
<!-- top of page -->
<img src="hero.jpg" alt="..." width="1200" height="600" fetchpriority="high">
<!-- further down -->
<img src="team.jpg" alt="..." width="600" height="400" loading="lazy" decoding="async">
Security and privacy notes
- Hotlinking. Pointing
srcat an image on someone else’s server uses their bandwidth, and they can change or remove the file, or block your site. Host the images you rely on yourself or on a CDN you control. - Referrer. By default browsers send the
Refererheader for cross-origin image requests with the policystrict-origin-when-cross-origin, which sends only your origin. To send nothing, addreferrerpolicy="no-referrer". - CORS. If you draw a cross-origin image onto a
<canvas>and read pixels back, you needcrossorigin="anonymous"on the image and a matchingAccess-Control-Allow-Originheader on the server; otherwise the canvas is tainted. - User-supplied URLs. If a user can set an image URL (a profile picture link, say), remember that your visitors’ browsers will request it, which reveals their IP address to that server. Prefer uploading and re-hosting the file.
- HTTPS. Load images over HTTPS; on an HTTPS page, browsers may block or upgrade plain HTTP images.
Setting src from JavaScript
You can change the source at runtime, and handle failures with the error event:
const img = document.querySelector("#avatar");
img.addEventListener("error", () => {
img.src = "/images/default-avatar.png";
}, { once: true });
img.src = userProvidedUrl;
The { once: true } option matters: if the fallback also fails, an unguarded handler would set the same source again and loop. If you build the markup as a string, as in many tutorials that use innerHTML, make sure the URL is not raw user input; create the element with document.createElement("img") and assign src instead. For more on the DOM and JavaScript basics, see our introduction to web development basics.
Image CDNs
Services such as Cloudinary, Imgix or Cloudflare Images store your originals and resize or convert them through URL parameters, which pairs well with srcset: each width in the list is just the same image with a different parameter. They are a convenience, not a requirement. For a small site, exporting three or four sizes at build time works fine. Check the provider’s current docs for their URL syntax and pricing, since both change.
Why your image is not showing
Go through these in order:
- Open the image URL directly. Copy the resolved URL from the Network tab of your browser’s developer tools and open it in a new tab. A 404 means the path is wrong; a 403 means permissions.
- Check the path form. Is it relative to the page or the site root? A leading slash changes the meaning (see the table above).
- Check the case and the extension. Many servers run on Linux, where
Lake.JPGandlake.jpgare different files, even if it worked on your Windows or macOS machine. Also check for spaces in file names; use hyphens. - Check the file is really deployed. It exists locally but was not committed, uploaded or copied to the build output.
- Mixed content. An
http://image on anhttps://page may be blocked. - Hidden by CSS. An image can load but be invisible because of
display: none, zero height in a flex or grid parent, ormax-height. Inspect the element and look at its computed size. - Wrong
srcset. If one of the candidate files 404s, only some screens show a broken image. Test with different window widths and with the device toolbar. - Wrong content type or a corrupt file. A server that sends an HTML error page with status 200 will show a broken icon. Check the response in the Network tab.
Quick checklist
- Correct
srcpath, tested from the deployed page. - Meaningful
alt, oralt=""for decoration. - Real
widthandheight, plusmax-width: 100%; height: autoin CSS. srcsetandsizesfor large content images;loading="lazy"below the fold.- Modern formats such as WebP or AVIF through
<picture>when file size matters, with a JPEG or PNG fallback. - Images hosted by you, served over HTTPS.
To practice HTML, CSS and JavaScript by building things step by step, you can try AlgoCademy. A good exercise is to take a page with one large photo and add dimensions, srcset, and lazy loading, then compare the Network tab before and after.
Frequently asked questions
Is there an imgsrc attribute?
No. The attribute is src on the <img> element. “imgsrc” is just a common way to refer to it in searches.
Is alt required?
For accessibility, yes. Use descriptive text for meaningful images and alt="" for decorative ones.
Can I use srcset without sizes?
With x descriptors, yes. With w descriptors, sizes defaults to 100vw, which is wrong for any image narrower than the full viewport and can make the browser download a larger file than needed.
Should every image be lazy-loaded?
No. Lazy-load images below the fold, and load the main visible image at the top of the page normally.
What is the difference between srcset on img and the picture element?
srcset lets the browser pick among sizes of the same image. <picture> lets you control the choice with media queries and file types, for different crops or formats.
