Does “display:none” prevent an image from loading?

前端 未结 17 1908
再見小時候
再見小時候 2020-11-22 05:13

Every responsive website development tutorial recommends using the display:none CSS property to hide content from loading on mobile browsers so the website load

相关标签:
17条回答
  • 2020-11-22 05:38

    Browsers are getting smarter. Today your browser (depending on the version) might skip the image loading if it can determine it's not useful.

    The image has a display:none style but its size may be read by the script. Chrome v68.0 does not load images if the parent is hidden.

    You may check it there : http://jsfiddle.net/tnk3j08s/

    You could also have checked it by looking at the "network" tab of your browser's developer tools.

    Note that if the browser is on a small CPU computer, not having to render the image (and layout the page) will make the whole rendering operation faster but I doubt this is something that really makes sense today.

    If you want to prevent the image from loading you may simply not add the IMG element to your document (or set the IMG src attribute to "data:" or "about:blank").

    0 讨论(0)
  • 2020-11-22 05:39

    The trick to using display:none with images is to assign them an id. This was there is not a lot of code needed to make it work. Here is an example using media queries and 3 stylesheets. One for phone, one for tablet, and one for desktop. I have 3 images, image of a phone, a tablet, and a desktop. On a phone screen only an image of the phone will display, a tablet will display only the tablet image, a desktop displays on the desktop computer image. Here is a code example to make it work:

    Source code:

    <div id="content">
    <img id="phone" src="images/phone.png" />
    <img id="tablet" src="images/tablet.png" />
    <img id="desktop" src="images/desktop.png" />
    </div>
    

    The phone CSS which doesn't need a media query. Its the img#phone that makes it work:

    img#phone {
        display: block;
        margin: 6em auto 0 auto;
        width: 70%;
        }
    
    img#tablet {display: none;}
    img#desktop {display: none;}
    

    The tablet css:

    @media only screen and (min-width: 641px) {
    img#phone {display: none;}
    
    img#tablet {
        display: block;
        margin: 6em auto 0 auto;
        width: 70%;
        }
    }
    

    And the desktop css:

    @media only screen and (min-width: 1141px) {
    img#tablet {display: none;}
    
    img#desktop {
        display: block;
        margin: 6em auto 0 auto;
        width: 80%;
        }
    }
    

    Good luck and let me know how it works for you.

    0 讨论(0)
  • 2020-11-22 05:40

    Quirks Mode: images and display: none

    When image has display: none or is inside an element with display:none, the browser may opt not to download the image until the display is set to another value.

    Only Opera downloads the image when you switch the display to block. All other browsers download it immediately.

    0 讨论(0)
  • 2020-11-22 05:40

    we're talking about images not loading on mobile, right? so what if you just did an @media (min-width: 400px){background-image:thing.jpg}

    wouldn't it then only look for the image at above a certain screen width?

    0 讨论(0)
  • 2020-11-22 05:45

    HTML5 <picture> tag will help you to resolve the right image source depending on the screen width

    Apparently the browsers behaviour hasn't changed much over the past 5 years and many would still download the hidden images, even if there was a display: none property set on them.

    Even though there's a media queries workaround, it could only be useful when the image was set as a background in the CSS.

    While I was thinking that there's just a JS solution to the problem (lazy load, picturefill, etc.), it appeared that there's a nice pure HTML solution that comes out of the box with HTML5.

    And that is the <picture> tag.

    Here's how MDN describes it:

    The HTML <picture> element is a container used to specify multiple <source> elements for a specific <img> contained in it. The browser will choose the most suitable source according to the current layout of the page (the constraints of the box the image will appear in) and the device it will be displayed on (e.g. a normal or hiDPI device.)

    And here's how to use it:

    <picture>
     <source srcset="mdn-logo-wide.png" media="(min-width: 600px)">
     <img src="mdn-logo-narrow.png" alt="MDN">
    </picture>
    

    The logic behind

    The browser would load the source of the img tag, only if none of the media rules applies. When the <picture> element is not supported by the browser, it will again fallback to showing the img tag.

    Normally you'd put the smallest image as the source of the <img> and thus not load the heavy images for larger screens. Vice versa, if a media rule applies, the source of the <img> will not be downloaded, instead it will download the url's contents of the corresponding <source> tag.

    Only pitfall here is that if the element is not supported by the browser, it will only load the small image. On the other hand in 2017 we ought to think and code in the mobile first approach.

    And before someone got too exited, here's the current browser support for <picture>:

    Desktop browsers

    Mobile browsers

    More about the browser support you can find on Can I use.

    The good thing is that html5please's sentence is to use it with a fallback. And I personally intend to take their advise.

    More about the tag you can find in the W3C's specification. There's a disclaimer there, which I find important to mention:

    The picture element is somewhat different from the similar-looking video and audio elements. While all of them contain source elements, the source element’s src attribute has no meaning when the element is nested within a picture element, and the resource selection algorithm is different. As well, the picture element itself does not display anything; it merely provides a context for its contained img element that enables it to choose from multiple URLs.

    So what it says is that it only helps you improve the performance when loading an image, by providing some context to it.

    And you can still use some CSS magic in order to hide the image on small devices:

    <style>
      picture { display: none; }
    
      @media (min-width: 600px) {
        picture {
          display: block;
        }
      }
    </style>
    
    <picture>
     <source srcset="the-real-image-source" media="(min-width: 600px)">
     <img src="a-1x1-pixel-image-that-will-be-hidden-in-the-css" alt="MDN">
    </picture>
    

    Thus the browser will not display the actual image and will only download the 1x1 pixel image (which can be cached if you use it more than once). Be aware, though, that if the <picture> tag is not supported by the browser, even on descktop screens the actual image won't be displayed (so you'll definitely need a polyfill backup there).

    0 讨论(0)
  • 2020-11-22 05:45

    ** 2019 Answer **

    In a normal situation display:none doesn't prevent the image to be downloaded

    /*will be downloaded*/
    
    #element1 {
        display: none;
        background-image: url('https://picsum.photos/id/237/100');
    }
    

    But if an ancestor element has display:none then the descendant's images will not be downloaded

    
    /* Markup */
    
    <div id="father">
        <div id="son"></div>
    </div>
    
    
    /* Styles */
    
    #father {
        display: none;
    }
    
    /* #son will not be downloaded because the #father div has display:none; */
    
    #son {
        background-image: url('https://picsum.photos/id/234/500');
    }
    

    Other situations that prevent the image to be downloaded:

    1- The target element doesn't exist

    /* never will be downloaded because the target element doesn't exist */
    
    #element-dont-exist {
        background-image: url('https://picsum.photos/id/240/400');
    }
    

    2- Two equal classes loading different images

    /* The first image of #element2 will never be downloaded because the other #element2 class */
    
    #element2 {
        background-image: url('https://picsum.photos/id/238/200');
    }
    
    /* The second image of #element2 will be downloaded */
    
    #element2 {
        background-image: url('https://picsum.photos/id/239/300');
    }
    

    You can watch for yourself here: https://codepen.io/juanmamenendez15/pen/dLQPmX

    0 讨论(0)
提交回复
热议问题