I have a section with a fullscreen background image that is loaded via a JavaScript data-attribute. As this is a responsive site, the same background image (1920 x 1080px) is scaled up and down depending on the screen size, which is not very performance-friendly, e.g. on mobile phones with smaller screen sizes.
HTML:
<!-- BEGIN PAGE TITLE -->
<section id="page-title" class="page-title-lg" data-bg-img="nature/full-20.jpg">
<div class="container">
<div class="page-title-wrapper">
<div class="page-title-txt">
<h1>Large Page Title</h1>
</div>
</div>
</div>
</section>
<!-- END PAGE TITLE -->
JS:
// Image Background
$('[data-bg-img]').each(function() {
var dataImg = $(this).attr('data-bg-img');
$(this).css('background-image', 'url(assets/img/' + dataImg + ')');
});
Is there a way to dynamically detect the window size and load the appropriate image via different data-attributes (e.g. 2560 x 1440, 1920 x 1440, 1280 x 800, 640 x 960, etc.) ?
I have a section with a fullscreen background image that is loaded via a JavaScript data-attribute. As this is a responsive site, the same background image (1920 x 1080px) is scaled up and down depending on the screen size, which is not very performance-friendly, e.g. on mobile phones with smaller screen sizes.
HTML:
<!-- BEGIN PAGE TITLE -->
<section id="page-title" class="page-title-lg" data-bg-img="nature/full-20.jpg">
<div class="container">
<div class="page-title-wrapper">
<div class="page-title-txt">
<h1>Large Page Title</h1>
</div>
</div>
</div>
</section>
<!-- END PAGE TITLE -->
JS:
// Image Background
$('[data-bg-img]').each(function() {
var dataImg = $(this).attr('data-bg-img');
$(this).css('background-image', 'url(assets/img/' + dataImg + ')');
});
Is there a way to dynamically detect the window size and load the appropriate image via different data-attributes (e.g. 2560 x 1440, 1920 x 1440, 1280 x 800, 640 x 960, etc.) ?
Share Improve this question asked Jun 16, 2016 at 19:38 user3046831user3046831 9- 1 Yes, there is. You haven't searched. – nicael Commented Jun 16, 2016 at 19:39
-
Why no CSS?
height: 100vh; width: 100vw;
– mferly Commented Jun 16, 2016 at 19:40 - Use CSS Media Queries. getbootstrap./css/#grid-media-queries – Dan Weber Commented Jun 16, 2016 at 19:41
- CSS media queries are not possible in this case. Unfortunately, this has to be a JS-solution. – user3046831 Commented Jun 16, 2016 at 19:41
- Look into .resize() for jQuery. Offers a callback when the "size of the browser" has changed, to which you can fire your code to manipulate the background image. – mferly Commented Jun 16, 2016 at 19:42
3 Answers
Reset to default 3If have three different images for say tablet, desktop, and mobile devices you could create a simple system to automatically choose the correct image to load.
<section id="page-title" class="page-title-lg" data-bg data-bg-img-desktop="nature/full-20.jpg" data-bg-img-tablet="nature/full-20.jpg" data-bg-img-mobile="nature/full-20.jpg"></section>
Notice the four attributes: data-bg data-bg-img-desktop, data-bg-img-tablet, data-bg-img-mobile.
When the page loads, get the screen width and load the image that is closest to the screen size:
<script type="text/javascript">
var imageBgs = document.querySelectorAll('[data-bg]');
var screenWidth = window.innerWidth;
for(var i=0; i<imageBgs.length; i++) {
if( screenWidth < 768 ){
// Load mobile image
imageBgs[i].style.backgroundImage = 'url('+imageBgs[i].getAttribute('data-bg-img-mobile')+')';
} else if( screenWidth >= 768 && screenWidth <= 1024 ) {
// Ipad
imageBgs[i].style.backgroundImage = 'url('+imageBgs[i].getAttribute('data-bg-img-tablet')+')';
} else {
// desktop image
imageBgs[i].style.backgroundImage = 'url('+imageBgs[i].getAttribute('data-bg-img-desktop')+')';
}
}
</script>
Is there a reason you can't change the CSS directly?
There are a few ways you could go about this. One way would be to listen to the resize
event, and update all images accordingly. However, you can also use jquery to create your media queries for each element during page load, and just let the browser handle switching everything out.
Here's a fiddle illustrating how to do that: https://jsfiddle/czr41bqp/
Essentially you would add a style in for each screen size you want to switch at and create your style
element here and append it to your header. Of course, this requires that you have pre-generated all versions of the images and that the sizes are consistent with each image.
$(function() {
//define a template with all media queries we want to target
var mediaQueryTemplate = '\
@media screen and (min-width:350px) { \
#{{ID}} { background-image: url({{BASE_URL}}/350x150) } \
} \
@media screen and (min-width:640px) { \
#{{ID}} { background-image: url({{BASE_URL}}/640x960) } \
} \
@media screen and (min-width:1280px) { \
#{{ID}} { background-image: url({{BASE_URL}}/1280x800) } \
} \
@media screen and (min-width:1280px) { \
#{{ID}} { background-image: url({{BASE_URL}}/1280x800) } \
} \
@media screen and (min-width:1920px) { \
#{{ID}} { background-image: url({{BASE_URL}}/1920x1440) } \
} \
@media screen and (min-width:2560px) { \
#{{ID}} { background-image: url({{BASE_URL}}/2560x1440) } \
} \
';
var $style = $('<style>');
$style.appendTo('head');
$('[data-bg-img]').each(function() {
//generate all media queries from the template for each image and add them to the style tag
var dataImg = $(this).attr('data-bg-img');
var mediaQueries = mediaQueryTemplate.replace(/{{ID}}/g, this.id).replace(/{{BASE_URL}}/g, dataImg);
$style.text($style.text() + mediaQueries);
});
});
One approach would be to leave the "src" attribute blank and then assign it depending on the screen width.
windowSize = $("window").width();
if(windowSize >= 1000){
$("img").attr("src","bigFile.png")
}
if(windowSize <= 999 && windowSize >= 500){
$("img").attr("src","mediumFile.png")
}
if(windowSize < 499){
$("img").attr("src","mobileFile.png")
}
Alternatively you could use something like:
if(windowSize >= 1000){
$("imageContainer").html("<img src="bigFile">);
}