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



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

我整理了一个静态示例,说明我试图使用每个部分的屏幕截图实现的目标:静态示例。当然,我希望内容是动态的,而不是平面图像。

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

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>

视差效果是使用 CSSbackground-attachment: fixed实现的,工作得很好;问题在于文本块。我想将它们"固定"到位并居中。如果它们设置为position: fixed它们当然会相互重叠,并且都显示在第一部分中。如果将它们设置为任何其他位置属性,它们将像任何其他元素一样滚动。

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

我尝试了许多HTML/CSS组合(包装器中的包装器等),我也尝试了各种JavaScript解决方案,如rellax,jarallax和ScrollMagic,但我遇到的一切都太强大了,无法满足我的需求。我四处寻找了大半天,希望找到我正在尝试的例子,但没有运气。

在上一个问题中,我对图像并使用了一些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>

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

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

最新更新