Every example uses simple common layout with associated CSS:
<section role="parallax-container"> <div parallax="anim-stage"> Content will scroll during 0%-33% progress, then stop, and continue up during 66%-100%... </div> </section>
section { height: 200vh; /* 2x the screen to make scrolling longer */ } /* Position fixed: ensures smooth animation across browsers */ [parallax~="anim-stage"] { position: fixed; height: 100vh; width: 100vw; background-color: #EFEFEF; } /* We can hide whole content when it is off-screen = animation status is "off" */ [parallax~="anim-stage"][parallax-status="off"] { display: none; } /* Slide stage up nicely, and slide out after while */ @keyframes anim-stage { 0% {top: 100vh;} 33.3333% {top: 0vh;} 66.6666% {top: 0vh;} 100% {top: -100vh;} }
The section
element will govern animation progress of nested animations thanks to
role="parallax-container"
attribute. Such element we call parallax container.
section
element will be bellow screen all animations will be set to the beginning of timeline (0%
).section
's center aligns with screen center nested animations progress to 50%
of the animation timeline.section
's will scroll up off-screen nested animations will be set to 100%
progress.
In addition when parallax container is off-screen it gets an attribute parallax-status="off"
. Analogically
when animated (progress is between 0%
and 100%
) it has an attribute parallax-status="off"
.
There is also parallax-progress
helper attribute set on all parallax containers and animated elements
that holds animation progress. Check DOM Inspector to see how it changes. Similarly parallax-step
attribute
holds the same value rounded to nearest 5/10. You can use it in your CSS. For example to assign different background color
when animation is between 10%
and 19%
you can use selector [parallax-step~="deca-10"] {background: silver;}
.
This is simple example. Word "Content..." will appear on bottm when section
element
enters viewport: animation 0% - 33%. Then it will stop during timeline 33% - 66% and then continue up: 66% - 100%.
Let define simple CSS animaton for fly-in and rotate effects. Effects start at 0% (parallax container enters the screen on bottom) and stop at 33% (parallax container having 200vh height is alligned with top of the screen).
<div class="box" parallax="fly-in-left"></div> <div class="box" parallax="fly-in-right"></div>
@keyframes fly-in-right { 0% {transform: translateX(100vh) rotate(360deg);} 33% {transform: translateX(0vh) rotate(0deg);} } @keyframes fly-in-left { 0% {transform: translateX(-100vh) rotate(-360deg);} 33% {transform: translateX(0vh) rotate(0deg);} }
You can use previous fly-in-right
and fly-out-right
animations and you can combine them, reverse them or scale on timeline.
If you use attribute
parallax="fly-in-right"
it will apply
animation as defined by @keyframes
statement. If you suffix it with :reverse
modifier it will apply the same animation in reverse
order.
Wile fly-in-right
will move element from right to center during
0% - 33% of timeline, fly-in-right:reverse
will reverse the animation
to start moving from center to left during 66% - 100% of timeline progress.
You can also combine the animations by specifying more then one in parallax
attribute.
E.g. parallax="fly-in-right fly-in-right:reverse"
will merge animations into one where
element flies in from right during 0% - 33% and then during 66% - 100% it flies back from where it came.
<div class="box" parallax="fly-in-left fly-in-left:reverse"></div> <div class="box" parallax="fly-in-right fly-in-right:reverse"></div>
You can use also :shift(n%)
and :scale(n)
modifiers to delay or scale animation progress.
<div class="row"> <div class="box" parallax="fly-in-left:shift(15%) fly-in-left:reverse:shift(-5%)"></div> <div class="box" parallax="fly-in-left:shift(5%) fly-in-left:reverse:shift(5%)"></div> <div class="box" parallax="fly-in-left:shift(-5%) fly-in-left:reverse:shift(15%)"></div> <div class="box" parallax="fly-in-right:shift(-5%) fly-in-right:reverse:shift(15%)"></div> <div class="box" parallax="fly-in-right:shift(5%) fly-in-right:reverse:shift(5%)"></div> <div class="box" parallax="fly-in-right:shift(15%) fly-in-right:reverse:shift(-5%)"></div> </div> <div class="row"> <div class="box" parallax="fly-in-left:scale(1.3) fly-in-left:scale(1.3):reverse"></div> <div class="box" parallax="fly-in-left:scale(1.1) fly-in-left:scale(1.1):reverse"></div> <div class="box" parallax="fly-in-left:scale(0.9) fly-in-left:scale(0.9):reverse"></div> <div class="box" parallax="fly-in-right:scale(0.9) fly-in-right:scale(0.9):reverse"></div> <div class="box" parallax="fly-in-right:scale(1.1) fly-in-right:scale(1.1):reverse"></div> <div class="box" parallax="fly-in-right:scale(1.3) fly-in-right:scale(1.3):reverse"></div> </div>
You are not limited to rotate and translate animations. You can use the full power of CSS animations.
<div class="sky-box" parallax="sky"> <div class="box" parallax="crazy"></div> </div>
.sky-box { width: 100vw; height: 100vh; display: flex; align-items: center; justify-content: center; background-image: url("sky.jpg"); background-attachment: fixed; background-repeat: repeat; } @keyframes sky { 0% {background-position: 0vw 40vh;} 33% {background-position: 0vw 0vh;} 66% {background-position: -40vw 0vh;} 100% {background-position: -40vw -40vh;} } @keyframes crazy { 0% { transform: translate(-50vw, -50vh) rotate(-720deg) scale(0.5) skewX(60deg); opacity: 0; filter: blur(5px); } 33% { transform: translate(0vh, 0vh) rotate(0deg) scale(1) skewX(0deg); opacity: 1; background-color: rgb(255, 0, 0); filter: blur(0px); } 50% { transform: translate(0vh, 0vh) rotate(0deg) scale(1) skewX(-60deg); filter: blur(10px); } 66% { transform: translate(0vh, 0vh) rotate(0deg) scale(1) skewX(0deg); opacity: 1; background-color: rgb(0, 255, 0); filter: blur(0px); border-radius: 0px; } 100% { transform: translate(0vw, 50vh) rotate(720deg) scale(2); background-color: rgb(0, 0, 255); opacity: 0; border-radius: 60px; } }
You can see the paging on the right side. Trick is
very easy. We want to animate each gear symbol based
on associted parallax container position. We
can bind any animation to position of any other
element using parallax-container
CSS selector.
<div class="paging"> <a href="#s1" parallax="paging-button" parallax-container="#s1">⚙</a> <a href="#s2" parallax="paging-button" parallax-container="#s2">⚙</a> <a href="#s3" parallax="paging-button" parallax-container="#s3">⚙</a> <a href="#s4" parallax="paging-button" parallax-container="#s4">⚙</a> <a href="#s5" parallax="paging-button" parallax-container="#s5">⚙</a> </div>
@keyframes paging-anim { 0% { background-color: rgb(0, 0, 0); transform: scale(1) rotate(0deg); } 50% { background-color: rgb(255, 0, 0); transform: scale(2) rotate(720deg); } 100% { background-color: rgb(0, 0, 0); transform: scale(1) rotate(1440deg); } }
You can link any parallax animation to a position of any other element relatively to a screen view.
Linked element is called parallax container and is determined as follows.
parallax-container="CSS_SELECTOR"
attribute then linked element will be selected by evaluating given CSS selector.parallax-container
in its role
attribute it will be used as parallax container.The parallax container's position starts at 0% when it is just bellow visible screen, 50% in the very middle, and ends at 100% just above visible screen.
Tip: Use browser's DOM Inpsector to inspect parallax-progress
attribute on animated element or its linked parallax container element.
As explained above any animated element can became parallax container itself. Animation progress will then depend on animated element's position relative to a screen. You can achieve easily quite interesting effects.
<div class="box" parallax="fly-in-left fly-in-right:reverse" role="parallax-container"></div> <div class="box" parallax="fly-in-left fly-in-right:reverse" role="parallax-container"></div> <div class="box" parallax="fly-in-left fly-in-right:reverse" role="parallax-container"></div> <div class="box" parallax="fly-in-left fly-in-right:reverse" role="parallax-container"></div> <div class="box" parallax="fly-in-left fly-in-right:reverse" role="parallax-container"></div> <div class="box" parallax="fly-in-left fly-in-right:reverse" role="parallax-container"></div>