Skip to main content

Images Tutorial

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

  1. It's just a wrapper for the img
  2. 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
  3. The img tag also caries the alt description, width, size, styles etc. which is used for all images
  4. The source tags contain rules like type or media which the browser uses to pick the best image
  5. The source also supports the same srcset and sizes just like the img tag
  6. Important: you must use srcset and not src on the source tags
  7. 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 srcset demo

<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&amp;h=865&amp;quality=75&amp;mode=crop&amp;scale=both'>
<img src='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&amp;h=865&amp;quality=75&amp;mode=crop&amp;scale=both' loading='lazy' class='img-fluid' width='1400' height='865'>
</picture>

Automatically Resized With Custom Alt and Classes

This is the ALT text

@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&amp;h=865&amp;quality=75&amp;mode=crop&amp;scale=both'>
<img src='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&amp;h=865&amp;quality=75&amp;mode=crop&amp;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&amp;h=865&amp;quality=75&amp;mode=crop&amp;scale=both'>
  <img src='/Portals/0/2sxc/Tutorial-Razor/img/assets/jellyfish-img-srcset-2000.jpg?w=1400&amp;h=865&amp;quality=75&amp;mode=crop&amp;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&amp;h=865&amp;quality=75&amp;mode=crop&amp;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)

Source Code of this file

Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code

@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 &amp 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 -->