Advertisement

#18 Responsive Images

In this article we will see how to deal with a couple of different problems, namely the resolution switching and art direction problems, related to the use of images on our site. We will see how to use the built in browser capabilities to dynamically switch to the appropriate image based on the device the user is using to visit our site.

The page model

  • WebUi
    • Pages
      • Responsive-Images.cshtml.cs

The first thing we are going to do is create a razor page where we can explore a couple different problems we may encounter when dealing with images and their solutions. To do this we need to have a page model that we can use to easily switch between them (a). We will use the Problem property to specify the type of problem and the Query property to explore the solutions.

Responsive-Images.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace WebUi.Pages {
    public class ResponsiveImagesModel : PageModel
    {
        [BindProperty(SupportsGet = true)] public string Problem { get; set; }
        [BindProperty(SupportsGet = true)] public string Query { get; set; }
        public void OnGet()
        {
            
        }
    }
}
(a) The page model we will use for exploring responsive images.

The razor page

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Now that we have a model we also need a page to use it on (b). The page provides us a basic ui that will make it easier to switch between the problems and their solutions.

Responsive-Images.cshtml

@page
@model WebUi.Pages.ResponsiveImagesModel

@{
    ViewData["Title"] = "Responsive Images";
}

@section Scripts {
    <environment include="Development">
        <script src="~/js/responsive-images.bundle.js"></script>
    </environment>
}

<nav class="responsive-image-nav">
    <label>Problems</label>
    <a class="@( Model.Problem == "resolution-switching" ? "active" : "" )"
       href="/responsive-images?problem=resolution-switching&query=initial">Resolution Switching</a>
    <a class="@( Model.Problem == "art-direction" ? "active" : "" )"
       href="/responsive-images?problem=art-direction&query=large">Art Direction</a>
</nav>

@if (Model.Problem == "resolution-switching") 
{
    <nav class="responsive-image-nav">
        <label>Resolution</label>
        <a class="@( Model.Query == "initial" ? "active" : "" )"
           href="/responsive-images?problem=resolution-switching&query=initial">Initial</a>
        <a class="@( Model.Query == "different-sizes" ? "active" : "" )"
           href="/responsive-images?problem=resolution-switching&query=different-sizes">Different Sizes</a>
        <a class="@( Model.Query == "same-size" ? "active" : "" )"
           href="/responsive-images?problem=resolution-switching&query=same-size">Same Size</a>
    </nav>

    if (Model.Query == "initial")
    {
        
    }
    else if (Model.Query == "different-sizes")
    {
        
    }
    else if (Model.Query == "same-size")
    {
        
    }
}
else if (Model.Problem == "art-direction")
{
    <nav class="responsive-image-nav">
        <label>Art</label>
        <a class="@( Model.Query == "large" ? "active" : "" )"
           href="/responsive-images?problem=art-direction&query=large">Large</a>
        <a class="@( Model.Query == "small" ? "active" : "" )"
           href="/responsive-images?problem=art-direction&query=small">Small</a>
        <a class="@( Model.Query == "picture" ? "active" : "" )"
           href="/responsive-images?problem=art-direction&query=picture">Picture</a>
    </nav>

    if (Model.Query == "large")
    {
        
    }
    else if (Model.Query == "small")
    {
        
    }
    else if (Model.Query == "picture")
    {
        
    }
}
(b) Our initial responsive images page with a basic ui to make it more useable.

Initial styling

  • WebUi
    • Source
      • pages
        • responsive-images.page.scss

The last thing to do before we get started with the problem at hand is to add just a little bit of styling to our page (c).

responsive-images.page.scss

@import "../../sass/_non-rendering";

$blue: #0984e3 !default;
$dark-gray: #333 !default;
$light-gray: #ddd !default;

.responsive-image-nav {
    background-color: $light-gray;
    display: flex;
    border-bottom: 1px solid $dark-gray;

    a, label {
        @include padding(1em 1em);
    }

    label {
        min-width: 110px;
        background-color: $blue;
        margin: 0;
        color: white;
    }

    a {
        display: block;
        color: $dark-gray;
        text-decoration: none;

        &.active {
            color: white;
            background-color: $dark-gray;
        }
    }
}
(c) The basic styling for the ui.

Basic image tag

  • WebUi
    • Pages
      • Responsive-Images.cshtml

To start with we will just add a typical image tag to our page (d). For some images if we add a larger image by default and it gets scaled down by the size of the display the image is still readable and for some images it would not be. But even if it is still readable there is a good chance that we are slowing down our site unnecessarly by serving an image that is too large for the device.

Responsive-Images.cshtml

...
@if (Model.Problem == "resolution-switching") 
{
    ...
    if (Model.Query == "initial")
    {
        <div class="image-container">
            <img src="/images/responsive-images/woman-balloon-chair-dark-800w.jpg"
                 alt="Woman sitting on a chair beside a balloon">
            <div class="image-caption">
                <p>Photo by Daria Shevtsova from Pexels</p>
                <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
            </div>
        </div>
    }
    ...
}
...
(d) Adding a single resolution image to our page.
Advertisement

Basic styling for our images

  • WebUi
    • Source
      • responsive-images
        • responsive-images.page.scss

Next up we are going to add just a little bit of styling (e).

responsive-images.page.scss

...
.image-container {
    @include margin(1em auto);
    display: table;

    picture, img {
        display: block;
    }

    picture {
        @include margin(null null 0.5em null);
    }

    .image-caption {
        display: table-caption;
        caption-side: bottom;
    }

    &.same-size {
        img {
            width: 320px;
        }
    }
}
...
(e) Basic styling for our image containers and their contents.

Resolution Switching: Different Sizes

  • WebUi
    • Pages
      • Responsive-Images.cshtml

There are a couple of different approaches that you can take when you want to show the same image content for everyone. The first one is show the image at a lower resolution for devices with smaller viewports. In this example we will show the image at 320px, 480px, and 800px width using breakpoints set at the same values (f).

Responsive-Images.cshtml

...
@if (Model.Problem == "resolution-switching") 
{
    ...
    else if (Model.Query == "different-sizes")
    {
        <div class="image-container">
            <img srcset="/images/responsive-images/woman-balloon-chair-dark-320w.jpg 320w,
                         /images/responsive-images/woman-balloon-chair-dark-480w.jpg 480w,
                         /images/responsive-images/woman-balloon-chair-dark-800w.jpg 800w"
                 sizes="(max-width: 320px) 320px,
                        (max-width: 480px) 480px,
                        800px"
                 src="/images/responsive-images/woman-balloon-chair-dark-800w.jpg"
                 alt="Woman sitting on a chair beside a balloon">
            <div class="image-caption">
                <p>Photo by Daria Shevtsova from Pexels</p>
                <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
            </div>
        </div>
    }
}
...
(f) Showing the same content for each device but at lower resolutions for lower resolution devices.

Resolution Switching: Same Size

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Next up is the case where we want to again show the same image content but we want to show a higher resolution image for higher resolution displays such as retina displays. In this case we fix the size of the image by specifying the width in css and then specify which image should be shown in a 1x and 2x dpr device (g).

Responsive-Images.cshtml

...
@if (Model.Problem == "resolution-switching") 
{
    ...
    else if (Model.Query == "same-size")
    {
        <div class="image-container same-size">
            <img srcset="/images/responsive-images/woman-balloon-chair-dark-320w.jpg,
                         /images/responsive-images/woman-balloon-chair-dark-640w.jpg 2x"
                 src="/images/responsive-images/woman-balloon-chair-dark-640w.jpg"
                 alt="Woman sitting on a chair beside a balloon">
            <div class="image-caption">
                <p>Photo by Daria Shevtsova from Pexels</p>
                <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
            </div>
        </div>
    }
}
...
(g) Specifying which image should be shown based on the device pixel ratio.

Art Direction: Large

  • WebUi
    • Pages
      • Responsive-Images.cshtml

In this section we will focus on showing modified images based on the resolution of the device. To begin with we will just show the large image (h).

Responsive-Images.cshtml

...
else if (Model.Problem == "art-direction")
{
    ...
    if (Model.Query == "large")
    {
        <div class="image-container">
            <img src="/images/responsive-images/abandoned-architecture-bungalow-2560w.jpg"
                 alt="Abandoned cabin in the woods">
            <div class="image-caption">
                <p>Photo by Mateas Petru from Pexels</p>
                <p>https://www.pexels.com/photo/wooden-house-on-a-forest-673788/</p>
            </div>
        </div>
    }
    ...
}
(h) The image that we want to have shown on a large device.

Art Direction: Small

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Next up we will take a look at the image after it has been cropped for display on a smaller device (i).

Responsive-Images.cshtml

...
else if (Model.Problem == "art-direction")
{
    ...
    else if (Model.Query == "small")
    {
        <div class="image-container">
            <img src="/images/responsive-images/abandoned-architecture-bungalow-1200w.jpg"
                 alt="Abandoned cabin in the woods">
            <div class="image-caption">
                <p>Photo by Mateas Petru from Pexels</p>
                <p>https://www.pexels.com/photo/wooden-house-on-a-forest-673788/</p>
            </div>
        </div>
    }
    ...
}
(i) Cropped image that we want to show on a smaller device.

Art Direction: Picture

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Lastly we can use the picture tag to specify which image should be shown again based on the size of the device (j).

Responsive-Images.cshtml

...
else if (Model.Problem == "art-direction")
{
    ...
    else if (Model.Query == "picture")
    {
        <div class="image-container">
            <picture>
                <source media="(max-width: 1199px)" 
                        srcset="/images/responsive-images/abandoned-architecture-bungalow-1200w.jpg">
                <source media="(min-width: 1200px)"
                        srcset="/images/responsive-images/abandoned-architecture-bungalow-2560w.jpg">
                <img src="/images/responsive-images/abandoned-architecture-bungalow-1200w.jpg"
                     alt="Abandoned cabin in the woods">
            </picture>
            <div class="image-caption">
                <p>Photo by Mateas Petru from Pexels</p>
                <p>https://www.pexels.com/photo/wooden-house-on-a-forest-673788/</p>
            </div>
        </div>
    }
}
(j) By using the picture tag we can take advantage of the built in functionality of the browser to determine based on media queries which image should be shown.
Exciton Interactive LLC
Advertisement