#7 Responsive and optimal Server-Side Images (picture)
Browser-Capabilities picture with different formats
The perfect image depends on browser capabilities.
The following example will get modern browsers a webp image (which is smaller/faster) and normal browsers a jpg.
Info about the Base Class
This tutorial inherits from the Custom.Hybrid.Razor14 base class.
This allows us to use Kit.Image to access IImageService without having to use GetService<>
What you need to know about picture
- It's just a wrapper for the
img
- You always need an
img tag inside it, and this is what old browsers like IE6 will take even if they don't understand picture
- The
img tag also caries the alt description, width, size, styles etc. which is used for all images
- The
source tags contain rules like type or media which the browser uses to pick the best image
- The
source also supports the same srcset and sizes just like the img tag
- Important: you must use
srcset and not src on the source tags
- Important: Order matters! Put the
source tags first in the order you need, as the first match will be taken.
<picture>
<source type="image/webp" srcset="@App.Path/img/assets/koi-400.webp">
<source type="image/png" srcset="@App.Path/img/assets/koi-400.png">
<img style="width: 40%;" src="@App.Path/img/assets/jellyfish-1000.jpg">
</picture>
Responsive picture with many resolutions
The perfect image is often different depending on the screen size.
The following example will get two different sizes, depending on the screen size.
Try resizing the screen and watch the network (F12) to see when the other sizes are loaded.
<picture>
<source type="image/webp"
srcset="@App.Path/img/assets/koi-img-srcset-2000.webp 2000w,
@App.Path/img/assets/koi-img-srcset-1000.webp 1000w,
@App.Path/img/assets/koi-img-srcset-500.webp 500w,
@App.Path/img/assets/koi-img-srcset-250.webp 250w,"
sizes="(max-width: 300px) 250px, (max-width: 600px) 500px, (max-width: 1200px) 1000px, 2000px">
<source type="image/png"
srcset="@App.Path/img/assets/jellyfish-img-srcset-2000.jpg 2000w,
@App.Path/img/assets/jellyfish-img-srcset-1000.jpg 1000w,
@App.Path/img/assets/jellyfish-img-srcset-500.jpg 500w,
@App.Path/img/assets/jellyfish-img-srcset-250.jpg 250w,"
sizes="(max-width: 300px) 250px, (max-width: 600px) 500px, (max-width: 1200px) 1000px, 2000px">
<img class="img-fluid" src="@App.Path/img/assets/jellyfish-img-srcset-1000.jpg" alt="Picture srcset demo">
</picture>
Automatically Resized Files & Formats
@Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg")
This generates
<picture>
<source type='image/jpeg' srcset='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both'>
<img src='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both' loading='lazy' class='img-fluid' width='1400' height='865'>
</picture>
Automatically Resized With Custom Alt and Classes
@Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg", imgAlt: "This is the ALT text", imgClass: "dummy-class")
This generates
<picture>
<source type='image/jpeg' srcset='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both'>
<img src='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both' loading='lazy'
alt='This is the ALT text' class='dummy-class img-fluid' width='1400' height='865'>
</picture>
Automatically Resized Bits with More Control
@{
var picControlled = Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg");
}
<picture>
@picControlled.Sources
@picControlled.Img.Id("some-id").Style("width: 75%").Title("Mouseover this!")
</picture>
This generates
<picture>
<source type='image/jpeg' srcset='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both'>
<img src='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both' loading='lazy' class='img-fluid' width='1400' height='865' id='some-id' style='width: 75%;width: 75%' title='Mouseover this!'>
</picture>
Automatically Resized Bits with Lots of Control
@{
var picFullControl = Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg");
}
<picture>
@foreach(var st in picFullControl.Sources){
@st
}
<img src='@picFullControl.Src' style='width: 50%' class='border border-primary'>
</picture>
This generates
<picture>
<source type='image/jpeg' srcset='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both'>
<img src='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&h=865&quality=75&mode=crop&scale=both' style='width: 50%' class='border border-primary'>
</picture>
#7 Responsive and optimal Server-Side Images (picture)
@inherits Custom.Hybrid.Razor14
<!-- unimportant stuff, hidden -->
Browser-Capabilities picture with... <!-- unimportant stuff, hidden -->
@Html.Partial("../shared/_KitBaseClassInfoBox.cshtml", new { ServiceName = "Image", Service = "IImageService" })
<!-- unimportant stuff, hidden -->
<picture>
<source type="image/webp" srcset="@App.Path/img/assets/koi-400.webp">
<source type="image/png" srcset="@App.Path/img/assets/koi-400.png">
<img style="width: 40%;" src="@App.Path/img/assets/jellyfish-1000.jpg">
</picture>
<br>
<code id="demo-picture-formats-label"></code>
Responsive picture with many resolutions... <!-- unimportant stuff, hidden -->
<picture>
<source type="image/webp"
srcset="@App.Path/img/assets/koi-img-srcset-2000.webp 2000w,
@App.Path/img/assets/koi-img-srcset-1000.webp 1000w,
@App.Path/img/assets/koi-img-srcset-500.webp 500w,
@App.Path/img/assets/koi-img-srcset-250.webp 250w,"
sizes="(max-width: 300px) 250px, (max-width: 600px) 500px, (max-width: 1200px) 1000px, 2000px">
<source type="image/png"
srcset="@App.Path/img/assets/jellyfish-img-srcset-2000.jpg 2000w,
@App.Path/img/assets/jellyfish-img-srcset-1000.jpg 1000w,
@App.Path/img/assets/jellyfish-img-srcset-500.jpg 500w,
@App.Path/img/assets/jellyfish-img-srcset-250.jpg 250w,"
sizes="(max-width: 300px) 250px, (max-width: 600px) 500px, (max-width: 1200px) 1000px, 2000px">
<img class="img-fluid" src="@App.Path/img/assets/jellyfish-img-srcset-1000.jpg" alt="Picture srcset demo">
</picture>
<code id="demo-picture-srcset-label"></code>
<hr>
<h2>Automatically Resized Files & Formats</h2>
@Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg")
<code id="pic-auto-label"></code>
<hr>
<h2>Automatically Resized With Custom Alt and Classes</h2>
@Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg", imgAlt: "This is the ALT text", imgClass: "dummy-class")
<code id="pic-auto-label"></code>
<hr>
<h2>Automatically Resized Bits with More Control</h2>
@{
var picControlled = Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg");
}
<picture>
@picControlled.Sources
@picControlled.Img.Id("some-id").Style("width: 75%").Title("Mouseover this!")
</picture>
<br>
<code id="pic-auto-control1-label"></code>
<hr>
<h2>Automatically Resized Bits with Lots of Control</h2>
@{
var picFullControl = Kit.Image.Picture(App.Path + "/img/assets/jellyfish-img-srcset-2000.jpg");
}
<picture>
@foreach(var st in picFullControl.Sources){
@st
}
<img src='@picFullControl.Src' style='width: 50%' class='border border-primary'>
</picture>
<br>
<code id="pic-auto-control2-label"></code>
<!-- unimportant stuff, hidden -->