#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 -->