4
votes

I am working on a Parallax/Scrolling Timeline project and I am having a problem with the CSS3 Background-size cover property.

The div has these properties:

background: url(../images/timeline/back-6.jpg) no-repeat top center black; 
background-size: cover;
padding-top: 90px;
height: 1855px;
position: relative;

Using jQuery I switch the background-attachment to fixed. When I do this the background image jumps "in" (meaning that parts of the image that were past the edge of the screen are now visible). Which isn't the desired result.

In testing I can switch the div to use background-size: 100% cover but it is causing different vertical jumping issues when scrolling.

Any ideas of how to prevent it from jumping in when I switch the background to fixed? (It also happens in reverse when I set the background to scroll).

I sadly can't link to a demo of this code as the page isn't ready to be deployed yet.

2

2 Answers

4
votes

I had the same issue, when setting background-size to cover or contain

Setting a fixed height, in example for smaller screens via @media prevents the background-image from jumping. After my tests I came to the conclusion, that the jumping is due to the orientation of the element after setting background-attachment to fixed

Setting it to fixed, the size is calculated by the size of the viewport, not the element containing the background-image. This is where the jumping comes from and why setting a fixed height or width for the background-size solves this issue.

0
votes

I had the same problem while creating a one page layout i wanted to use with a scrollTo-Plugin and so on.... The page layout was devided in two parts: Left side for the background image which should change/scroll with the content on the right side. So i used to make a kind of jquery Plugin to combine both "background-position: fixed" and "background-size: cover". you just need to define the element by class/id for aligning the background-images.

dont complain about the code. im relatively new to javascript/jquery. but its working ;) there it is:

function fixedResize() {
    var targetEl = $('element where bg-images are in');
    var targetWidth = targetEl.width();
    var targetHeight = targetEl.height();
    var targetPosX = targetEl.offset().left;
    var targetPosY = targetEl.offset().top;
    var leftRatio = targetWidth / targetHeight;
    //console.log('TargetWidth', targetWidth, 'TargetHeight', targetHeight, 'Offset', targetPosX, targetPosY, 'leftRatio', leftRatio);
    targetEl.each(function(){

        var imgTarget = $(this);
        var url = $(this).css('background-image').replace('url(', '').replace(')', '').replace("'", '').replace('"', '');
        var bgImg = $('<img />'); // make background-image as image tag for getting width and height of the image
        imgTarget.css('background-attachment','fixed');
        bgImg.hide();
        bgImg.bind('load', function(){
            var imgHeight = $(this).height();
            var imgWidth = $(this).width();
            var imgRatio = imgWidth / imgHeight;
            $(this).remove(); // remove img Tags again

            // Calculate resize dimensions
            if (imgRatio > leftRatio) {
                var currentWidth = imgRatio * targetHeight; // image width after resize
                var currentHeight = (currentWidth/imgWidth)*imgHeight;
                var setToLeft = ((currentWidth - targetWidth)/2);
                var imgPosX = targetPosX - setToLeft;
                var imgPosY = (currentHeight - targetPosY - currentHeight/2 - targetHeight/2)* -1;
                var resizeImg = 'background-size: auto '+ targetHeight +'px;';                  

                } else if (imgRatio < leftRatio){
                    var currentWidth = targetWidth;
                    var currentHeight = (currentWidth/imgWidth)*imgHeight;
                    var imgPosX = targetPosX;
                    var imgPosY = (currentHeight - targetPosY - currentHeight/2 - targetHeight/2)* -1;
                    var resizeImg = 'background-size: '+ targetWidth +'px auto;'; // resize background
                }
            imgTarget.attr('style','background-attachment: fixed; background-position: '+ imgPosX +'px '+ imgPosY +'px;' + resizeImg);
            console.log('imgWidth', imgWidth, 'imgHeight', imgHeight, 'imgRatio', imgRatio, 'currentWidth', currentWidth, 'currentHeight', currentHeight, 'setToLeft', setToLeft);
            console.log('imgPos', imgPosX, imgPosY, 'setToLeft', setToLeft, targetPosX);

        });
        $(this).append(bgImg);
        bgImg.attr('src', url);

    });
}
fixedResize(); // initiate function

$(window).resize(function() {
    fixedResize(); // initiate function for window resize (Fluid behavior)
});

or jsfiddle.net/rowphant/eXb6e/14/