(CSS) сделайте прокрутку фонового изображения медленнее, чем все остальное

вот мой код CSS для тела:

body {
  padding: 0;
  margin: 0;
  background-image: url("../images/background.jpg");
  background-repeat: no-repeat;
  background-color: grey; 
  background-size: 100%;
}

Я хочу сделать так, чтобы изображение прокручивалось медленнее, чем все остальное на странице, чтобы сделать простой эффект параллакса. Я посмотрел в интернете, и все примеры, которые я видел, намного сложнее, чем то, что я хочу.

6 ответов


я наткнулся на это, ища больше гибкости в моей скорости параллакса, которую я создал с помощью чистого CSS, и я просто хочу указать, что все эти люди ошибаются, и это возможно с чистым CSS также возможно контролировать высоту вашего элемента лучше.

вам, вероятно, придется немного отредактировать DOM / HTML, чтобы иметь некоторые элементы контейнера, в вашем случае вы применяете фон к телу, которое будет сильно ограничивать вас и не кажется хорошая идея.

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

вот как вы контролируете высоту с помощью Viewport-процентные длины на основе размера экрана:

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;
  }

скорость слоя контролируется комбинацией значений перспективы и перевода Z. Элементы с отрицательными значениями Z будут прокрутите медленнее, чем те, у которых положительное значение. Чем дальше значение от 0, тем более выраженный эффект параллакса (т. е. translateZ (- 10px) будет прокручиваться медленнее, чем translateZ (- 1px)).

вот демо, которое я нашел с помощью поиска google, потому что я знаю, что там много неверующих, никогда не говорите невозможно:

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


вы можете использовать что-то простое, как здесь: формат html:

движение

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;

    });
  };

})();

здесь jsfiddle


согласитесь, что это невозможно только с css, потому что вам нужно вычислить соотношение высоты изображения и документа. Мне также нравится этот эффект, поэтому создана простая функция, которая делает именно это. Вот функция и ее вызов на событие прокрутки:

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

вы можете найти его здесь вместе с примером и визуальным объяснением, что на самом деле происходит с изображением и документом:

плавная прокрутка фонового изображения


Если вы хотите применить высокое фоновое изображение, используйте это 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 + "%";
        });
})();

Я понимаю, что это старый вопрос, однако недавно я сам наткнулся на эту проблему и потратил много времени, пытаясь найти лучший рабочий код. Все, что я нашел, было либо слишком сложным, либо не работало без большого отставания, особенно в Chrome. Как указывали другие, проблема не может быть решена с помощью чистого CSS, но я сделал свою собственную простую директиву AngularJS для решения проблемы:

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
    });
  };
}]);

его можно использовать в html как это:

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

Если вы хотите увидеть пример, как это выглядит, вы можете на странице на этой странице.