Skip to content

Bits of .NET

Daily micro-tips for C#, SQL, performance, and scalable backend engineering.

  • Asp.Net Core
  • C#
  • SQL
  • JavaScript
  • CSS
  • About
  • ErcanOPAK.com
  • No Access
  • Privacy Policy
HTML

HTML5: Use Picture Element for Responsive Images (Better Than srcset)

- 03.02.26 - ErcanOPAK

Serving same 4K image to mobile users? Picture element lets you serve different images per device, saving 80% bandwidth and loading 3x faster.

The Old Way – One Image for All:

<img src="hero-4k.jpg" alt="Hero" />

<!-- Problems:
- Mobile downloads 5MB 4K image
- Only displays 800px wide on phone
- Wasted 80% of bandwidth
- 5 second load time on mobile
-->

Better – srcset Attribute:

<img 
    src="hero-1x.jpg" 
    srcset="hero-1x.jpg 1x, hero-2x.jpg 2x, hero-3x.jpg 3x"
    alt="Hero" 
/>

<!-- Browser picks based on screen density
- 1x: Standard displays (1920×1080)
- 2x: Retina displays  
- 3x: High-end mobile
-->

Best – Picture Element (Full Control):

<picture>
    <!-- Mobile: small image -->
    <source 
        media="(max-width: 480px)" 
        srcset="hero-mobile.jpg"
    />
    
    <!-- Tablet: medium image -->
    <source 
        media="(max-width: 1024px)" 
        srcset="hero-tablet.jpg"
    />
    
    <!-- Desktop: large image -->
    <source 
        media="(min-width: 1025px)" 
        srcset="hero-desktop.jpg"
    />
    
    <!-- Fallback for old browsers -->
    <img src="hero-desktop.jpg" alt="Hero" />
</picture>

<!-- Result:
Mobile (480px): Downloads 200KB image
Tablet (1024px): Downloads 500KB image  
Desktop (1920px): Downloads 1.5MB image
= Smart bandwidth usage
-->

Advanced – Modern Image Formats:

<picture>
    <!-- AVIF (best compression, newest) -->
    <source type="image/avif" srcset="hero.avif" />
    
    <!-- WebP (great compression, widely supported) -->
    <source type="image/webp" srcset="hero.webp" />
    
    <!-- JPEG (fallback for old browsers) -->
    <img src="hero.jpg" alt="Hero" />
</picture>

<!-- Browser picks best format it supports:
Chrome 90+: Uses AVIF (70% smaller than JPEG)
Chrome 80+: Uses WebP (30% smaller than JPEG)
Old browsers: Uses JPEG
-->

Combine Both – Format AND Size:

<picture>
    <!-- Mobile AVIF -->
    <source 
        media="(max-width: 480px)"
        type="image/avif"
        srcset="hero-mobile.avif"
    />
    
    <!-- Mobile WebP -->
    <source 
        media="(max-width: 480px)"
        type="image/webp"
        srcset="hero-mobile.webp"
    />
    
    <!-- Mobile JPEG -->
    <source 
        media="(max-width: 480px)"
        srcset="hero-mobile.jpg"
    />
    
    <!-- Desktop AVIF -->
    <source 
        media="(min-width: 1025px)"
        type="image/avif"
        srcset="hero-desktop.avif"
    />
    
    <!-- Desktop WebP -->
    <source 
        media="(min-width: 1025px)"
        type="image/webp"
        srcset="hero-desktop.webp"
    />
    
    <!-- Fallback -->
    <img src="hero-desktop.jpg" alt="Hero" />
</picture>

Art Direction – Different Crops:

<picture>
    <!-- Mobile: Portrait crop (vertical) -->
    <source 
        media="(max-width: 480px)" 
        srcset="hero-portrait.jpg"
    />
    
    <!-- Tablet: Square crop -->
    <source 
        media="(max-width: 1024px)" 
        srcset="hero-square.jpg"
    />
    
    <!-- Desktop: Landscape crop (horizontal) -->
    <source 
        media="(min-width: 1025px)" 
        srcset="hero-landscape.jpg"
    />
    
    <img src="hero-landscape.jpg" alt="Hero" />
</picture>

<!-- Use case: Hero images where composition matters
Mobile: Show person's face (vertical crop)
Desktop: Show full scene (horizontal crop)
-->

Lazy Loading with Picture:

<picture>
    <source 
        media="(max-width: 480px)" 
        srcset="hero-mobile.webp"
        type="image/webp"
    />
    
    <img 
        src="hero-desktop.jpg" 
        alt="Hero"
        loading="lazy"  <!-- Native lazy load -->
    />
</picture>

<!-- Images below fold don't load until user scrolls -->

Performance Comparison:

Same image (1920×1080 hero photo):

Single JPEG (4K optimized):
- File size: 2.5 MB
- Mobile load time: 8 seconds (3G)
- Desktop load time: 1.2 seconds (WiFi)

Picture element with WebP + responsive sizes:
- Mobile: 180 KB (94% smaller!)
- Tablet: 450 KB  
- Desktop WebP: 820 KB (67% smaller!)
- Mobile load time: 1.5 seconds (3G)
- Desktop load time: 0.4 seconds

= 5-6x faster on mobile!

Browser Support:

Picture element: 98% (all modern browsers)
AVIF: 85% (Chrome 85+, Firefox 93+, Safari 16+)
WebP: 97% (all except IE)

Always include JPEG fallback for <2% old browsers

Related posts:

HTML5 Forms: The Built-In Validation That Replaced jQuery Validate

HTML5: Pro Form Validation without a Single Line of JavaScript

Javascript Refresh and CountDown Timer

Post Views: 3

Post navigation

CSS: Create Smooth Skeleton Loading Screens with Pure CSS (No JavaScript)
JavaScript: Use Optional Chaining to Prevent ‘Cannot Read Property of Undefined’ Errors

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

April 2026
M T W T F S S
 12345
6789101112
13141516171819
20212223242526
27282930  
« Mar    

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (950)
  • How to add default value for Entity Framework migrations for DateTime and Bool (858)
  • Get the First and Last Word from a String or Sentence in SQL (836)
  • How to select distinct rows in a datatable in C# (805)
  • How to make theater mode the default for Youtube (753)
  • Add Constraint to SQL Table to ensure email contains @ (578)
  • How to enable, disable and check if Service Broker is enabled on a database in SQL Server (564)
  • Average of all values in a column that are not zero in SQL (531)
  • How to use Map Mode for Vertical Scroll Mode in Visual Studio (489)
  • Find numbers with more than two decimal places in SQL (447)

Recent Posts

  • C#: Use Init-Only Setters for Immutable Objects After Construction
  • C#: Use Expression-Bodied Members for Concise Single-Line Methods
  • C#: Enable Nullable Reference Types to Eliminate Null Reference Exceptions
  • C#: Use Record Types for Immutable Data Objects
  • SQL: Use CTEs for Readable Complex Queries
  • SQL: Use Window Functions for Advanced Analytical Queries
  • .NET Core: Use Background Services for Long-Running Tasks
  • .NET Core: Use Minimal APIs for Lightweight HTTP Services
  • Git: Use Cherry-Pick to Apply Specific Commits Across Branches
  • Git: Use Interactive Rebase to Clean Up Commit History Before Merge

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (950)
  • How to add default value for Entity Framework migrations for DateTime and Bool (858)
  • Get the First and Last Word from a String or Sentence in SQL (836)
  • How to select distinct rows in a datatable in C# (805)
  • How to make theater mode the default for Youtube (753)

Recent Posts

  • C#: Use Init-Only Setters for Immutable Objects After Construction
  • C#: Use Expression-Bodied Members for Concise Single-Line Methods
  • C#: Enable Nullable Reference Types to Eliminate Null Reference Exceptions
  • C#: Use Record Types for Immutable Data Objects
  • SQL: Use CTEs for Readable Complex Queries

Social

  • ErcanOPAK.com
  • GoodReads
  • LetterBoxD
  • Linkedin
  • The Blog
  • Twitter
© 2026 Bits of .NET | Built with Xblog Plus free WordPress theme by wpthemespace.com