Suppose you have nice, large image, and you want to set it on your web page as a background.
That shouldn't be too hard, add following CSS to the page
body{ background-position: center 0; background-repeat: no-repeat; background-size: auto auto; background-image: url("pics/prettyimage.jpg"); }and there it is, page looks pretty. But here's the problem. Most large, or even very large, images have height less than 1500px. And if your document is longer than it (as most documents are), when user scrolls down, after image he or she will see blank white space in background. Which might be OK for some pages, but for most it isn't very pretty anymore.
This problem have two solutions with CSS.
One is to repeat image again. Change line of CSS above to background-repeat: repeat;
Now there's no blank space, but composition is broken. There is a line where bottom of upper image meets the top of
the one below which creates not very nice effect.
Another solution would be to change the height of image to some upper height limit of our document.
Change the line of CSS to let's say background-size: auto 2000px;
. Now everything looks good for all documents
that are shorter than 2000px. But this approach has its faults too. What if in some cases document is longer than 2000px
(on narrow screens for example)? We can to be sure put background-size: auto 3000px;
, but now image
will become very stretched and we will never see the bottom of it.
Again, this might work well for some web sites, but the both aren't the real solutions.
One solution might be like this. When page is open we have situation depicted in picture. Top of document, background image, and browser window are all aligned.
And when scrolled to bottom, we want again all three to be aligned. This time at its bottoms.
In all other scrolling positions, background image should be proportionally scrolled between the two
end cases.
This means that image will scroll slower than document, which will give it nice parallax effect too.
$(window).on('scroll', function() { smoothBackgroundScroll("relative/image/url"); }); function smoothBackgroundScroll(imgsrc) { function loadImageHeight(url, width) { var img = new Image(); img.src = url; if (width) { img.width = width; } return img.height; } var dh, wh, ih, st, posy, backh, backw; if (!this._smoothBackgroundScroll) { var bcksize = $(document.body).css('background-size'); var bmatch = /(\w+)\s*(\w+)/.exec(bcksize); if (!bmatch || bmatch.length < 3) { backh = loadImageHeight(imgsrc) } else { backh = parseInt(bmatch[2]); if (isNaN(backh)) { backw = parseInt(bmatch[1]); backh = loadImageHeight(imgsrc, parseInt(backw)); } } this._smoothBackgroundScroll = { dh: $(document).height() , wh: $(window).height() , ih: backh } } dh = this._smoothBackgroundScroll.dh; wh = this._smoothBackgroundScroll.wh ih = this._smoothBackgroundScroll.ih; st = $(document).scrollTop(); posy = (dh - ih) * st / (dh - wh); document.body.style.backgroundPosition = 'center ' + posy + 'px'; }Function
smoothBackgroundScroll(imgsrc)
will work for both cases when background-size
CSS property is set or not. And it is also used on this page as an example, so you can see its effect and
take working code from source.
Enjoy!