The HTML img Element
Think about what happens when you put a photograph on a wall. You have to decide which photograph, where to hang it, how big it should be, and what to write on the little label next to it for people who cannot see it.
The <img> element is how you do all of that on a web page. It is one of the oldest and most used elements in HTML, and it looks simple. Behind that simplicity, there are details that decide whether your images load fast, fit the page, and work for everyone. This lesson shows you how <img> works, from the inside out.
What You Will Learnβ
- What the
<img>element is, and why it is a "replaced" element - What the browser does from the moment it finds an image
- The core attributes and some useful extras
- Why images are inline, and how to fix the small gap below them
- How to make images fit any screen with CSS
- What happens when an image fails, and how to prepare for it
- When to use
<img>, and when to use something else
The Basicsβ
An image needs a source and a description. Everything else is a bonus.
- HTML Code
- Browser Output
<img
src="images/harbor.jpg"
alt="A small sailboat on blue waves under a bright sun"
width="240"
height="160"
/>
The demo uses a small drawing built into the page, since there are no image files here. In your project, src would be a file path like the one in the code.
A "Replaced" Elementβ
Most HTML elements contain their own content: a paragraph holds text, a list holds items. An <img> is different. It holds nothing. Its content comes from a separate file that the browser fetches and puts in its place.
Because of this, <img> is called a replaced element, and it is also a void element:
- It has no closing tag. Write
<img ... />or<img ...>. - It has no children. You cannot put text or other elements inside it.
- Its size comes from the file itself, unless you say otherwise.
In plain HTML, <img ...> is fine. In MDX and JSX, which this tutorial site uses, always write <img ... /> with the closing slash.
What the Browser Does With an Imageβ
Understanding this sequence explains many of the tips later in this section.
- Reads the HTML and finds the
<img>element. - Starts a request for the file at
src. This happens in parallel with other work, so the page keeps building. - Reserves space, if it knows the size from
widthandheight. If not, the space is empty until the file arrives. - Downloads the file over the network. Big files take longer.
- Decodes the image, turning the compressed file into pixels.
- Paints it on the page. If the size was not reserved, the content below jumps to make room.
This is why three habits matter so much: small files (steps 4 and 5), width and height (step 3), and lazy loading for images far down the page (step 2). You will learn each of them in this section.
The Core Attributesβ
| Attribute | Purpose | Notes |
|---|---|---|
src | The address of the image file | Required. See Src and Alt |
alt | A text alternative | Required. Use alt="" for decoration |
width | Width in pixels | Without px. Reserves space. See Width and Height |
height | Height in pixels | Same as above |
loading | eager or lazy | See Lazy Loading |
srcset | A list of image files at different sizes | See Srcset and Sizes |
sizes | How wide the image will be on screen | Works together with srcset |
A Few Extras Worth Knowingβ
| Attribute | What it does | When to use it |
|---|---|---|
decoding="async" | Lets the browser decode the image without blocking other work | Most content images |
fetchpriority="high" | Hints that this image is very important | The main image at the top of a page, often called the "hero" |
crossorigin | Controls how an image from another site is requested | When you draw it on a canvas, or use special security rules |
referrerpolicy | Controls what is sent about your page | For privacy, as in Link Security |
title | A tooltip | Use sparingly. Touch and keyboard users never see it |
<!-- The big image at the top of the page: load first -->
<img
src="images/hero.jpg"
alt="Students learning to code together"
width="1200"
height="600"
fetchpriority="high"
decoding="async"
/>
<!-- An image far down the page: load later -->
<img
src="images/team.jpg"
alt="The CodeHarborHub team on a video call"
width="600"
height="400"
loading="lazy"
decoding="async"
/>
title instead of altalt is for everyone who cannot see the image. title is only a tooltip that appears on mouse hover. They do different jobs, and alt is the one you must always write.
Images Are Inlineβ
By default, an <img> behaves like a letter in a sentence, not like a paragraph. It sits on the same line as the text around it, and it lines up with the baseline of the text.
- HTML Code
- Browser Output
<p>
A boat
<img src="images/boat-icon.png" alt="" width="24" height="24" />
can sit right inside a sentence.
</p>
A boat
can sit right inside a sentence.
That is perfect for small icons. For a large picture, you usually want it to stand alone as a block.
The Mysterious Gapβ
If you put an image alone in a container, you may see a small empty strip below it. This is not a bug. The image sits on the text baseline, and the space under the baseline is reserved for letters like "g" and "y".
There are two simple fixes.
/* Fix 1: make the image a block */
img {
display: block;
}
/* Fix 2: align it to the bottom of its line */
img {
vertical-align: middle;
}
Many developers add one of these to every project. A common choice is display: block for large images and vertical-align: middle for icons beside text.
Making Images Fit: A Few Lines of CSSβ
An image keeps its natural size unless told otherwise. A photograph that is 3000 pixels wide will overflow a phone screen. This short rule makes images shrink to fit their container, and never grow beyond their real size.
img {
max-width: 100%;
height: auto;
}
max-width: 100%stops the image from being wider than its container.height: autokeeps the proportions, so the picture is not squashed.
height: auto with width and height attributesWhen you set width and height in HTML and use max-width: 100%, add height: auto too. Without it, the image may stay tall while its width shrinks, and look stretched.
Fitting an Image Into a Fixed Boxβ
Sometimes the box has a fixed shape, such as a square card. Use object-fit to decide how the picture fills it.
object-fit value | What happens |
|---|---|
fill | Stretches to fill the box. Can distort the image |
contain | Shows the whole image inside the box, with empty space if needed |
cover | Fills the box and crops the extra. Best for cards and avatars |
none | Keeps the original size |
scale-down | Uses none or contain, whichever is smaller |
.card img {
width: 100%;
height: 200px;
object-fit: cover;
object-position: center;
}
A Few More Handy Stylesβ
.avatar {
width: 64px;
height: 64px;
border-radius: 50%; /* a circle */
object-fit: cover;
}
.framed {
border: 4px solid #e2e8f0;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.15);
}
When an Image Does Not Loadβ
Images fail more often than you might think: a typo in the path, a deleted file, a slow network, or a blocked request. The browser shows a broken image icon, and the alt text appears in its place.
That is another reason alt matters: it is your fallback.
<img src="images/harbour.jpg" alt="Fishing boats resting in a calm harbor at sunrise" />
<!-- If the file is named harbor.jpg, the path above is wrong. Visitors see the alt text. -->
You can also react in JavaScript, for example to show a default picture.
<img
id="profile"
src="images/users/amara.jpg"
alt="Profile photo of Amara"
width="64"
height="64"
/>
<script>
const picture = document.getElementById("profile");
picture.addEventListener("error", () => {
picture.src = "images/users/default.png";
}, { once: true });
</script>
The { once: true } option makes sure the fallback runs only once, so a missing fallback file cannot cause an endless loop.
Quick Debugging Checklistβ
- Check the path. Is it relative to the right folder? See Relative URLs.
- Check the spelling and case.
Photo.JPGis notphoto.jpgon most servers. - Check the file exists and was uploaded.
- Open the browser's developer tools. The Network tab shows failed requests in red.
- Check the file type. A file that was renamed to
.jpgbut is really another format may fail to display.
Images That Are Linksβ
Wrap an <img> in an <a> to make it clickable. The alt text then becomes the link's name, so describe where the link goes.
<a href="/">
<img src="images/logo.svg" alt="CodeHarborHub home" width="140" height="40" />
</a>
img, picture, SVG, or CSS Background?β
You have several ways to show an image. Each has a place.
| Method | Best for | Notes |
|---|---|---|
<img> | Almost all content images | Accessible, searchable, easy to lazy-load |
<picture> | Different formats or crops for different screens | Contains an <img>. See Picture Element |
Inline <svg> | Icons and graphics you want to style or animate | Part of the page's HTML |
<img src="file.svg"> | A logo or illustration as a separate file | Cacheable and simple |
CSS background-image | Decoration that carries no meaning | Has no alt, so keep it for purely visual use |
The rule of thumb: if the image means something to the reader, use <img>. If it is only decoration, a CSS background is fine.
Common Mistakesβ
Mistake 1: Forgetting altβ
Every <img> needs an alt. Use an empty one for decoration, never leave it out.
Mistake 2: Using a huge file for a tiny spaceβ
A 4000-pixel photo shown at 300 pixels wastes data and time. Resize it first.
Mistake 3: Squashing an image with the wrong width and heightβ
Set values that match the image's real proportions, and use height: auto in CSS.
Mistake 4: Putting content inside <img>β
It is a void element. Text placed between <img> and </img> is invalid.
Mistake 5: Using a CSS background for an important pictureβ
Without alt, a screen reader skips it, and search engines may ignore it.
Mistake 6: Not testing on a slow connectionβ
Use the developer tools to slow the network down, then see how your page loads.
Mistake 7: Hot-linking someone else's imageβ
It uses their bandwidth, it can break without warning, and it may break copyright rules. Use your own copy, and only if you have the right to.
Try It Yourselfβ
Here is a short project.
- Create a folder
imagesand put two pictures in it: one photo and one small icon. - Create
gallery.htmlwith an<h1>and add both images withsrc,alt,width, andheight. - Add
img { max-width: 100%; height: auto; }in a<style>block. Resize the browser window. What happens? - Put the photo alone in a
<div>. Do you see a gap below it? Fix it withdisplay: block. - Make a card with a fixed-height box and test the
object-fitvaluescontainandcover. - Break the
srcon purpose. What do you see? Check that thealttext makes sense on its own. - Wrap the icon in a link and write
alttext that says where it goes. - Add
fetchpriority="high"to the first image andloading="lazy"to the second.
Quick Recapβ
Click a question to check your answer.
1. Why is <img> called a replaced element?
Its content comes from an external file that the browser fetches and puts in its place. The element itself holds nothing.
2. Is <img> a block or an inline element by default?
Inline. It sits in the flow of text, aligned to the text baseline.
3. What two CSS lines make images fit their container?
max-width: 100%; and height: auto;.
4. What does object-fit: cover do?
It makes the image fill its box completely and crops whatever does not fit, without distorting it.
5. When is a CSS background better than <img>?
When the picture is only decoration and carries no meaning, because CSS backgrounds have no alt text.
Key Takeawaysβ
<img>is a void, inline, replaced element whose content comes from the file atsrc.- Always provide
alt, and addwidthandheightto reserve space. - Use
max-width: 100%andheight: autoso images fit any screen, andobject-fitfor fixed boxes. - Use
display: blockorvertical-alignto remove the small gap below an image. - Choose
<img>for meaningful content, and prepare for failure with goodalttext and a clear debugging routine.
Now you know how the element works. Next, learn how to point to the right file and describe it well in Src and Alt.