WebP and AVIF through the native <picture> element is one of the highest-return optimisations you can make in 2025, and it requires zero build tooling once you understand the markup pattern. This guide shows you exactly how to do it inside a static HTML template, with real code you can copy into any project today.
Key Takeaways
- AVIF offers the best compression of any mainstream format, typically 50 percent smaller than JPEG at equivalent quality, but encoding is slow and browser support reached roughly 96 percent globally only in 2024.
- WebP has near-universal support (97 percent-plus) and is the safe default modern format for most static sites right now.
- The
<picture>element lets browsers pick the best format they support without JavaScript, using a simple cascade of<source>tags. - Combining
srcsetandsizesinside<picture>gives you both format negotiation and resolution switching at the same time. - Static HTML templates such as the Canvas HTML Template do not convert images for you, so you must generate WebP and AVIF variants before referencing them in your markup.
- Lazy loading with
loading="lazy"and correctwidth/heightattributes on the fallback<img>prevent cumulative layout shift.
Why Image Format Choice Has a Direct Impact on Core Web Vitals
Largest Contentful Paint (LCP) is almost always triggered by a hero image or a large product photograph. Google’s Core Web Vitals thresholds require LCP under 2.5 seconds for a “good” score. A 400 KB JPEG hero image can push you over that threshold on a mid-range mobile connection by itself. Converting the same image to AVIF often brings it under 120 KB; WebP typically lands at 180 to 220 KB. The difference shows up in both Lighthouse scores and real user metrics.
Static HTML templates are particularly sensitive to this because there is no server-side processing layer to intercept requests and transcode images on the fly. Every byte you serve is a byte you chose to serve. That makes the image authoring step a deliberate engineering decision, not an afterthought.

WebP vs AVIF: Which Format to Use and When
WebP was introduced by Google in 2010 and is supported in all major browsers including Safari since version 14 (released 2020). It supports lossy compression, lossless compression, transparency, and animation. For most projects, WebP is the safe choice: support is effectively universal and encoding tools are mature.
AVIF is derived from the AV1 video codec. It achieves roughly 20 to 50 percent smaller file sizes than WebP at the same perceived quality, and it supports wide colour gamut (HDR), alpha channels, and film grain encoding. Browser support as of 2025 covers Chrome 85+, Firefox 93+, and Safari 16+. The practical compression advantage over WebP is real, but encoding AVIF is significantly slower. That matters when you are batch-converting hundreds of product images in a build pipeline.
When to skip AVIF: if your audience skews toward older iOS devices (pre-iPhone 14 running iOS 15) or you operate in enterprise environments with locked-down browsers, use WebP as your primary modern format and treat AVIF as an optional top layer rather than a requirement.
The picture Element: Syntax You Can Use Today
The <picture> element is a container. It holds one or more <source> elements followed by a mandatory <img> fallback. Browsers evaluate <source> tags top-to-bottom and use the first one they support. The <img> tag is what non-supporting browsers, screen readers, and crawlers see.
A minimal format-switching example looks like this:
<picture>
<source type="image/avif" srcset="hero.avif">
<source type="image/webp" srcset="hero.webp">
<img
src="hero.jpg"
alt="A team collaborating in a modern coworking space"
width="1200"
height="630"
loading="eager"
>
</picture>AVIF is listed first because it is the preferred format. WebP is next. JPEG is the fallback. A browser that supports all three picks AVIF. A browser that supports only WebP skips the AVIF source and picks WebP. Internet Explorer (officially retired) falls through to the <img> JPEG.

Adding srcset and sizes for Responsive Images
Format switching alone only solves half the problem. A 1200 px wide AVIF served to a phone with a 390 px viewport is still wasteful. Combine srcset with sizes to give the browser width variants alongside format variants.
<picture>
<source
type="image/avif"
srcset="
hero-400.avif 400w,
hero-800.avif 800w,
hero-1200.avif 1200w
"
sizes="(max-width: 576px) 100vw, (max-width: 992px) 80vw, 1200px"
>
<source
type="image/webp"
srcset="
hero-400.webp 400w,
hero-800.webp 800w,
hero-1200.webp 1200w
"
sizes="(max-width: 576px) 100vw, (max-width: 992px) 80vw, 1200px"
>
<img
src="hero-1200.jpg"
srcset="
hero-400.jpg 400w,
hero-800.jpg 800w,
hero-1200.jpg 1200w
"
sizes="(max-width: 576px) 100vw, (max-width: 992px) 80vw, 1200px"
alt="A team collaborating in a modern coworking space"
width="1200"
height="630"
loading="eager"
>
</picture>The breakpoints above (576 px, 992 px) align with Bootstrap 5’s sm and lg breakpoints, making this pattern a natural fit inside any Bootstrap-based static template. If you are already trimming your Bootstrap bundle to reduce CSS payload, pairing that work with proper image sizing delivers compounding performance gains.
Generating WebP and AVIF Files from Your Source Images
Static templates do not generate image variants for you. You need to create the files before referencing them. The three most practical approaches are:
- Squoosh CLI (free, no server required):
npx @squoosh/cli --avif '{}' --webp '{}' images/*.jpgprocesses an entire folder. Squoosh is maintained by the Google Chrome team and produces good results with sensible defaults. - Sharp (Node.js library): Integrate into an existing Gulp or Vite workflow with
sharp('input.jpg').avif({ quality: 65 }).toFile('output.avif'). Sharp uses libvips under the hood and is the fastest option for batch processing. - ImageMagick or libavif CLI: Suitable for CI/CD pipelines.
avifenc --min 30 --max 50 input.jpg output.avifgives you direct control over encoder settings.
For quality settings, start at 75 to 80 for WebP and 60 to 70 for AVIF (on a 0 to 100 scale). That range gives a reasonable balance of visual quality and file size for photographic content. Always do a visual comparison before committing to a quality value in production.
Integrating the Pattern Into a Static HTML Template
Inside a Bootstrap 5 static template, images almost always sit inside a containing column with a maximum width defined by the grid. A hero image in a full-width Bootstrap row needs the 1200 px variant as its largest srcset entry. A card image inside a col-md-4 column rarely needs anything wider than 600 px. Matching your srcset entries to the actual rendered width is where the real savings come from.
If you are using lightbox functionality, such as the pattern covered in the guide to adding GLightbox to Bootstrap 5, point the href attribute on the anchor to the full-size JPEG or WebP. Let the lightbox serve the high-resolution version while the grid thumbnail uses the optimised responsive markup.
Always include explicit width and height attributes on the <img> fallback. Bootstrap 5’s img-fluid class sets max-width: 100% and height: auto, which works correctly alongside these attributes. The browser uses the declared dimensions to reserve space before the image loads, preventing layout shift without any JavaScript.
<!-- Bootstrap 5 card with responsive WebP/AVIF image -->
<div class="card border-0 shadow-sm">
<picture>
<source type="image/avif" srcset="card-thumb.avif">
<source type="image/webp" srcset="card-thumb.webp">
<img
src="card-thumb.jpg"
class="card-img-top img-fluid"
alt="Project thumbnail"
width="600"
height="400"
loading="lazy"
>
</picture>
<div class="card-body">
<h3 class="card-title h5">Project Title</h3>
</div>
</div>Use loading="eager" on above-the-fold images (hero, first section) and loading="lazy" on everything below. Native lazy loading is reliable in all modern browsers and requires no JavaScript library.
Frequently Asked Questions
No. The <picture> element handles format negotiation entirely in the browser. You only need the physical image files to exist on your server or CDN. The browser reads the type attribute on each <source> and picks the first format it supports, with no server-side content negotiation required. You do need tooling (such as Squoosh CLI or Sharp) to generate the WebP and AVIF files before uploading them.
AVIF browser support is strong but not yet universal enough to use as a sole format. Chrome, Firefox, and Safari all support it, but older Safari versions (pre-16) on iOS do not. List AVIF first in the <picture> source order and fall back to WebP, which has effectively universal support. Capable browsers get AVIF; older ones get WebP without any penalty.
No. Bootstrap’s img-fluid and other image utility classes target the <img> element inside <picture>, and they work exactly as they would on a standalone <img>. Apply your Bootstrap classes directly to the <img> tag, not to the <picture> wrapper. The <picture> element itself is display inline by default; set it to display: block with a utility class if needed to avoid unwanted inline spacing.
For most use cases, three variants cover the practical range: a small version (400 px wide) for mobile, a medium version (800 px) for tablets and narrow desktop columns, and a large version (1200 to 1600 px) for full-width desktop sections. Hero images for very large monitors may warrant a 1920 px variant. Generating more than five variants per image rarely provides measurable benefit and significantly increases storage and maintenance overhead.
Google’s crawler understands the <picture> element and indexes images correctly. The alt attribute on the <img> fallback is the text Google uses for image search, so write descriptive alt text as you normally would. Using modern formats does not hurt indexing, and faster page load times improve overall search rankings through Core Web Vitals scoring.
Looking for a production-ready Bootstrap 5 HTML template? Browse Canvas Template demos and find the perfect starting point for your next project.
If you’re building with the Canvas HTML Template and want to ship production-ready Bootstrap 5 layouts faster, try Canvas Builder free — the visual builder that exports clean Canvas-ready markup in minutes.
Skip the setup and build it free
Spin up a complete Bootstrap 5 site, blog included, with Canvas Builder. No coding, no cost.
Canvas Team
Tutorials and tips for building beautiful Bootstrap 5 websites with the Canvas HTML Template and Canvas Builder.
More from the Canvas Blog