Different image for 3 perspectives

I need to use a different image for a mobile a tablet and a pc screen, and have managed to get it right for mobile and pc, but cant seem to get it right for the third image for tablet working with the code i got.

Here is what I got already,

.visible-mobile { display: none !important;}

@media (max-width: 489px) {.visible-mobile { display: inline !important;}
.hidden-mobile {display: none !important; }
#headerL img{position:relative; max-width:480px; width:100%; min-height:304px; height:100%;} }

<div id="headerL"><img src="img/nt-boxed2.jpg" alt="" class="hidden-mobile"><img src="img/nt-boxed2-Small.jpg" alt="" class="visible-mobile"></div>

http://www.accend4web.co.uk/fiona2/index.html

A better approach to swapping images based on screen size is the <picture> element.

Or you may find it easier to apply the image as a background.

But in this case, because the image is largely text and plain colour, with just one part an actual photo, I would take a different approach to this design.
I would crop the picture to be only the photo part. Then make the text part be actual text and the background colour be an actual background colour, then use css to arrange the layout.
The picture being smaller would not require to be swapped making it faster for all users. Also the text would be machine readable, making the page more accessible and semantic which would benefit both users and search engines.

4 Likes

Oh thank you, didnt know about that.

Cheers SamA74

Yes as Sam said the picture element is the way to go because if you use three foreground images which you show with media queries the browsers will still load all three images. If you used background images then only one image would get loaded depending on the browser width.

The picture element is much better as the browser just loads the one image. If you don’t need ‘art direction’ then srcet is a better way to go although support in IE is only from edge onwards so a fallback will be needed.

Just for information your original question could be answered like this.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
@media screen and (max-width: 762px) {
	.swapimg {display: none;}
	.visible-tablet {display: inline;}
}
@media screen and (max-width: 489px) {
	.swapimg {display: none;}
	.visible-mobile {display: inline;}
}
@media screen and (min-width: 763px) {
	.swapimg {display: none;}
	.visible-desktop {display: inline;}
}


</style>
</head>

<body>
<div id="headerL"><img src="img/nt-boxed2.jpg" alt="Large" class="swapimg visible-desktop"><img src="img/nt-boxed2-Small.jpg" alt="small" class="swapimg visible-mobile"><img src="img/nt-boxed2-medium.jpg" alt="Medium" class="swapimg visible-tablet"></div>
</body>
</html>

But as I said above the browser will (almost) always load all the three images because they are in the html.

2 Likes

Hi Paul,

Thank you for the feedback, and yes I implemented the way and it works great.

And like you say its not then loading the three images, which saves on load time.

Here is a rough example. In this I use a background image in the banner.
In the end I did end up swapping the image in a query because otherwise it goes under the text on small screens and the purple text clashes with the purple flowers and gets lost. So I load a smaller version and re-position it.
It’s not a pixel perfect match for your site, but a rough approximation to show how it could be done to be more responsive and semantic.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name=viewport content="width=device-width, initial-scale=1">
        <title>Fiona</title>
        <link href="https://fonts.googleapis.com/css?family=Work+Sans:200" rel="stylesheet">
        <style>
            body {
                margin: 0 auto;
                max-width: 85em;
            }
            header {
                padding: 1em
            }
            header > * { display: inline-block; }
            .banner {
                background: url(image.jpg) no-repeat top right 6%, #c297c5;
                background-size:  contain;
                font-family: sans-serif ;
                color: #562178;
                padding: 1em 6% 1.4em ;
            }
            .banner h2 {
                font-family: 'Work Sans', sans-serif ;
                text-transform: lowercase;
                font-weight: lighter;
                font-size:3.5em;    /* For old browsers */
                font-size: calc(2em + 3vw) ;
                margin: 0.4em 0 ;
            }
            .banner h2 span:first-child {
                color: #fff;
            }
            .caps {
                text-transform: uppercase;
            }
            .banner h2 span {
                display: block;
            }
            .banner sup {
                font-size: 0.24em;
                position: relative;
                top: -1em;
                left: -1em;
            }
            .banner ul {
                list-style: none;
                padding: 0;
                line-height: 1.5
            }
            @media screen and (min-width: 70em)    { /* For big screens */
                .banner h2 {font-size: 4em}
            }
            @media screen and (max-width: 625px)    { /* For small screens */
                .banner {
                    background: url(small.jpg) no-repeat top right, #c297c5;
                    background-size:  35%;
                    }
            }
        </style>
    </head>
    <body>
        <header>
            <h1>Logo</h1>
            <p>Nav Etc...</p>
        </header>
        <div class="banner">
            <h2>
                <span>Natural</span> <span>Therapies <sup class="caps">TM</sup></span>
            </h2>
            <ul class="caps">
                <li>Clinical Aromatherapy</li>
                <li>Japanese Facial Massage</li>
                <li>Reiki Healing</li>
                <li>Indian Head Massage</li>
                <li>Bach Flower Remedies</li>
            </ul>
        </div >
        <p>Other content.</p>
    </body>
</html>

These are the cropped images:-

1 Like

Having done it this way, is there anyway to set a max width and height to the images within source

<picture>
<source media="(min-width: 800px)" srcset="img/nt-boxed2.jpg">
<source media="(min-width: 480px)" srcset="img/nt-boxed2-Small-Tab.jpg">
<source srcset="img/nt-boxed2-Small.jpg">
<img src="img/nt-boxed2-Small.jpg" alt="Autumn in Moscow">
</picture>

I tried this and it didnt seem to work. The way I tried it was to actually make the width and height a silly small number but it didnt do anything

<source media="(min-width: 800px)" srcset="img/nt-boxed2.jpg" style="max-height:300px; max-width:1400px">

I’ve never seen both min and max used before so I tried a bit of experimenting myself.

I’ve learned that I obviously don’t understand how they work as much as I thought I did, so I’m looking forward to seeing more about this as well.

The only approaches I’ve used that work are JavaScript that uses height and width, finds the acceptable max and scales accordingly.
But I would be interested in learning a CSS-only way of doing this as well.

Staying tuned :radio:

Ye its an awkward one, because what I’m trying to do is set the max-width of the image, whilst its being dictated to by the min-width of the screen width.

I’m probably miles off mind, but ye I’m looking to see what options there are if any

Just use media queries and target the image at the appropriate points. The image that will be visible will be the one in the srcset and you can control that via the media query if you need to. If I understand you correctly of course :slight_smile:

It all seems a bit elaborate to me as I rarely have to go to those lengths and a simple max-width does the trick. Many times simpler is better so don;t over-think the solution.

You can’t set a max-height and a max-width on the image anyway because that will break aspect ratios. It’s either or.:wink:

3 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.