Headers & Images

Optimizing Images for Fast HTML and CSS Web Templates

Images are usually the heaviest files on a template page and the main cause of content jumping around while it loads. Better formats, sensible compression, size attributes and lazy loading deal with both.

· 6 min read

Assorted printed photographs spread across a beige wooden table
Assorted printed photographs spread across a beige wooden table. Photo: Soragrit Wongsa / Unsplash

Pick a modern format

Many templates still ship with large JPEG photos and PNG graphics. Switching to newer formats is the quickest way to cut page weight without visible loss.

WebP handles both lossy and lossless compression, supports transparency and can replace animated GIFs at a fraction of their size. For photographs it typically produces noticeably smaller files than JPEG at similar quality.

AVIF, based on the AV1 video codec, usually compresses photos further still and handles smooth gradients with fewer artifacts. Encoding takes longer, which matters when you process many images, but the browser does not pay that cost.

Both formats are supported in all current major browsers. A picture element offers them in order of preference with a JPEG fallback:

<picture>
  <source srcset="studio.avif" type="image/avif">
  <source srcset="studio.webp" type="image/webp">
  <img src="studio.jpg" width="1200" height="800"
       alt="Wooden desk with a laptop, notebook and coffee cup">
</picture>

The browser checks each source in order and uses the first type it supports. If it supports neither, it loads the JPEG. Only one file is downloaded either way.

Compress with your eyes open

Choosing a format is half the job. The compression settings decide the rest.

Lossy compression throws away detail the eye is unlikely to notice. It suits photographs and other images with continuous tones. Every encoder has a quality setting, and the numbers mean different things in different tools, so there is no universal right value. Export a few versions, view them at actual size next to each other, and choose the smallest one that still looks clean. Push too far and you get blocky patches, smeared texture and banding in skies.

Lossless compression keeps every pixel. Use it for screenshots, interface graphics, line art and logos with sharp edges, where lossy artifacts show up immediately. Whatever the format, strip metadata on export. Camera details, location data and editing history add weight and can reveal more than you intend.

Resize before you compress. A photo straight from a camera is often several thousand pixels wide. If the layout never shows it wider than 1,200 CSS pixels, export it at that size for standard screens and at double that for high-density displays, using srcset to let the browser choose.

SVG needs its own cleanup

Icons and simple illustrations are often best as SVG, which stays sharp at any size. Files exported from design applications tend to carry editor metadata, hidden layers, unused definitions and overly precise path coordinates. Running them through an SVG optimizer removes most of that, and the files often shrink considerably without any visible change.

Reserve space with width and height

When a browser lays out a page before an image has downloaded, it does not know how tall the image will be. Without help, it reserves no space, then pushes everything below down once the image arrives. That jump is what layout shift metrics measure, and readers notice it when a paragraph moves just as they start reading.

The fix is to put the image's real pixel dimensions in the markup:

<img src="cards.webp" width="1200" height="675"
     alt="Three product cards arranged in a row">

Then let CSS keep the image flexible:

img {
  max-width: 100%;
  height: auto;
}

The browser uses the two attributes to work out the aspect ratio, reserves a box of the right shape at whatever width the layout gives it, and fills it when the file arrives. The attributes do not fix the displayed size; the CSS still controls that. When an element uses srcset, give width and height the dimensions of any one of the candidates, since they all share the same ratio.

Lazy load what sits below the fold

Downloading every image on a long page at once wastes data and competes with the images people actually see first. Native lazy loading tells the browser to wait until an image is close to the viewport:

<img src="gallery-04.webp" width="800" height="600"
     alt="Close-up of a hand-drawn page wireframe"
     loading="lazy" decoding="async">

The browser decides how early to start fetching, and the distance can vary with the connection. The decoding="async" hint lets the browser decode the image without holding up other rendering work.

Leave lazy loading off anything visible on the first screen. The header image, the lead image of an article and a product's main photo should load as early as possible. Lazy loading them delays Largest Contentful Paint, the metric that tracks when the main content appears. A gallery further down, images inside a long article and footer graphics are good candidates. Native lazy loading also replaces the script-based techniques older templates used, so you can usually remove those libraries.

Write alt text that does a job

Alt text replaces the image for people who cannot see it and for anyone whose connection fails to load it. Describe what matters about the image in its context, briefly. Skip phrases like "image of", since screen readers already announce that it is an image.

When an image is the only content of a link or button, the alt text should describe the action, not the picture. A magnifying glass icon that submits a search should read "Search", not "magnifying glass".

Purely decorative images, such as background textures, dividers and ornamental shapes, should have an empty alt="", which tells screen readers to skip them. Leaving the attribute out entirely is not the same: many screen readers then fall back to reading the file name.

Keep track of image licenses

Templates that will be shared or sold often include sample photos. Each one comes with its own license, and terms differ. Some free photo libraries allow commercial use without attribution, others ask for credit, and Creative Commons licenses range from attribution only to no commercial use at all. Read the license for every image, and keep any credit it requires.

The simplest way to keep track is a credits file in the project folder that lists each image file, its source, its author and the license. Where credit should be visible, a caption does the job:

<figure>
  <img src="team-meeting.webp" width="800" height="533"
       alt="Four people talking around a table covered in sketches">
  <figcaption>Photo by the photographer's name, used under the license stated in CREDITS.txt</figcaption>
</figure>

Anyone customizing the template later can then see at a glance which images they may keep and which they need to replace. This is practical housekeeping rather than legal advice, so when a project depends on the terms, have them checked properly.

Frequently asked questions

What is the difference between WebP and AVIF?

Both compress photos much better than JPEG. AVIF usually produces smaller files at similar quality but takes longer to encode. Both are supported in all current major browsers, and a picture element with a JPEG fallback covers older ones.

Why add width and height attributes to images?

They tell the browser the image's aspect ratio before the file arrives, so it can reserve the right amount of space. With height set to auto in CSS, the image still scales with its container, and the page does not jump as images load.

Which images should not be lazy loaded?

Anything visible when the page first opens, especially the hero or header image and the main image of an article. Lazy loading them delays the largest visible element. Use loading="lazy" for images further down the page.

What alt text should decorative images have?

An empty alt attribute, written alt="". Screen readers then skip the image. Leaving alt out entirely is different and often makes screen readers announce the file name instead.

More in Headers & Images