视差效果 - 强制文本块的行为类似于背景附件:固定

时间:2018-04-10 22:52:21

标签: javascript html css css3

我正在尝试创建一个简单的视差效果,其中每个100vh部分向上滚动以显示下一部分(新背景颜色,背景图像和文本块),同时保持文本块相对于其父级固定容器

我已经使用每个部分的屏幕截图组合了一个我想要实现的静态示例:static example。当然,我希望内容是动态的,而不是平面图像。

到目前为止,这是我的代码的简单版本:

body {
  margin: 0;
  padding: 0;
}
h2 {
  font-size: 48px;
}
p {
  font-size: 18px;
}
section {
  min-height: 100vh;
  width: 100%;
  text-align: center;
  position: relative;
  background-attachment: fixed !important;
  background-size: cover !important;
  background-repeat: no-repeat !important;
}
section.first {
  background: url(https://picsum.photos/1920/500/?image=1057);
}
section.first .content {
  background-color: rgba(74, 180, 220, .85);
}
section.second {
  background: url(https://picsum.photos/1920/500/?image=1067);
}
section.second .content {
  background-color: rgba(103, 198, 180, .85)
}
section.third {
  background: url(https://picsum.photos/1920/500/?image=1033);
}
section.third .content {
  background-color: rgba(5, 123, 188, .85);
}
section.fourth {
  background: url(https://picsum.photos/1920/500?image=1063);
}
section.fourth .content {
  background-color: rgba(187, 216, 100, .85)
}
.content {
  position: relative;
  height: 100vh;
  width: 100%;
  padding: 50px 0;  
}
.copy {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  font-family: 'Noto Serif', serif;
  font-weight: 300;
}
.button {
  border: 2px solid #fff;
  border-radius: 3px;
  padding: 15px 25px;
  display: inline-block;
  width: auto;
  font-family: 'Assistant', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  transition: .2s ease all;
}
.button:hover {
  background: #fff;
  color: #333;
  cursor: pointer;
}
<body>
	<section class="first">
		<div class="content">
			<div class="copy">
				<h2>Header 1  </h2>
				<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
			</div>
		</div>
	</section>
	<section class="second">
		<div class="content">
			<div class="copy">
				<h2>Header 2</h2>
				<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
			</div>
		</div>
	</section>
	<section class="third">
		<div class="content">
			<div class="copy">
				<h2>Header 3</h2>
				<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
			</div>
		</div>
	</section>
	<section class="fourth">
		<div class="content">
			<div class="copy">
				<h2>Call to action</h2>
				<a class="button">Button</a>
			</div>
		</div>
	</section>
</body>

使用CSS background-attachment: fixed实现视差效果,效果很好;麻烦在于文本块。我想让他们“固定”到位,并在他们的部分中心。如果它们设置为position: fixed,它们当然会相互重叠,并且都显示在第一部分中。如果将它们设置为任何其他位置属性,它们将像任何其他元素一样滚动。

现在,我意识到将元素的位置设置为fixed意味着它不再相对于其父元素;它可以说是逃避了流程,但我试图确定是否有办法通过一些高级CSS甚至是JS替代方案来实现这种效果。

我尝试了很多HTML / CSS组合(包装器中的包装器等),我也尝试了各种javascript解决方案,例如rellax,jarallax和ScrollMagic,但我遇到的一切都太强大了我的需要。我一直在四处搜寻,希望找到一个我正在尝试的例子,但没有运气。

2 个答案:

答案 0 :(得分:2)

previous question中,我对图像和使用一些JS做了类似的效果,所以我将使用相同的技术使用内容重现这一点,因为我认为没有纯CSS解决方案。因此,我们的想法是通过使用绝对位置来模拟固定位置,并在滚动时动态调整top属性。

这是一个例子,我也调整了一些CSS以使其更容易。我还将依赖CSS变量来使JS代码非常轻,因此我们可以使用CSS管理所有内容。

window.onscroll = function() {
  var scroll = window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop;
  document.documentElement.style.setProperty('--scroll-var', scroll + "px");
}
:root {
  --scroll-var: 0px
}

body {
  margin: 0;
  padding: 0;
}

h2 {
  font-size: 48px;
}

p {
  font-size: 18px;
}

section {
  min-height: 100vh;
  width: 100%;
  text-align: center;
  overflow: hidden;
  background-attachment: fixed !important;
  background-size: cover !important;
  background-repeat: no-repeat !important;
  position: relative; /*Mandatory for the overflow effect*/
  height: 100vh;
}

section.first {
  background: linear-gradient(rgba(74, 180, 220, .85), rgba(74, 180, 220, .85)), url(https://picsum.photos/1920/500/?image=1057);
}

section.first .content {
  /* the first section so top start from 0*/
  top: calc((0 * 100vh) + var(--scroll-var));
}

section.second {
  background: linear-gradient(rgba(103, 198, 180, .85), rgba(103, 198, 180, .85)), url(https://picsum.photos/1920/500/?image=1067);
}

section.second .content {
  /* the second section so we need to remove the height of top section
     to have the same position so -100vh and we do the same for the other sections  
  */
  top: calc((-1 * 100vh) + var(--scroll-var));
}

section.third {
  background: linear-gradient(rgba(5, 123, 188, .85), rgba(5, 123, 188, .85)), url(https://picsum.photos/1920/500/?image=1033);
}

section.third .content {
  top: calc((-2 * 100vh) + var(--scroll-var));
}

section.fourth {
  background: linear-gradient(rgba(187, 216, 100, .85), rgba(187, 216, 100, .85)), url(https://picsum.photos/1920/500?image=1063);
}

section.fourth .content {
  top: calc((-3 * 100vh) + var(--scroll-var));
}

.content {
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.copy {
  color: #fff;
  font-family: 'Noto Serif', serif;
  font-weight: 300;
  max-width: 300px;
}

.button {
  border: 2px solid #fff;
  border-radius: 3px;
  padding: 15px 25px;
  display: inline-block;
  width: auto;
  font-family: 'Assistant', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  transition: .2s ease all;
}

.button:hover {
  background: #fff;
  color: #333;
  cursor: pointer;
}
<body>
  <section class="first">
    <div class="content">
      <div class="copy">
        <h2>Header 1 </h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="second">
    <div class="content">
      <div class="copy">
        <h2>Header 2</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="third">
    <div class="content">
      <div class="copy">
        <h2>Header 3</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="fourth">
    <div class="content">
      <div class="copy">
        <h2>Call to action</h2>
        <a class="button">Button</a>
      </div>
    </div>
  </section>
</body>

答案 1 :(得分:0)

我已经提出了一个小片段,这是有效的。但是你需要弄清楚自己定位背后的确切数学。当然还要注意细节

&#13;
&#13;
$( document ).ready(function() {
    $(document).scroll(function() {
      // get the position of my first slide, so I know where did I move
      var rect = $(".first")[0].getBoundingClientRect();
      
      // get height of viewport
      var screenHeight = $( window ).height();
      
      // setting offset for every .copy element on page, so they share
      // the same offset from top (are on top of each other)
      // Now you just need to figure out exact math here
      $(".copy").offset({ top: screenHeight*1.5-rect.bottom});
    });
});
&#13;
body {
  margin: 0;
  padding: 0;
}

h2 {
  font-size: 48px;
}

p {
  font-size: 18px;
}

section {
  min-height: 100vh;
  width: 100%;
  text-align: center;
  position: relative;
  background-attachment: fixed !important;
  background-size: cover !important;
  background-repeat: no-repeat !important;
  
  /* added overflow hidden, so that my boxes don't flow out of the slide */
  overflow: hidden;
}

section.first {
  background: url(https://picsum.photos/1920/500/?image=1057);
}

section.first .content {
  background-color: rgba(74, 180, 220, .85);
}

section.second {
  background: url(https://picsum.photos/1920/500/?image=1067);
}

section.second .content {
  background-color: rgba(103, 198, 180, .85)
}

section.third {
  background: url(https://picsum.photos/1920/500/?image=1033);
}

section.third .content {
  background-color: rgba(5, 123, 188, .85);
}

section.fourth {
  background: url(https://picsum.photos/1920/500?image=1063);
}

section.fourth .content {
  background-color: rgba(187, 216, 100, .85)
}

.content {
  position: relative;
  height: 100vh;
  width: 100%;
  padding: 50px 0;
}

.copy {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  font-family: 'Noto Serif', serif;
  font-weight: 300;
}

.button {
  border: 2px solid #fff;
  border-radius: 3px;
  padding: 15px 25px;
  display: inline-block;
  width: auto;
  font-family: 'Assistant', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  transition: .2s ease all;
}

.button:hover {
  background: #fff;
  color: #333;
  cursor: pointer;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
  <section class="first">
    <div class="content">
      <div class="copy">
        <h2>Header 1 </h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="second">
    <div class="content">
      <div class="copy">
        <h2>Header 2</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="third">
    <div class="content">
      <div class="copy">
        <h2>Header 3</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="fourth">
    <div class="content">
      <div class="copy">
        <h2>Call to action</h2>
        <a class="button">Button</a>
      </div>
    </div>
  </section>
</body>
&#13;
&#13;
&#13;