Web

Transparent PNG images on websites: HTML, CSS and performance

How to add transparent PNGs to a web page the right way: img vs background images, alt text, responsive sizes, lazy loading, dark mode, WebP fallbacks and recolouring with CSS.

By the pngtop team · · 4 min read

Transparent PNGs let a product, character or illustration sit directly on your page design, without a box around it. Used well, they make a site look polished. Used carelessly, they make it slow and inaccessible. This guide covers the techniques that matter.

<img> or CSS background?

Use an <img> element when the image is content: a product, a diagram, a person, an illustration that explains something. It can have alt text, it is found by search engines, and browsers can load it efficiently.

<img
  src="/images/coffee-cup.png"
  alt="Paper coffee cup with a brown sleeve"
  width="600"
  height="600"
  loading="lazy"
  decoding="async"
>

Use a CSS background when the image is purely decorative, such as a leaf in a corner or a splash behind a heading:

.hero {
  background: url(/images/leaf-corner.png) no-repeat right top / 240px auto;
}

Decorative images in CSS are skipped by screen readers, which is what you want.

Always set width and height

Adding width and height attributes lets the browser reserve the right space before the image loads, so the page does not jump around. It does not stop the image being responsive; combine it with CSS:

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

Write useful alt text

Alt text describes the image for people using screen readers and for search engines.

  • Describe what matters in context: "Red sports car, side view" rather than "car.png".
  • Do not start with "image of".
  • For decorative images in <img> elements, use an empty alt (alt="") so screen readers skip them.

Serve the right size

A 3000-pixel PNG shown at 400 pixels wastes bandwidth and slows the page, especially on phones. Resize images to roughly the largest size they are displayed at, doubled for high-density screens. Then let the browser choose:

<img
  src="/images/burger-800.png"
  srcset="/images/burger-400.png 400w, /images/burger-800.png 800w, /images/burger-1600.png 1600w"
  sizes="(max-width: 600px) 90vw, 400px"
  alt="Cheeseburger with lettuce and tomato"
  width="800" height="800"
>

Consider WebP with transparency

WebP supports transparency and is usually much smaller than PNG for photographic images. Use the <picture> element to offer WebP with a PNG fallback:

<picture>
  <source srcset="/images/sneaker.webp" type="image/webp">
  <img src="/images/sneaker.png" alt="White running sneaker" width="800" height="600">
</picture>

PNG remains the better choice for screenshots, line art and images where every pixel must stay exact. Our comparison of PNG, JPG, WebP and SVG goes into the details, and the guide to optimizing PNG file size shows how to compress PNGs you keep.

Lazy loading

Add loading="lazy" to images below the first screen. The browser then waits to download them until the visitor scrolls near them. Do not lazy-load the main image at the top of the page; it should load as early as possible, and can be marked with fetchpriority="high".

Dark mode and coloured backgrounds

A PNG that looks perfect on white can look wrong on a dark background:

For simple dark icons, a CSS filter can invert them in dark mode:

@media (prefers-color-scheme: dark) {
  .icon-dark-on-light {
    filter: invert(1);
  }
}

For anything more complex, provide a second version of the image and switch with <picture>:

<picture>
  <source srcset="/images/logo-light.png" media="(prefers-color-scheme: dark)">
  <img src="/images/logo-dark.png" alt="Company logo" width="200" height="60">
</picture>

Recolouring icons with CSS masks

A single-colour PNG icon can take any colour using mask:

.icon-cart {
  width: 24px;
  height: 24px;
  background-color: currentColor;
  -webkit-mask: url(/icons/cart.png) no-repeat center / contain;
  mask: url(/icons/cart.png) no-repeat center / contain;
}

The icon now follows the text colour, including hover states and dark mode. More approaches are in our guide to changing the colour of a PNG.

Shadows that follow the shape

box-shadow draws a rectangle around the image box, which looks wrong on a cut-out. Use filter: drop-shadow() instead, which follows the transparent outline:

.product {
  filter: drop-shadow(0 12px 18px rgba(0, 0, 0, 0.18));
}

Overlapping layouts

Transparent images are perfect for letting an object break out of a card or section:

.card {
  position: relative;
  overflow: visible;
  padding-top: 120px;
}
.card img {
  position: absolute;
  top: -80px;
  left: 50%;
  transform: translateX(-50%);
  width: 220px;
}

Respect image rights

Images on your website are publicly visible and easy to find. Use images you are allowed to use for that purpose, avoid implying endorsement by brands or people shown, and keep a note of where each image came from. Our guide to using free PNG images responsibly explains what to check.

Quick checklist

  • <img> for content, CSS backgrounds for decoration.
  • Width, height and meaningful alt text on every content image.
  • Resized and compressed files; WebP where it helps.
  • loading="lazy" below the fold, high priority for the hero.
  • drop-shadow() instead of box-shadow for cut-outs.
  • Tested on light and dark backgrounds.