To get began with Locomotive Scroll, it’s a must to embody the next recordsdata in your venture:
- The
locomotive-scroll.css
file or its minified model - The
locomotive-scroll.js
file or its minified model
You possibly can obtain them by visiting its GitHub repo, utilizing a bundle supervisor (e.g. npm), or loading the required property via a CDN (e.g. jsDelivr). For this tutorial, we’ll select the final possibility.
As mentioned within the introduction, for this demonstration, past the Locomotive recordsdata, we’ll additionally incorporate Tailwind CSS to create the web page structure.
With that in thoughts, for those who look underneath the Settings tab of our demo pen, you’ll see that there are two exterior CSS recordsdata and one exterior JavaScript file.
1. Structuring the Web page
Locomotive Scroll comes with a number of completely different information
attributes for manipulating the weather. We’ll use lots of them, so on the finish of this tutorial you’ll have a very good grasp of what they do and the way you should use them.
Let’s begin by specifying a wrapper ingredient with the data-scroll-container
attribute. Inside it we’ll place the web page sections and a back-to-top hyperlink. In a while, we’ll initialize the plugin by focusing on this wrapper.
All web page sections could have the data-scroll-section
attribute. Plus, nearly all of them could have an id
attribute. This attribute will assist us easily navigate to focus on sections via the menu and back-to-top hyperlinks.
Right here’s the preliminary web page construction:
<div data-scroll-container> <part id="intro" class="h-screen flex items-center justify-center text-center bg-green-200" data-scroll-section>...</part> <part class="py-40" data-scroll-section>...</part> <part id="about-section" class="py-40 bg-green-50" data-scroll-section>...</part> <part id="workplace" class="py-20" data-scroll-section>...</part> <part id="companies" class="relative py-60 bg-green-50" data-scroll-section>...</part> <part id="case-studies" class="text-center" data-scroll-section>...</part> <part id="clients-section" class="py-40" data-scroll-section>...</part> <part id="contact" class="py-80 border-t-2 border-solid border-gray-50" data-scroll-section>...</part> <part class="h-screen flex items-center justify-center text-center bg-green-200" data-scroll-section>...</part> <a category="back-to-top fastened bottom-24 right-4 text-red-500 hover:text-red-600 focus:text-red-600 transition opacity-0 invisible" href="#intro" position="button" aria-label="Again to high" data-scroll-to> <svg aria-hidden="true" xmlns="https://www.w3.org/2000/svg" width="40" peak="40" viewBox="0 0 24 24"> <path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm0 7.58l5.995 5.988-1.416 1.414-4.579-4.574-4.59 4.574-1.416-1.414 6.006-5.988z" /> </svg> </a> </div>
At this level, we’re able to have a more in-depth have a look at the vital web page sections.
Part #1
The primary part will embody a heading and a paragraph.
One other vital factor right here: by default, the back-to-top hyperlink received’t seem. As we scroll:
- If the heading is in view, the hyperlink will probably be/stay invisible.
- It can seem solely when the heading isn’t in view.
To implement this performance, we’ll move the data-scroll
, data-scroll-repeat
, and data-scroll-call="toggleBackToTop"
attributes to the heading. Let’s now focus on somewhat additional the position of those attributes:
- The job of the
data-scroll
attribute is to examine if the ingredient is in view. As quickly because it seems for the primary time, the plugin will add theis-inview
class to it. This class received’t be eliminated any extra. Discover additionally how the plugin modifies the ingredient’s CSSremodel
property to use the completely different results.
- The job of the
data-scroll-repeat
attribute is to examine repeatedly if the ingredient is in view. The plugin will toggle theis-inview
class relying on the ingredient’s place. In our case, we’ll use this attribute solely in pair with thedata-scroll-call
attribute that wants it to work correctly. - The job of the
data-scroll-call
attribute is to set off Locomotive’sname
occasion. The attribute worth that may be something we would like is handed as a parameter to the occasion callback and permits us to do stuff when the goal ingredient enters or leaves the viewport. It’s a bit arduous to elucidate it with phrases, so it’s higher that you simply see the JavaScript code. We’ll work with it once more within the upcoming sections. As mentioned, keep in mind that we’ll use it along with thedata-scroll-repeat
attribute.
Right here’s how we construction this part:
<part id="intro" class="h-screen flex items-center justify-center text-center bg-green-200" data-scroll-section> <div class="container px-5 mx-auto"> <h1 class="text-5xl font-bold" data-scroll data-scroll-repeat data-scroll-call="toggleBackToTop">A Easy Demo With <a category="underline" href="https://locomotivemtl.github.io/locomotive-scroll/" goal="_blank">Locomotive Scroll</a></h1> <p class="text-2xl mt-2">Scroll down 👇</p> </div> </part>
Part #2
The second part will embody the menu hyperlinks.
To navigate easily to web page sections upon clicking a hyperlink, we now have to offer the data-scroll-to
attribute to the hyperlinks.
Observe: we’ll move the identical attribute to the back-to-top hyperlink.
Needless to say this attribute isn’t a part of the docs on the time of this writing. Should you’re questioning how I learn about its existence, the reply is that I discovered it by checking the supply code of the plugin’s GitHub Web page.
Alternatively, for those who don’t need to use this attribute, you may obtain this performance utilizing some JavaScript scrolling strategies.
Right here’s how we construction this part:
<part class="py-40" data-scroll-section> <div class="lg:container px-5 mx-auto"> <nav> <ul class="grid md:grid-flow-col gap-4 lg:gap-16 justify-center text-center"> <li> <a category="inline-block text-2xl font-medium px-4 py-2 border-4 border-double border-transparent hover:border-green-400 focus:border-green-400 rounded-md transition" href="#about-section" data-scroll-to> About </a> </li> <li> <a category="inline-block text-2xl font-medium px-4 py-2 border-4 border-double border-transparent hover:border-green-400 focus:border-green-400 rounded-md transition" href="#workplace" data-scroll-to> Workplace </a> </li> ... </ul> </nav> </div> </part>
Part #3
The third part will embody a heading and a few textual content.
As we scroll, we’ll pin the heading to the highest. However, for a way lengthy? Properly, till we scroll previous its guardian. At that time, the ingredient will disappear as it’s going to then be a part of the traditional doc circulation.
To implement this performance, we’ll assign the data-scroll
, data-scroll-sticky
, and data-scroll-target="#about"
attributes to the heading. Some notes:
- As we already know, the
data-scroll
attribute will detect if our ingredient is in view. - The
data-scroll-sticky
attribute will make it sticky in pair with thedata-scroll-target
attribute. - The worth of the
data-scroll-target
attribute will decide the ingredient’s preliminary and closing sticky positions.
We’ll observe the identical method within the seventh (purchasers) part, so we’ll skip that one.
Right here’s how we construction this part:
<part id="about-section" class="py-40 bg-green-50" data-scroll-section> <div class="container px-5 mx-auto"> <div id="about" class="lg:grid grid-cols-2 gap-4 items-start"> <h2 class="text-5xl font-extrabold" data-scroll data-scroll-sticky data-scroll-target="#about">About</h2> <div class="text-xl pt-4 lg:pt-0">...</div> </div> </div> </part>
Part #4
The fourth part will embody two Unsplash photographs.
As we scroll, a parallax impact will occur. To be extra particular, the primary picture will transfer 4 instances quicker than the second.
To implement this performance, we’ll move the data-scroll
and data-scroll-speed
attributes to the photographs. The worth of the second attribute will decide their scrolling pace. Right here we’ll give data-scroll-speed="4.8"
to the primary picture and data-scroll-speed="1.2"
to the second.
Right here’s how we construction this part:
<part id="workplace" class="py-20" data-scroll-section> <div class="sm:grid grid-cols-2 gap-40"> <determine class="flex items-end"> <img class="shadow-lg" width="1000" peak="667" src="https://webdesign.tutsplus.com/tutorials/office1.jpg" alt="" data-scroll data-scroll-speed="4.8"> </determine> <determine> <img class="shadow-lg" width="1000" peak="1498" src="office2.jpg" alt="" data-scroll data-scroll-speed="1.2"> </determine> </div> </part>
Part #5
The fifth part will embody a heading and two textual content banners explaining our companies.
As we scroll, a number of parallax results will happen:
- First, the heading’s letters will transfer at completely different speeds. Plus, every time they come into sight, they may obtain a random shade from an inventory of predefined colours.
- Second, the banners will transfer horizontally in several instructions.
To implement this performance, we’ll do the next:
- Assign the
data-scoll
,data-scroll-repeat
,data-scroll-speed
, anddata-scroll-call="randomizeTextColor"
attributes to the heading’s letters. As we would like a parallax impact, the worth of thedata-scroll-speed
attribute will fluctuate for every letter. Keep in mind the position of thedata-scroll-call
attribute. Right here we’re saying: because the letters enter the viewport and Locomotive’sname
occasion fires, do one thing. Should you examine the JavaScript part, you’ll discover that at this level thegetRandomColor()
perform is firing. Optionally, right here we will additionally put into motion thedata-scroll-delay
attribute. - Assign the
data-scroll
,data-scroll-direction="horizontal"
,data-scroll-speed
, anddata-scroll-target="#companies"
attributes to the banners. Thedata-scroll-direction="horizontal"
will transfer the weather horizontally on scroll. Subsequent, by giving them reverse values for thedata-scroll-speed
attribute, we be sure that they may transfer in several instructions (from left to proper or proper to left). Lastly, thedata-scroll-target="#companies"
attribute will decide when the horizontal animations ought to begin. To know it, attempt to put theid
of one other part e.g.data-scroll-target="#workplace"
and reload the web page. Discover that the animations begin a lot ahead of they need to be.
Right here’s how we construction this part:
<part id="companies" class="relative py-60 bg-green-50" data-scroll-section> <h2 class="absolute top-1/2 left-1/2 remodel -translate-x-1/2 -translate-y-1/2 -skew-x-12 whitespace-nowrap text-6xl sm:text-9xl font-extrabold py-4"> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="3" data-scroll-call="randomizeTextColor">S</span> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="2" data-scroll-call="randomizeTextColor">e</span> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="3" data-scroll-call="randomizeTextColor">r</span> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="2" data-scroll-call="randomizeTextColor">v</span> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="3" data-scroll-call="randomizeTextColor">i</span> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="2" data-scroll-call="randomizeTextColor">c</span> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="3" data-scroll-call="randomizeTextColor">e</span> <span class="inline-block" data-scroll data-scroll-repeat data-scroll-speed="2" data-scroll-call="randomizeTextColor">s</span> </h2> <div class="remodel rotate-6 skew-x-12"> <div data-scroll data-scroll-direction="horizontal" data-scroll-speed="20" data-scroll-target="#companies"> <span class="text-3xl sm:text-4xl md:text-6xl 2xl:text-7xl bg-green-400 p-5 whitespace-nowrap">Social Media — Electronic mail Advertising — Digital Promoting</span> </div> </div> <div class="remodel -rotate-6 -skew-x-12 mt-40"> <div data-scroll data-scroll-direction="horizontal" data-scroll-speed="-20" data-scroll-target="#companies"> <span class="text-3xl sm:text-4xl md:text-6xl 2xl:text-7xl bg-green-400 p-5 whitespace-nowrap">Internet Growth - Movement Design - Graphic Design</span> </div> </div> </part>
Part #6
The sixth part will embody three featured case research. Every case examine will include a heading, a picture, and a hyperlink to the case examine’s inside web page.
As we scroll, every time a case examine’s heading (identify) comes into view, the background shade of the physique
ingredient will change primarily based on the worth of the data-bg
attribute of the related part.
To implement this performance, we may once more use the name
occasion, which might be a extra environment friendly method. However, let’s, this time, reap the benefits of one other occasion that the library offers, the scroll
one. Verify the Javascript code for higher element on how we deal with this occasion.
Concerning the customized attributes:
- We’ll give the
data-bg-color
attribute to every part with the specified shade worth. - We’ll add the
data-scroll
anddata-scroll-repeat
attributes to the headings so this performance is repeated as we scroll. Observe that we will customise the time that the library toggles theis-inview
class through thedata-scroll-offset
attribute.
Right here’s how we construction this part:
<part id="case-studies" class="text-center" data-scroll-section> <part class="py-32 border-b-2 border-gray-400 sub-section" data-bg-color="#aed9e0"> <div class="container px-5 mx-auto"> <h2 class="text-5xl font-extrabold" data-scroll data-scroll-repeat>...</h2> <determine class="my-16"> <img class="shadow-lg mx-auto" width="1000" peak="667" src="https://webdesign.tutsplus.com/tutorials/case-study-1.jpg" alt=""> </determine> <a category="text-3xl" href="#" data-scroll>...</a> </div> </part> <!-- two extra sections right here --> </part>
Should you want the physique shade to alter primarily based on the part’s visibility and never on the heading’s visibility, take away the data-scroll
and data-scroll-repeat
attributes from the headings, and add them to the sections. Additionally, make the changes wanted on the JavaScript code.
Additionally, you do not have to cease solely on the physique shade. Relying in your structure, you may change the textual content shade of every part, add animations, and so forth.
Part #8
The eighth part will embody a call-to-action heading.
As we scroll, two issues will occur:
- First, every time the heading comes into view, it’s going to obtain a random shade, just like the earlier instance.
- Second, we’ll animate every letter by creating one other parallax (lerp) impact.
To implement this performance, we’ll do the next:
- Assign the
data-scoll
,data-scroll-repeat
, anddata-scroll-call="randomizeTextColor"
attributes to the heading. Keep in mind that we’ve already met thedata-scroll-call="randomizeTextColor"
attribute. It’s completely fantastic to make use of it right here as effectively. - Assign the
data-scroll
,data-scroll-delay
, anddata-scroll-speed="5"
attributes to every letter. All letters will transfer 5 instances quicker than regular scrolling, but with completely different delays. For instance, the primary letter could havedata-scroll-delay="0.15"
whereas the seconddata-scroll-delay="0.095"
. This may create the lerp/staggering impact. Once more you may see lerp results within the plugin’s showcase instance.
Right here’s how we construction this part:
<part id="contact" class="py-80 border-t-2 border-solid border-gray-50" data-scroll-section> <div class="container px-5 mx-auto text-center"> <h2 class="text-2xl sm:text-5xl font-extrabold py-4" data-scroll data-scroll-repeat data-scroll-call="randomizeTextColor"> <span class="inline-block" data-scroll data-scroll-delay="0.15" data-scroll-speed="5">h</span> <span class="inline-block" data-scroll data-scroll-delay="0.095" data-scroll-speed="5">e</span> <span class="inline-block" data-scroll data-scroll-delay="0.085" data-scroll-speed="5">l</span> <span class="inline-block" data-scroll data-scroll-delay="0.075" data-scroll-speed="5">l</span> <span class="inline-block" data-scroll data-scroll-delay="0.065" data-scroll-speed="5">o</span> <span class="inline-block" data-scroll data-scroll-delay="0.055" data-scroll-speed="5">@</span> <span class="inline-block" data-scroll data-scroll-delay="0.045" data-scroll-speed="5">g</span> <span class="inline-block" data-scroll data-scroll-delay="0.035" data-scroll-speed="5">e</span> <span class="inline-block" data-scroll data-scroll-delay="0.035" data-scroll-speed="5">o</span> <span class="inline-block" data-scroll data-scroll-delay="0.045" data-scroll-speed="5">r</span> <span class="inline-block" data-scroll data-scroll-delay="0.055" data-scroll-speed="5">g</span> <span class="inline-block" data-scroll data-scroll-delay="0.065" data-scroll-speed="5">e</span> <span class="inline-block" data-scroll data-scroll-delay="0.075" data-scroll-speed="5">.</span> <span class="inline-block" data-scroll data-scroll-delay="0.085" data-scroll-speed="5">c</span> <span class="inline-block" data-scroll data-scroll-delay="0.095" data-scroll-speed="5">o</span> <span class="inline-block" data-scroll data-scroll-delay="0.15" data-scroll-speed="5">m</span> </h2> </div> </part>
2. Initializing the Plugin
We’ve talked about most of the plugin’s options, but we haven’t initialized it. Let’s try this now.
Right here’s all of the required JavaScript code:
const physique = doc.physique; const backToTop = doc.querySelector(".back-to-top"); const opacityClass = "opacity-0"; const visibilityClass = "invisible"; const scroll = new LocomotiveScroll({ el: doc.querySelector("[data-scroll-container]"), easy: true, pill: { easy: true }, smartphone: { easy: true } }); const arrayOfColors = [ "#0a9396", "#005f73", "#ae2012", "#3d405b", "#003049", "#bc6c25", "#ff006e", "#ef476f", "#1982c4", "#ee964b", "#0ead69", "#390099", "#f6aa1c", "#54101d", "#2b2c28", "#85c7f2", "#e15a97", "#2b70e3", "#b36a5e" ]; perform getRandomColor() { const arrayLength = arrayOfColors.size; const randomValue = Math.random() * arrayLength; const roundedNumber = Math.ground(randomValue); const shade = arrayOfColors[roundedNumber]; return shade; } scroll.on("name", (worth, means, obj) => { if (worth === "randomizeTextColor") { if (means === "enter") { obj.el.model.shade = getRandomColor(); } } else if (worth === "toggleBackToTop") { if (means === "enter") { backToTop.classList.add(opacityClass, visibilityClass); } else { backToTop.classList.take away(opacityClass, visibilityClass); } } }); scroll.on("scroll", (occasion) => { const visibleSubSectionHeading = doc.querySelector( ".sub-section h2.is-inview" ); if (visibleSubSectionHeading) { const parentSection = visibleSubSectionHeading.parentElement.parentElement; physique.model.backgroundColor = parentSection.dataset.bgColor; } else { physique.model.backgroundColor = ""; } });
Some fast notes:
- We’ll maintain its easy habits throughout all units.
- Discover the parameters of the
name
occasion callback. The primary one (i.e.worth
) holds the values of thedata-scroll-call
attributes. Utilizing anif
situation, we examine to see which values are energetic every time, then whether or not the related components enter or go away the viewport, and at last, we carry out the specified actions. - Though not utilized in our case, the callback of the
scroll
occasion accepts one parameter that gives helpful data. For instance, how a lot have we scrolled and which components are presently in view. Use your browser console to see the output of this parameter.
Conclusion
Congrats, people! We managed to construct a parallax scrolling web site due to Locomotive Scroll. Hopefully, this train has revealed the facility of this tiny library and motivated you to begin creating superior scrolling results effortlessly.
Right here’s a reminder of what we constructed:
Don’t overlook to offer it some love ❤️!
Earlier than closing, let me go away you with a number of ideas:
- As with each expertise/instrument/library, one of the best ways to study Locomotive Scroll is thru its docs. Go forward, examine the revealed instance and use your browser instruments to examine its supply code. Additionally, examine its GitHub repo for points, how energetic the venture is, how different individuals use the library, or simply for taking some concepts. Should you really feel extra adventurous, examine the plugin’s native code. Right here you’ll study issues like what parameters a perform (e.g. the callback of the
name
occasion) can settle for, and so forth. - Scrolling results can lower a web site’s efficiency. Apart from this truth, the extra advanced the consequences, the extra danger there may be they may encounter points throughout completely different browsers/units. For instance, on cellular units I might keep away from utilizing the horizontal animations we coated.
- For much more highly effective locomotive scroll results, you may mix Locomotive Scroll with different animation libraries like GSAP and barba.js.
Have you ever ever used Locomotive Scroll and Tailwind to construct a easy scrolling web site? What different plugins have you ever tried in that route?
Final however not least, an enormous due to Locomotive builders for this plugin! As all the time, thanks lots for studying, and make sure to share with us your Locomotive tasks!
Take a look at these different tutorials to study extra about JavaScript and scrolling: