In this tutorial you are going to learn how to create horizontally scrolling Elementor containers without any plugin.
You will also learn how to create an horizontal scrolling gallery.
This tutorial uses the new containers element, as they are perfect for this.
See the demos here.
Horizontally scrolling Elementor containers:
Horizontal Scrolling Gallery, Loop Grid, and Posts elements (scroll down all the way!) :
Horizontal Scrolling Woo Products
Features:
- Polyvalent: Make any content at all horizontally scrollable
- Works with native features: Compatible with Elementor's entrance animations
- Works everywhere: Works well and smoothly on desktop and mobile
- Performance optimized: The scroll event is throttled and we are using requestAnimationFrame for optimal CPU performance.
- No dependencies JavaScript: We aren't loading a large JS animation library like GSAP here. I coded the entire functionality in vanilla JS.
- Lightweight: This is the most lightweight way to do this kind of design, loading in only a very few KBs of JS and CSS.
- RTL compatible
- No plugins required
- New: Direct support for Gallery, Products and Loop Grid elements!
- New: Anchor links support
Important note: You will need the feature "Container" to be enabled under WP > Elementor > Features > Container. This uses the container element.
Templates included: All three templates you see above are included.
Let's get started!
First, import the template to your page
This is a premium tutorial. Purchase access to unlock the full tutorial and download the template.
92 Responses
How could I adjust this to allow me to set variable widths for each child container?
Hey Paul!
This is a bit complex, and above the scope of the tutorial. The tutorial is made to work with containers that are 100vw by 100vh, so that it's relatively simple and straightforward to use in the editor.
Changing this, while possible, makes it wonky in the editor, so that's why I don't officially support it.
However for adventurous users, both code snippets actually support this (varying containers sizes) out of the box.
Here is how you can play with this:
On the containers that are direct child of the horizontalScroll_translateContainer, in their advanced > custom CSS field, add this CSS, and adjust to your liking:
In the editor, it will be easier to edit things if you use values that are under 100vw, instead of above. In any case, both should work.
Different containers can have different widths.
Hope this helps!
Hey,
Not really no... not as it is at least. With extra work, it would be possible, however it is above the intended scope of this tutorial. It becomes quite specific and would rather be custom work.
No problem Maxime, I've found that is possible to use fixed or absolute positioning placing that items in "horizontalScroll_innerWrapper".
Even elementor motion effects works with GSAP setting the effect relative to "Entire Page".
Alright I'm glad you found a solution that works for your use case!
Thanks for sharing!
is it possible add locomotive scroll effect for the sections in vertical scroll?
tnx for all
Sorry Mirko, this isn't possible.
I had a good look at this and the problem with locomotive scroll is that it is very incompatible with Elementor. It breaks nearly every scroll related features of Elementor, such as entrance animations, scrolling effects, anchors smooth scroll, etc.
To prevent adding smooth scroll, but creating a host of problems, I opted to go with stability instead.
It is possible to use it with sections instead of containers ?
Thanks
It's possible, however due to the all the DIVs generated, it's not a really good idea. That's why this tutorial is only about how to do it with the containers.
it is possible to have a parallax effect ?
Not really unfortunately. Further custom code would be needed, and it would probably need to be project specific.
Hi Maxime ( - now commenting on correct tutorial!)
I'm still struggling to get this to work - https://blancheandco.co.uk
Been through the tips and code several times and I'm stuck, can you see what's wrong here?
Hey Louise!
The problem is that your containers, for some reason, aren't display:flex; but they are display:block;
It's the clear what the reason is... I suspect maybe your optimization plugin. It's as if some CSS is missing.
Adding
.e-container, .e-con { display: flex;}
should fix the problem
Cheers!
That sorted it! Thank you 🙂 Was my caching plugin as well I suspect - minifying CSS maybe, taken that off
Hi, how to make section scroll on click like the shop now button in the demo?
Hey Nicholas!
The "Shop now" button just has a "#" link that scrolls back up to the top of the page.
Unfortunately with this design it's not easily possible to have a button to scroll to a specific scroll section. With extra JS this might be possible but it's out of the intended scope of the tutorial....
Cheers!
Hi, I've been using the horizontal scroll for some time and it worked great until the last version of Elementor.
Since version 3.8.0 it doesn't work at all, is there an update coming soon to fix this?
Hey Mounir!
Indeed there has been class names changes with 3.8 that breaks the code slightly. Please replace "e-container" with "e-con" in these two lines of code:
To work with Elementor 3.8 and above, they should be:
You can simply copy paste the code from the tutorial, it's updated to work with 3.8. Writing here the changes needed for reference.
Also note that the "horizontalScroll_parent", "horizontalScroll_innerWrapper" and "horizontalScroll_translateContainer" containers needs to be set to "full width" layout, and not boxed.
Hi Maxime,
Thanks a lot for your answer. I'm going to put it in place right away.
Thank you for sharing, really helpful!
Thanks! Work perfect!
Thank you Steffen! I'll try that out.
Have you been able to make it work on mobile? I've tried but it was way too jumpy and jittery so I decided to disable in on mobile for now.
Hey Steffen,
Yes indeed performance on mobile can be a challenge with this design. It will depend a lot on what's on your page, what's part of the content, and also simply the specs of the smartphone being used to view the page.
Older smartphones in particular won't have a good UX. This is one of the con of this horizontal scrolling design. Use the straight JS version for optimal mobile performance (then you don't have easing though).
That's one of the reason I explain how to disable this on mobile. Generally speaking, while it works there, it might not be ideal. Mostly if you have a heavy page already.
Cheers!
EDIT: I actually greatly improved performance for mobile, and it should be 100% usable there in most cases.
Hi Maxime,
How can I make the next non-sticky, non-horizontal scrolling row show up faster?
The way it is now, there is a big white space before the next section/container shows up (which isn't a horizontal scrolling section).
I hope that makes sense, happy to provide further details!!
Love the template, it's perfect for what I need it for. 🙂
To readers: Daniel sent me his URL and I could have a look. The issue in this particular case was that he had changed, in the CSS provided, the "100vh" to "75vh", leaving 25vh of empty space at the bottom.
Going back to 100vh fixed the issue.
Hi Maxime, All working ok, but my website has a sticky nav, which disappears on the page where the horizontal code / feature is installed. I go live this thurs and really need the nav to show. Is there a fix you can help with?
Thanks, Andrew
Hey,
Could you please share you URL with me? I will have a look.
Yes no problem will email it now
Hey Roni!
It should work for several on the same page, the structure needs to be carefully followed tho.
Hey there!
How to eliminate the whitespace between last black container and first "section after" container?
Greetings
Stefan
Hey Stefan!
Could you share your URL with me? I will have a look.
Hey Maxime!
Normaly you can saw it at your own DEMO here, at the beginning of this page...
May a Screenshot give the right insight: https://pixelharmonie.de/Screenshot-2023-07-26-203001.png
(*i located other problems with elementor dev edition right now... otherwise i would show you the testpage...)
Thank in advance!
Stefan
Hey Stefan!
That's simply some bottom margin on the wrapper container. Remove through the Elementor UI.
WTF. Sometimes you stand too close. Sorry and thank you at the same time!
No worries at all Stefan! Happens to everyone of course...
Hello,
very nice template!
Unfortunately I am not a programmer. Is it possible to have something like a "snap"? This means the following:
1. when I scroll through the horizontal slider, that when it is fully visible, it "snaps" for about 1 second before the scroll continues.
2. if I have the next slide 90% in view when scrolling and stop scrolling, it will automatically finish scrolling until it is 100% in view.
Is this possible?
Greetings
Oliver
Hey Oliver!
An earlier version of this tutorial provided a 'snap' version. I removed it, for several reasons:
It looks and sounds like a good idea at first, but in practice, it gets really annoying, really quickly for users. It becomes a kind of 'scroll jacking', degrading UX.
It was dependant on GSAP, making it heavier. Now the current code is vanilla JS, with no dependencies, so it's as lightweight as possible.
The GSAP code was also less performant, CPU wise. The current code is as performant as can be, so can be used on mobile fine, in most cases.
I won't add the snapping version back. People almost always ended up reverting to the normal, non-snapping version anyway, when the UX flaws became obvious.
Hope you understand!
Cheers
Hi
i was wondering how can i make anchor link work on the horintal tetorial
ive purchase it which is great
but can make menu scroll to # tag
any clues how it can be done
thanks in adnvanced
Greetings eytan,
Add this code. It will add support for anchor links, while on the same page.
Your IDs will need to be given to a direct children of the horizontalScrollTranslate container.
So, give your IDs to the containers that are direct descendent of it.
Copy paste it directly below this line:
/* END OF preload the images after the first image gets in the viewport */
Cheers!
Hi thanks
it doesnt work for some reason
im using your template to check if it works
ive added id the each direct descendent container doesnt work
any clues why
thanks
I updated the code in my comment, please try again.
thanks it did the job
if you can please take a look of what idid
im doing a one page which combines container and aslo loop grid
basicly ive i have 2 html in the same page to make it work
is it ok to do it like that?
another question my scroll doesnt reach to the posint of the anchor
thanks again
Hey Eytan!
Sorry my code works for the default setup of each container having 100vw per 100vh.
I'd need more work to get it functioning in every scenario... like what you have here.
Hey Eytan!
I improved the code to get it working in all scenarios, and added the instructions in the tutorial.
Cheers!
Hi Eytan!
I added the code for desktop only, as you say in the instructions, this is one of them https://cloud.cacomartin.com/m3Pvmfds
But this is my result https://cloud.cacomartin.com/WDw8NqQy
What did I do wrong?
Thanks!
Hey Caco!
Could you please share your live URL with me? I will have a look!
Cheers!
Maxime
Hi, for sure!
https://carlosavila.expert/asesoria-de-imagen-personal-en-madrid/
Please let me know if you need access to admin panel.
Thanks in advance!
Hey Caco!
While in tablet and mobile mode, go in your horizontalScrollTranslate containers, and set the Flex Direction to "column".
Let me know if that works!
Cheers!
Wooow! it works!! thank you for your hard and creative work! I love the workflow to design with this template.
Cheers! What you have done looks really great!
Hi,
Had been looking for something exactly alike this.
Haven't had to chance to play around with it as of yet but was wondering if it would be possible to make something along the lines of this with it: https://www.pieaerts.com/personal-work/umoja/
on mobile and laptop up until around 1920x1080 it will show the flex container in grid form, so the photos will be shown in grid form which in my opinion gives a very sleek look as you minimize your monitor, if you have a large monitor it jumps smoothly from scroll to grid as you downsize browser tab, I presume this is also possible with this adaption of this particular scroll container? Any ideas on how I could set this up? So the goal is on smaller monitors + mobile + tablet for it to not show as scroll container but as grid.
Hey Alex!
I have instructions to enable the horizontal scroll on desktop only in the tutorial.
https://element.how/elementor-horizontal-scroll-containers/#table-of-content-7
If you want it to be above 1920 instead of 1024, just change the value here:
to
This won't get you exactly what you have on the example site though, as that one is made differently... but it should get you started.
Cheers!
Hi
i was wondering does the anchor link
support link from external url
right now when i go to # from external url i get only the 1 section of the selected id
is theres a way to solve it
thanks
Greetings Eytan!
Try this code for the anchor links, let me know if it works!
Cheers!
Hi thanks for replaying
look i have allready anchorlink support from the same page
do i have to add it to the code
or do i need to replace it
when i add it it doesnt work
thanks
Yes, please try replacing it with what I sent in the comment...
hi thanks
it did the work partily
here is an actual link of the live website i did
when you will enter you will see the about but you wont see oter section in the layout
when you reresh again you will see all of the website like it should
any clues what is wrong
thanks
Greetings,
I see what the problem is... the default browser behaviour on page load is creating problems.
Instead, let's try this:
Replace the /* anchor links support */ code with this:
Then (important):
Go in each of your containers where you have IDs, and rewrite them like this instead: hr-anchortexthere
So if you had "about", it becomes "hr-about", etc.
Only do this on the containers CSS ID field!
Don't change the links, they should still be #about (and not #hr-about)
Let me know if that works and thanks for your patience.
Cheers!
PERFECTTTT!
thanks for great support
Hi C - any chance you can elaborate on how you made this work? I can't see "horizontalScroll_innerWrapper" in the template? Thanks!
question when going mobiel ive disabled the horizontal scroll
make all containers in 100%row
in vertcial format
does the anchors suppoese to work?
thanks
Greetings Eytan,
No indeed you are right, the anchors won't work on mobile...
To fix this, add
directly below the line:
Let me know if that works!
thanks
sorry it doesnt work
heres the website
the probelm is with mobile only
inside the home page and when i go back from a project
thanks i advanced
Hey Eytan!
Try this instead , replace everything in between the <script> tags with this:
Cheers!
Hi, installed the script/code etc which is superb on desktop however we are experiencing a very glitchy effect on tablet and mobile. I'm hoping it's something simple, are you able to help please?
Hey Westbrook!
Hmmm, this is probably just the browser having difficulty. This design is a bit taxing for mobile browsers in particular (that includes iPad), that's one reason why I have instructions on how to disable it for mobile devices only, in case it's just not smooth enough.
Otherwise the only thing we can do is try to make the DOM as shallow as possible: all containers on the page that can be (where it won't change the layout), should be set to "full width" layout instead of "boxed". Usually that means all inner containers. That will save 1 DIV depth per container... Sometimes it makes enough of a difference to make it better, depending on where we started from!
Having said that I'd be glad to have a look at your page to check if I can find anything else that could be improved...
Hope this helps!
Cheers!
Thanks Maxime, we'll give that a try and if all else fails try an alternative layout for mobile devices. If I get stuck I'll come back to you. Cheers.
Hey Westbrook!
I think I found a fix for this. Please add this CSS:
This should make it work really well on mobile. If you try it, let me know how it works for you!
Cheers!
Hey Maxime, that worked really well thanks, the glitchy experience has stopped. Much appreciate you sticking with this. I'll come back with any further issues if we encounter any. Cheers.
Awesome, glad to read it!
Cheers!
Hi Maxime,
Thanks for the previous response and help. I've gotten pretty far to where i wanted the page to be, but ran into some problems. For some reason the page is not acting fully responsive and doesn't preload the cache of the lower viewports, this results in no transition between the scrolled viewport and the ones below 1024 unless the site is reloaded. I've tried turning off all my caching plugins and server based caching but it didn't change much.
test page in question: https://www.alexwhelan.art/rr-test
2 short 5 second clips that show the problem:
https://gyazo.com/119e5805cea5f1a4e56dc5d99713b1e0
https://gyazo.com/351e90f11ace530a27399d23cc85cf59
2 short 5 second clips that show it working correctly after reloading the website while on a smaller viewport:
https://gyazo.com/071245aedbf1422187169d9ebd0806b3
https://gyazo.com/fe2d0068f6adfefd703d3e8510ac4d23
So question is would there be a way to forcefully pre load those viewports so it transitions smoothly and works responsive instead of having to F5? When the site is opened in smaller viewport it transitions fine to anything >1024.
So problem only persists when moving from from full screen browser to <1024.
Was looking at other peoples sites that were linked in the comments and nobody seems to have an alike problem so figured i'd add some more info:
Caching: Flyingpress + Cloudflare
Hosting:Siteground
Theme:Oceanwp
Appreciate the insights,
Alex
Greetings Alex!
Actually this is partly by design. I can't think of any real world use case where the user would first open a page with <1024 viewport, and then expand it... and vice versa. Only use web designers do this when we are inspecting a website for errors / etc.
So sometimes when the JS gets complex, instead of trying to update everything across mobile to desktop viewports, I don't, to have leaner, more simple code.
If you have a use case where you would need this though, I could offer a few solutions... first I'd like to know if you have any data that shows real world user are running across this scenario on your site?
Let me know!
Cheers!
Hi Maxime!
Thanks for the rapid response, yeah was showing several people some new pages to kind of gage their responses between several potential designs for the new portfolio sections. Most of them noticed this particular issue.
I also personally tend to do this rather often just scrolling through the web having multiple windows open on bigger monitors resulting in multiple lower viewport windows.
I was looking through older comments to look for potential solutions to save you the effort but couldn't really find much.
I found someone that linked this website though: https://blancheandco.co.uk/
Where the slider does act responsively. And switches smoothly as you decrease the size of your browser window into the new viewport.
Would you know what the particular difference in implementation is between this website and mine? I couldn't really figure it out.
Regards,
Alex
Hey Alex!
I understand... Thank you for the information. So the issue would be with people who open windows NOT in full screen. Fair enough!
I had a good look at your page and I can see the problem clearly:
The code is meant for desktop only ( it was wrapped with if (window.innerWidth > 1024){ as instructed in the tutorial)
So when the window opens at 1000px, and goes to >1024px, then the JS isn't in place.
Conversely, if the window opens at 1100px, and goes down to <1025px, then the JS IS in place, but should not be.
Solution? A page refresh when that breakpoint crosses over.
Add this in the code, just before the closing </script> tag :
Cheers!
Perfect, thanks for the rapid response. Was hesitant to purchase a tutorial that didn't include a plugin and focused on code particular but the extra support has been all worth it. Kudos Maxime
Thanks again
Cheers!
Is there a way to have have the scrolling stop once the final image in a gallery is shown. Currently, it continues scrolling to the left until about half of the page is just blank whitespace.
I have a gallery of 3 images, and want the scrolling to pretty much stop once all 3 are visible, even if the first image is getting cut off a little on the left thats fine...
Is it possible? i tried playing with the "width: fit-content;" setting with no luck. Thanks in advance!
Greetings!
Yes this is possible. Go on the Image Gallery element > Advanced > Padding, and adjust what you will find there to what you need.
In the template I have 44vw left and right padding, to get the result that you see in the demo. It's optional however and you can have as little or as much padding as you wish!
Cheers!
Thank you so much for the prompt reply!!! That didn't seem to give me the desired effect - it added white space to both the left and right.
And example of what I am going for is towards the middle of this page: https://www.canyonranch.com/
When i adjust the padding in advanced of the gallery, the gallery images just continue to scroll into the white space.. my example is at https://mountainsofhope.com/ towards the middle of the page.
For this, just lower the padding down a lot, maybe 60px each side.
Or (depending on what you want) on the left side, keep ~30vw , and on the right, 100px.
Keep in mind though that if all three of your cards fit in the viewport already, then there just won't be much of any horizontal scrolling... the code snippet is really made for when there are offscreen elements
Cheers!
Hi! I added the code for supporting anchor links but, I don't know why doesn't work.
Can you find what I made wrong? https://carlosavila.expert/
Thanks!
Greetings Caco!
The issue seems to be an error earlier in the code. I see that you have these two lines:
let images = document.querySelectorAll('.horizontalScrollContainer img');
let firstImage = images[0];
It should be this instead:
let images = document.querySelectorAll('.horizontalScrollContainer img');
if (!images.length) return;
let firstImage = images[0];
Let me know if making this changes fixes it.
Cheers!
Oh Gosh!!
Only that line... I'll would never notice. Now works beautiful seamlessly. Thanks a lot!
Awesome, glad it's resolved!
Cheers!
Hey Maxime, just loaded this in and it doesn't seem to work... Not sure what i'm doing wrong...
https://azprwlectc.wpdns.site/the-gvc-story/
Thanks,
Sorted it... Thanks
Back again, the active state for the navigation doesn't work when using anchor links, any work around?
Thanks,
Hey Will!
Sorry this is just too complex with the current setup unfortunately.
Okay no worries!
Hi Maxime,
Can you see what's going wrong here? I've added the template and customized the gallery widget, but it keeps scrolling down. Would love that the images also start on the left side.
https://jermaine.be/boutique/
Kind Regards,
Jaap
Greetings!
It's not sticky because you have this CSS on the page:
body, html {
overflow-x: hidden;
}
See the Debugging Position: sticky tutorial to learn more about this: https://element.how/css-debugging-position-sticky-not-working/
Quick fix: add this CSS:
html body {
overflow: visible;
}
To have the images start elsewhere, just adjust the padding on the gallery element, in the editor UI.
Cheers!
Hi,
Thanks for the reply, it's working, amazing service of you again!
Do you also have a trick to make the images full screen, like this effect?
When you scroll down to the end of the page, you see this slider in like full screen effect.
https://balo.be/nl
Greetings!
In the custom CSS, you will see this:
.horizontalScrollContainer .elementor-image-gallery .gallery-item img {
max-width: initial;
width: auto;
height: 48vh;
}
Just change to
.horizontalScrollContainer .elementor-image-gallery .gallery-item img {
max-width: initial;
width: auto;
height: 100vh;
}
Cheers!