8

How can I make it so that within the mobile version of my site the images are not downloaded to from the web server as these are large files that are not needed and not being used and therefore severely impacting the use of the mobile version of the site. Having looking at previous threads of such nature I saw that hiding the parent of the image using code such as below can benefit.

.parent {display:block;}
.background {background-image:url(myimage.png);}

@media only screen and (max-width:480px) {
.parent {display:none;}
}

The problem being I don't want to use background image CSS for SEO issues associated with them as I like to use Schema tagging etc ..so how can I prevent an IMG tag from being downloaded, as display:none; only hides the image rather than stopping it being downloaded.

Note: This is not for copyright protection issues e.g. preventing right click etc etc but for speed and ultimately size of the downloaded content to mobile.

Henry Quekett
  • 429
  • 1
  • 7
  • 15
  • THere's several scripts and techniques out there for sniffing the device the request is being made with. Several may be found here, the ones from what it sounds like that show how to *forward* a client to a *mobile-only* version of the site sans heavy image downloads. Note, I don't believe any of them are *foolproof* either; it's a constantly evolving browser or device world. But there are onces that should give you what you want. – Jared Farrish Mar 13 '13 at 22:32
  • Sounds like you'll need to use a bit of Javascript. I'm not sure if there's any CSS you can use which will actually tell the browser not to go download the images. – Cory Danielson Mar 13 '13 at 22:32
  • :( CSS4 I need you already! – Henry Quekett Mar 13 '13 at 22:33
  • 2
    Personally, I would probably have all of the image tags like `` and then maybe check the screen size to determine if it's a phone/tablet/pc and then select all images and swap the `data-src` values into the `src` values on `load` so that this would occur as soon as possible. If you know the size of the images ahead of time, it'd be useful to set the `width` and `height` attributes of those images as well. `There's got to be a library for this somewhere. I'm sure it will be posted soon as a response....` – Cory Danielson Mar 13 '13 at 22:35
  • 1
    Another option, of course, could be to server your `img` files with a script and use the script to block the download to clients with the some type of detection script. – Jared Farrish Mar 13 '13 at 22:36
  • some good options here I just need script or links but whenever I google it all that it dishes out is blooming prevent right click and people stealing images which i don't care about – Henry Quekett Mar 13 '13 at 22:43
  • Your site is running in a PHP or Ruby environment? Is it a framework or just something you've put together? – Jared Farrish Mar 13 '13 at 22:52
  • Something that I have put together and running in a php environment.. – Henry Quekett Mar 13 '13 at 22:53
  • Do you know the images and the height/width ahead of time? If so you can use background-images for all images and prevent loading by simple not setting a background image for small screens. – Cory Danielson Mar 13 '13 at 23:18
  • 1
    @HenryQuekett, take a look at [Mobile Detect](http://mobiledetect.net/), which is a fairly useful toolkit for handling these types of things. – Jared Farrish Mar 13 '13 at 23:24
  • https://github.com/scottjehl/picturefill is one of the better solutions imo. – Scott Simpson Mar 13 '13 at 23:44

3 Answers3

4

This solution uses CSS to prevent background-images from loading and jQuery to prevent images from loading. I'm not familiar with any CSS solution that will prevent images from loading.

JS Fiddle: http://jsfiddle.net/CoryDanielson/rLKuE/6/

If you know the images height and width (or even ratio) ahead of time you could set the background-image for a bunch of fixed size DIVs. This might be applicable for icons and layout-type images. Look at the HTML/CSS below for an example of that.

Background Images

/* hidden by default */
aside {
    display: none;
}

/* Pictures load for 'big screen' users.. pcs/tablets? */
@media screen and (min-width: 750px) {
  aside {
      display: block;
  }

  .catpicDiv {
    height: 100px;
    width: 100px;
    display: inline-block;
    border: 1px solid red;
    background-image: url('http://img2.timeinc.net/health/images/slides/poodle-1-400x400.jpg');
    background-size: cover;
  }
}

and HTML

<aside>
    <div class="catpicDiv"></div>
    <div class="catpicDiv"></div>
    <div class="catpicDiv"></div>
</aside>


Image Elements are a different story...

I don't know of any purely CSS solution to prevent them from loading the images. So I'd solve it like this:

Define IMG tags as follows

<img src="" data-src="url-to-image.jpg" />

Then, somewhere in the head of the document you need similar javascript


1) Function to load all of the images

function loadAllTheImages() {
    $("img").each(function(){
        $(this).attr('src', $(this).attr('data-src'));
    });
}

2) Code to determine if the user is on mobile or a PC (slow vs fast connection) and then load the images. This code isn't bulletproof, there are much more accurate and reasonable tests than this.

$(window).load(function(){
    if ( $(window).width() > 750 ) {
        loadAllTheImages(); // !
    } else {
        $("body").append("<a id='mobileCheck' href='javascript: void(0);'>I GOTS 4G, LEMME HAVE EM!</a>");
    }
});

3) As well as maybe some code to activate a button to load the images anyways? Why not, I guess... ?

$(document).ready(function(){
    $('body').prepend("<h1>" + $(window).width().toString() + "</h1>");
    $('body').on('click', '#mobileCheck', function(){
        loadAllTheImages(); // !
        $("#mobileCheck").remove();
    });
});

Similar solution as here and what I hypothesized in the comments:

Delay image loading with jQuery

Community
  • 1
  • 1
Cory Danielson
  • 13,192
  • 3
  • 42
  • 49
  • Nice the only issue that I have with it although I appreciate your work and may be my fault from the original question is that I don't want to load all image of none if that makes sense but I am being selective and removing larger images that are for graphics only and there is no need for the user to be waiting for a minute while it downloads but THANKYOU I don't write JS yet so I struggle when It comes to things like this – Henry Quekett Mar 13 '13 at 23:24
  • p.s. I voted it up although I'm only not accepting it as i Cant use it as it stands ... – Henry Quekett Mar 13 '13 at 23:25
  • 1
    If you gave the "large" images a specific `class` attribute you could target them specificually with jQuery. Inside of `loadAllTheImages` instead of `$("img")` you could have `$("img.largeImage")` and that will select all `image elements` with a `class` of `largeImage`. – Cory Danielson Mar 13 '13 at 23:26
  • so would be removed by $("img.NoMobile")? – Henry Quekett Mar 13 '13 at 23:28
  • My other concern with the script not trying to sound ungrateful is that I prefer to use device rather than browser width with my browser device degrading rather than size degrading if that make sense and currently the user would lose image if they where to reduce the browser window correct ? – Henry Quekett Mar 13 '13 at 23:33
  • 1
    They wouldn't lose the images if they've already loaded. The code is a 1 time thing. Right when the page loads, it checks *is it a small screen?* if so, no images. if it's a big screen, the images will load. I updated the JS Fiddle to include regular images as well and only removed a few "largeImages" http://jsfiddle.net/CoryDanielson/rLKuE/8/ – Cory Danielson Mar 13 '13 at 23:35
  • You can do device detection in javascript, checking for the screen width is a lazy way to determine the device, but it makes for a decent example of what's possible. – Cory Danielson Mar 13 '13 at 23:37
  • Device Detection in JS: http://stackoverflow.com/questions/3514784/best-way-to-detect-handheld-device-in-jquery – Cory Danielson Mar 13 '13 at 23:37
  • The update fiddle looks great thanks! Im going to be honest I'm sure what you just sent me to is some great script and I can fully understand your script but when it comes to writing it for myself and editing it thats my only worry! – Henry Quekett Mar 13 '13 at 23:40
  • Yeah. It's definitely a learning curve, but gotta start somewhere. That's how I got into Javascript... once you hit the limitations of CSS you've gotta start wrangling with some JS. – Cory Danielson Mar 13 '13 at 23:43
  • would it be possible for me to implement this to http://mobiledetect.net a jQuery browser detection library just looks a little more robust that the forum code that was mentioned earlier ? also will the no JS fall back just be all images load or none cause thats my other concern... – Henry Quekett Mar 13 '13 at 23:48
  • That looks like a PHP library. If javascript wasn't running, none of the JS code would execute and therefore none of the "noMobile" images would load. Was that your question? – Cory Danielson Mar 13 '13 at 23:52
  • 2
    @HenryQuekett - You could also do the the same thing with PHP on your server and a server-side sniffer, `ob_start()` and `ob_get_clean()` and `str_replace(' – Jared Farrish Mar 13 '13 at 23:52
  • 1
    sorry my error i was looking at a jQuery one earlier... yes so your basically saying if a user had JS switched of they would get no large images which is a problem :( I really appreciate all this help sorry im being such a pain I'm trying to reward you as much rep as possible for your help... – Henry Quekett Mar 13 '13 at 23:57
  • 1
    The simple answer to your question is really just `No.` Unfortunately HTML & CSS just isn't powerful enough to do what you want... :( it's an increasingly common problem now-a-days and I'm sure they'll work on something in the future. They have CSS solutions for 1x and 2x (retina) images, but not for no loading. – Cory Danielson Mar 13 '13 at 23:58
  • 1
    @HenryQuekett - Here's a really brief PHP demo of what I'm talking about: [codepad](http://codepad.viper-7.com/gwlDbO) More or less, using a detect script like mobiledetect-like script on the server to check and swap out the `img` tags in your site's output, which you can trap into a variable (in many cases) with `ob_start()` and `ob_get_clean()`. Cory, `+1` too. – Jared Farrish Mar 14 '13 at 00:26
  • Im just wondering if there is anyway in HTML to say that if JS cant run use data-src as the images src then it would be problem solved on that front ? – Henry Quekett Mar 14 '13 at 00:41
  • You can use the ` – Cory Danielson Mar 14 '13 at 00:42
0

There is no native solution in CSS that would prevent images from loading even if you hide them or set display to none.

You have to use some JS to achieve that result. If you are familiar with JS that should not be an issue at all. There are several plugins ready to go to do what you want. You can also write your own JS because its not that difficult.

Here is my code that loads images based on the screen size:

DEMO AT CODE PEN

It works without any libraries like JQ but if you use one of those it will automatically switch to it (Tweak it to your specific needs).

JS

// use jQuery or pure JS
if (typeof jQuery !== 'undefined') {
  // jQuery way
  // alert("jquery");

  $(function() {
    $(window).on('load resize', function() {
      var products = $("[data-product-image]");
      products.each(function(key, value) {
        var bg = null;
        if (window.outerWidth < 500) return;
        if (window.outerWidth < 1000) bg = $(value).data("product-image-s");
        if (window.outerWidth >= 1000) bg = $(value).data("product-image");
        console.log($(window).outerWidth);
        $(value).css({
          'background-image': 'url(' + bg + ')',
          'background-position': 'center',
          'background-size': 'cover',
        });
      });
    });
  });
} else {
  // Pure JS way
  // alert("JS");

  (function() {
    window.addEventListener('load', wlImageLoader);
    window.addEventListener('resize', wlImageLoader);
    function wlImageLoader() {
      console.log('event! Trig trig');
      var all = document.getElementsByTagName("div");
      var products = [];
      for (i = 0; i < all.length; i++) {
        if (all[i].hasAttribute('data-product-image')) {
          products.push(all[i]);
        }
      }
      Array.prototype.forEach.call(products, function(value) {
        var bg = null;
        var curent = window.getComputedStyle(value).getPropertyValue('background-image');
        console.log(curent);
        if (window.outerWidth < 500 || curent != 'none') return;
        if (window.outerWidth < 1000 && curent == 'none') bg = value.getAttribute('data-product-image-s');
        if (window.outerWidth >= 1000 && curent == 'none') bg = value.getAttribute('data-product-image');
        // if (window.outerWidth >= 2000 && curent == null) bg = value.getAttribute('data-product-image-l');
        if(bg == null || curent != 'none') return;
        value.style.backgroundImage = "url(" + bg + ")";
        value.style.backgroundPosition = "center";
        value.style.backgroundSize = "cover";
        curent = window.getComputedStyle(value).getPropertyValue('background-image');
        console.log(curent);
      });
    }
  })();
}

HTML

<div data-product-image="img/something_normal.jpg" data-product-image-s="img/something_small.jpg" id="p3" class="product">

However if you are a time loading freak you probably prefer to write your code natively in JS as you often don't use most of the jQuery library. For fast internet connection this is not a problem but if you target mobile devices on country side that might make a difference.

Antoine
  • 732
  • 13
  • 28
DevWL
  • 11,946
  • 5
  • 71
  • 69
-1

I would suggest combining perhaps the @import and @media commands to only @import the stylesheet which contains images if the @media tag meets you criteria (say, over a certain resolution).

So by default you wouldn't import the stylesheet which applies the BG image, you'd only end up doing it if you had determined the site was 'non-mobile'..if that makes sense!

The W3c site has some decent examples of combining the rules:

http://www.w3.org/TR/css3-mediaqueries/#media0

dougajmcdonald
  • 17,178
  • 7
  • 49
  • 87
  • I am lead to believe @import is a killer for site performance and I was looking to keep the images linked via IMG tags in the HTML, but thanks for the suggestion – Henry Quekett Mar 13 '13 at 22:41
  • @JaredFarrish I did read it of course, was trying to keep to the concept of not downloading un-needed images for the mobile site. Whilst the OP mentions not downloading the 'IMG tag' he's talking about background images, so really we talking here about not downloading the image file, as I interpreted it anyway! – dougajmcdonald Mar 13 '13 at 22:43
  • Here's the deal: The OP has the images in `img` elements, not stylesheets. In everything but mobile devices, it will stay that way. What the OP seeks is a *manner in which to toggle from `img` to nothing or otherwise restricted*. The switch is the hard part, not dealing with the aftermath in the mobile client. – Jared Farrish Mar 13 '13 at 22:48