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

2018-12-31 12:42发布

Every responsive website development tutorial recommends using the display:none CSS property to hide content from loading on mobile browsers so the website loads faster. Is it true? Does display:none not load the images or does it still load the content on mobile browser? Is there any way to prevent loading unnecessary content on mobile browsers?

16条回答
无色无味的生活
2楼-- · 2018-12-31 13:40

If you make the image a background-image of a div in CSS, when that div is set to 'display: none', the image will not load.

Just expanding on Brent's solution.

You can do the following for a pure CSS solution, it also makes the img box actually behave like an img box in a responsive design setting (that's what the transparent png is for), which is especially useful if your design uses responsive-dynamically-resizing images.

<img style="display: none; height: auto; width:100%; background-image: 
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block 
visible-lg-block" src="img/400x186_trans.png" alt="pic 1 mofo">

The image will only be loaded when the media query tied to visible-lg-block is triggered and display:none is changed to display:block. The transparent png is used to allow the browser to set appropriate height:width ratios for your <img> block (and thus the background-image) in a fluid design (height: auto; width: 100%).

1078/501 = ~2.15  (large screen)
400/186  = ~2.15  (small screen)

So you end up with something like the following, for 3 different viewports:

<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">

And only your default media viewport size images load during the initial load, then afterwards, depending on your viewport, images will dynamically load.

And no javascript!

查看更多
不再属于我。
3楼-- · 2018-12-31 13:42

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

Desktop browsers support

Mobile browsers

Mobile browsers support

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.

Anyhow, you can still try to make a dodgy hack 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 image and will only download the 1x1 pixel image, which can be cached if you use it more than once. Anyhow it's really not recommended to do that, because if the tag is not supported even the desktop browsers would show only the 1x1px image.

查看更多
何处买醉
4楼-- · 2018-12-31 13:42

The background-image of a div element will load if the div is set do 'display:none'.

Anyway, if that same div has a parent and that parent is set to 'display:none', the background-image of the child element will not load. :)

Example using bootstrap:

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


<div class="col-xs-12 visible-lg">
	<div style="background-image: url('http://via.placeholder.com/300x300'); background-repeat:no-repeat; height: 300px;">lg</div>
</div>
<div class="col-xs-12 visible-md">
	<div style="background-image: url('http://via.placeholder.com/200x200'); background-repeat:no-repeat; height: 200px;">md</div>
</div>
<div class="col-xs-12 visible-sm">
	<div style="background-image: url('http://via.placeholder.com/100x100'); background-repeat:no-repeat; height: 100px">sm</div>
</div>
<div class="col-xs-12 visible-xs">
	<div style="background-image: url('http://via.placeholder.com/50x50'); background-repeat:no-repeat; height: 50px">xs</div>
</div>

查看更多
谁念西风独自凉
5楼-- · 2018-12-31 13:43

Those images are loaded. The browser, due to the possibility of a script dynamically checking an element of the DOM, doesn't optimize elements (or elements content) away.

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

The image has a display:none style but its size is read by the script. 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").

EDIT :

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

查看更多
刘海飞了
6楼-- · 2018-12-31 13:44

Use @media query CSS, basically we just release a project where we had an enormous image of a tree on desktop at the side but not showing in table/mobile screens. So prevent image from loading its quite easy

Here is a small snippet:

.tree {
    background: none top left no-repeat; 
}

@media only screen and (min-width: 1200px) {
    .tree {
        background: url(enormous-tree.png) top left no-repeat;
    }
}

You can use the same CSS to show and hide with display/visibility/opacity but image was still loading, this was the most fail safe code we came up with.

查看更多
旧人旧事旧时光
7楼-- · 2018-12-31 13:46

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.

查看更多
登录 后发表回答