If I create a container and want to set a background image based on media queries, why does the browser (Firefox, Chrome) download the medium sized image, if the large one has already been downloaded? That seems totally against the point (i.e. saving bandwidth).
HTML
<div id="background"></div>
CSS
#background {
width: 100%;
height: 400px;
background-image: url(/content/images/2016/04/airport-small.jpg);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
@media (min-width: 500px) {
#background {
background: url(/content/images/2016/04/airport-medium.jpg);
}
}
@media (min-width: 800px) {
#background {
background: url(/content/images/2016/04/airport-large.jpg);
}
}
If I load a page the browser downloads the -large.jpg
, in this setup. If I resize the screen (below 800px), the browser downloads and renders the -medium.jpg
, and so on.
How can I prevent this?
Using media queries are a popular technique for delivering a tailored style sheet (responsive web design) to desktops, laptops, tablets, and mobile phones. You can also use media queries to specify that certain styles are only for printed documents or for screen readers (mediatype: print, screen, or speech).
Simply assign a new value to the image's width property. As a result, the image's height will adjust itself in accordance. Make sure to use relative units (like a percentage) for the width property instead of absolute units like pixels.
Actually placing media queries directly in the head section of your page will cause your pages to load much faster than linking to them. Also, linking to an external style sheet for any reason will slow down the page load time as well.
You're re-sizing the window, which is causing multiple media queries to execute, which results in multiple images being downloaded.
But you're a web developer re-sizing your browser for testing purposes. An actual user doesn't normally do this. A user simply lands on your site to do their business – on one screen size.
In your case, if this user is on a device with a browser width of 500px - 799px, he/she would get the medium jpg and/or small jpg, depending on the browser (see below).
Note that a user on a screen width greater than 800px may get all three images. (A window that matches min-width: 800px
also matches min-width: 500px
.)
Based on a review of Media Query & Asset Downloading Results, browser behavior varies in terms of image download. In particular, see test #4.
Also, consider the picture
element, which tells the browser which image is most suitable for a particular screen size.
The
picture
element is a container which provides multiple sources to its containedimg
element to allow authors to declaratively control or give hints to the user agent about which image resource to use, based on the screen pixel density, viewport size, image format, and other factors.
<picture>
<source srcset="airport-small.jpg" media="(max-width: 499px)">
<source srcset="airport-medium.jpg" media="(min-width: 500px) and (max-width: 799px)">
<source srcset="airport-large.jpg" media="(min-width: 800px)">
<img src="airport-small.jpg" alt="">
</picture>
If all source
elements evaluate to false, the img
element is applied. This is a useful fallback as picture
is not supported by Internet Explorer.
References:
picture
element ~ W3Cpicture
definition ~ MDNpicture
browser support ~ caniuse.compicture
element ~ PicturefillI think the main cause of the conflict here is your assumption that media queries were implemented to save bandwidth. They were implemented to display different things at different sizes, that's all. The fact you've chosen to display the same image at a different size was simply how you decided to utilize them, and media queries are just faithfully doing what they promised to do all along: Show the user what you told it to show the user.
I'd recommend evaluating whether this is really a worthy investment in time and code (keeping in mind that most users won't resize a window or rotate a mobile device, and those who do probably wouldn't be put off by a flash-and-reload). If you decide to do it, it won't be through only CSS. Your best bet will to research JavaScript methods to do this, such as adding a class loaded-large
to the body tag onload, and then writing a CSS rule for smaller images only to load when the body tag does not have class='loaded-large'
.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With