(CSS) Make a background image scroll slower than everything else

后端 未结 8 1070
死守一世寂寞
死守一世寂寞 2020-12-12 17:33

here is is my CSS code for the body:

body {
  padding: 0;
  margin: 0;
  background-image: url(\"../images/background.jpg\");
  background-repeat: no-repeat;         


        
相关标签:
8条回答
  • 2020-12-12 17:43

    Agree that it isn't possible just with css, because you have to compute image and document height ratio. I also like this effect, that's why created simple function that does just that. Here is function and its call on scroll event:

    $(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';
    }

    You can find it here along with example and visual explanation what's really going on with image and document:

    Smooth background image scrolling

    0 讨论(0)
  • 2020-12-12 17:43

    Best way is to do it with jQuery. There are a lot of sites about this, for example:

    • jQuery to give impression of background scrolling slower
    • http://code.tutsplus.com/tutorials/a-simple-parallax-scrolling-technique--net-27641
    • http://callmenick.com/2014/09/08/advanced-parallax-scrolling-effect/
    0 讨论(0)
  • 2020-12-12 17:44

    you can use something simple like here: html:

    Motion

    css:

    body {
    
      min-height:4000px;
      background-image: url("http://www.socialgalleryplugin.com/wp-content/uploads/2012/12/social-gallery-example-source-unknown-025.jpg");
    }
    
    h1 {margin-top:300px;}
    

    js:

    (function(){
    
      var parallax = document.querySelectorAll("body"),
          speed = 0.5;
    
      window.onscroll = function(){
        [].slice.call(parallax).forEach(function(el,i){
    
          var windowYOffset = window.pageYOffset,
              elBackgrounPos = "50% " + (windowYOffset * speed) + "px";
    
          el.style.backgroundPosition = elBackgrounPos;
    
        });
      };
    
    })();
    

    Here is jsfiddle

    0 讨论(0)
  • 2020-12-12 17:46

    I realize that this is an old question, however, I recently stumbled upon this problem myself and spent a lot of time trying to find the best working code. Everything I found was either too complicated or didn't work without lagging a lot, especially in Chrome. As pointed out by others, the problem cannot be solved by pure CSS, but I made my own simple AngularJS directive to solve the problem:

    app.directive("paraBack", ['$window', function ($window) {
      return function(scope, element, attrs) {
        element.css("background-image", "url("+attrs.paraBack+")"); // Apply the background image with CSS
        element.css("background-attachment", "fixed"); // Disable background scrolling
    
        var max = Infinity;
    
        var image = new Image(); // Create a JavaScript image so that the code below can be run when the background is loaded
        image.src = attrs.paraBack;
        image.onload = function () {
          max = image.height - window.innerHeight; // Stop scrolling after the bottom of the picture is reached
          var xOffset = -(image.width/2-window.innerWidth/2);
          element.css("background-position-x", xOffset+'px'); // Horizontally align the background
        }
    
        var scrollHandler = function () {
          var offset = Math.floor(this.pageYOffset*0.1); // Set background to scroll at 10% of scrolling speed
          if (offset<max) {
            element.css('background-position-y', '-'+offset+'px'); // If not the bottom of the image is reached, move the background (scroll)
          }
        };
    
        angular.element($window).on('scroll', scrollHandler); // Set the defined scrollHandler function to be ran when user scroll
    
        scope.$on('$destroy', function () {
          angular.element($window).off('scroll', scrollHandler); // Unbind the function when the scope is destroyed
        });
      };
    }]);
    

    It can be used in the html like this:

    <body para-back="url/to/image">
    

    If you want to see an example of what it looks like, you can visit this page.

    0 讨论(0)
  • 2020-12-12 17:49

    If you want to apply a high background image, use this JS:

    (function () {
            var body = document.body,
                    e = document.documentElement,
                    scrollPercent;
            $(window).unbind("scroll").scroll(function () {
                scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());
                body.style.backgroundPosition = "0px " + scrollPercent + "%";
            });
    })();
    
    0 讨论(0)
  • 2020-12-12 17:53

    I stumbled upon this looking for more flexibility in my parallax speed that I have created with pure CSS and I just want to point out that all these people are wrong and it is possible with pure CSS It is also possible to control the height of your element better.

    You will probably have to edit your DOM/HTML a bit to have some container elements, in your case you are applying the background to the body which will restrict you a lot and doesn't seem like a good idea.

    http://keithclark.co.uk/articles/pure-css-parallax-websites/

    Here is how you control the height with Viewport-percentage lenghts based on screen size:

    https://stanhub.com/how-to-make-div-element-100-height-of-browser-window-using-css-only/

      .forefront-element {
        -webkit-transform: translateZ(999px) scale(.7);
        transform: translateZ(999px) scale(.7);
        z-index: 1;
      }
    
      .base-element {
        -webkit-transform: translateZ(0);
        transform: translateZ(0);
        z-index: 4;
      }
    
      .background-element {
        -webkit-transform: translateZ(-999px) scale(2);
        transform: translateZ(-999px) scale(2);
        z-index: 3;
      }
    

    Layer speed is controlled by a combination of the perspective and the Z translation values. Elements with negative Z values will scroll slower than those with a positive value. The further the value is from 0 the more pronounced the parallax effect (i.e. translateZ(-10px) will scroll slower than translateZ(-1px)).

    Here is a demo I found with a google search because I know there are a lot of non-believers out there, never say impossible:

    http://keithclark.co.uk/articles/pure-css-parallax-websites/demo3/

    0 讨论(0)
提交回复
热议问题