HTML Image Size
Setting an image size in HTML takes two attributes and about ten seconds. Knowing which number to put in them, and why you still need CSS as well, is the part that actually affects how your page looks and how fast it feels.
The short answer
Put width and height on the img tag, using the image file's real pixel dimensions:
<img src="/photo.jpg" width="800" height="600" alt="Harbour at sunrise">
Plain integers. No px, no quotes around units, no percentages. The values are CSS pixels, and they describe the file, not the slot you want it to sit in.
The rules for the attributes
| Written as | Valid? | Why |
|---|---|---|
| width="800" | Yes | A non-negative integer is exactly what HTML5 asks for |
| width="800px" | No | Units are not allowed; browsers may ignore the value |
| width="50%" | No | Valid in HTML 4, dropped in HTML5. Use CSS for relative sizing |
| width="800" only | Incomplete | Scales correctly but reserves no space, so the page shifts on load |
Why you should always set both
For years the advice was to leave sizing to CSS entirely. That reversed once browsers started deriving an aspect ratio from the two attributes. Modern browsers apply an internal rule equivalent to this:
img {
aspect-ratio: attr(width) / attr(height);
}The practical effect: the browser knows the shape of the image before a single byte of it arrives, so it can reserve a correctly sized box in the layout immediately. Without the attributes it reserves nothing, the image pops in at full height when it finishes downloading, and everything below it jumps down the page. That jump is cumulative layout shift, one of the Core Web Vitals.
The catch is that this only works if your CSS lets the height stay flexible. Pair the attributes with the standard reset:
img {
max-width: 100%;
height: auto;
}HTML attributes vs CSS: which wins
CSS wins, always. The width and height attributes are what the spec calls presentational hints. They land at the very bottom of the cascade, below any rule you write yourself, so even a single unscoped img { width: 300px } overrides them.
This is why the two are not in conflict and you want both. Think of it as a division of labour:
HTML attributes
Describe the file. They tell the browser the intrinsic size and therefore the aspect ratio, before the download completes. Set once, from the real dimensions.
CSS
Describes the layout. It decides how much room the image gets on this particular page at this particular viewport width. Change it freely per breakpoint.
The modern recipe
Putting it together, a well-formed image in 2026 looks like this:
<img
src="/photo-800.jpg"
width="800"
height="600"
alt="Harbour at sunrise"
loading="lazy"
decoding="async"
>
<style>
img { max-width: 100%; height: auto; }
</style>One caveat on loading="lazy": leave it off anything visible in the first screenful. Lazy-loading your hero image delays the largest contentful paint rather than helping it.
Sizing responsively with srcset
A single fixed size cannot suit both a phone and a desktop. Offer the browser a set of files and tell it how wide the image will be rendered, and it picks the right one for the screen it is on:
<img
src="/photo-800.jpg"
srcset="/photo-400.jpg 400w,
/photo-800.jpg 800w,
/photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
width="800"
height="600"
alt="Harbour at sunrise"
>The w descriptors are the real widths of each file. sizes describes the slot the image will occupy, which the browser needs before layout happens. Keep the width and height attributes on as well; all the candidates share an aspect ratio, so they still do their job.
Forcing an image into an exact box
Sometimes you need every thumbnail in a grid to be identical regardless of what shape the originals are. Set the box, then tell the image how to fill it:
.thumb {
width: 300px;
height: 300px;
object-fit: cover; /* fill the box, crop the overflow */
object-position: center;
}Use cover to crop and contain to letterbox. Without object-fit, fixing both dimensions in CSS simply squashes the image out of proportion.
The mistake the attributes cannot fix
Shrinking an image with width does not shrink the download. A 4000-pixel-wide photo displayed at width="400" still transfers every byte of the original; the browser just draws it small. Because file size tracks area rather than width, an image twice as wide as it needs to be is roughly four times the bytes.
The fix is to resize the file itself, not the tag. Our image compressor does it in your browser, and natural vs rendered dimensions explains how far apart the two numbers are allowed to drift.
Finding the numbers to put in the attributes
The attributes are only useful if they match the file. Three ways to get the real dimensions:
- One image, from its URL: paste it into the image dimension finder.
- Every image on a page at once: the website image checker reports natural and rendered size for each one, including CSS backgrounds.
- In the console: read them off the element directly.
document.querySelectorAll('img').forEach(img => {
console.log(img.src, img.naturalWidth, img.naturalHeight);
});Check whether your width and height attributes match the actual files.
Scan a Page NowFrequently Asked Questions
How do you set image size in HTML?
Use the width and height attributes on the img tag: <img src="photo.jpg" width="800" height="600" alt="...">. Both values are plain integers in CSS pixels, with no units and no px suffix. Set both, not just one, so the browser can reserve the right amount of space before the image downloads.
Can I use a percentage in the HTML width attribute?
No. Percentages in the width and height attributes were valid in HTML 4 but are not valid in HTML5, which requires a non-negative integer. If you want percentage-based sizing, do it in CSS with width: 50% instead. The attributes should carry the intrinsic pixel dimensions of the file.
Should I set image size in HTML or CSS?
Both, and they do different jobs. Put the image file’s real pixel dimensions in the HTML width and height attributes so the browser knows the aspect ratio before the file arrives. Then control how big it actually appears with CSS. This is not duplication: the attributes reserve space, the CSS does the layout.
Does CSS override the HTML width attribute?
Yes. The width and height attributes are presentational hints with lower priority than any author stylesheet rule, so a CSS width always wins. That is why the standard reset img { max-width: 100%; height: auto; } works even on images that carry explicit width and height attributes.
What happens if I set only the width and not the height?
The image still scales proportionally, because the browser derives the missing dimension from the file’s aspect ratio. But it cannot do that until the file has loaded, so the space is not reserved in advance and the page contents jump when the image appears. That jump is cumulative layout shift, and setting both attributes is what prevents it.
What is the correct image size to use in HTML?
Match the attributes to the image file’s actual pixel dimensions, then serve a file roughly one to two times the width it will be displayed at. An image shown in a 400 CSS-pixel slot wants a source around 800 pixels wide to stay sharp on a 2x screen. Much larger than that and you are downloading pixels nobody will see.
Checking images at scale?
Bulk-audit hundreds of URLs at once or hit a dimensions API from your own code.