Elementor Full Screen Horizontal Scroll Containers

Elementor Full Screen Horizontal Scroll Containers

Level up your game with the CSS Course for Elementor Users

Table of Contents

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:

Please purchase access and be logged in to access this template.

 

Horizontal Scrolling Gallery, Loop Grid, and Posts elements (scroll down all the way!) :

Please purchase access and be logged in to access this template.

 

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.

Access tutorial

$59/one time Purchase access

Includes

  • Gain Access to This TutorialUnlock complete access to the current tutorial: Elementor Full Screen Horizontal Scroll Containers
  • Future UpdatesYou will get access to all future updates to this tutorial.
  • Enjoy Unlimited UsageUse on as many of your own sites or your clients sites as you wish.

    Note that reselling or redistributing is not permitted.

Access everything

$299/one time Purchase All Access

Includes

  • Unlock every premium tutorial on Element.howGet access to the entire library of premium tutorials on Element.how
    Preview premium tutorials
  • Get access to the CSS course for Elementor usersAccess the complete 14 HTML chapters, 30 CSS chapters and 7 Elementor Projects.Learn more
  • Simple CSS Grid For ElementorAn Elementor Addon to Create Awesome Grid Layouts in a Single Click for Containers, Galleries and Loop Grid. Learn more
  • free extra: ShapeDividers.com Premium AccessLifetime Premium Access to ShapeDividers.comVisit ShapeDividers.com
  • 30 day money backNo questions asked money back. Not what you expected? Get a refund.
  • One-time payment of only $299No hidden fees or subscriptions.

    Sales taxes added where applicable.
  • Great supportGet help when you need it. Support includes getting things working as intended.

    Support excludes customization work.
  • Lifetime access to everything Element.howThe price reflects what is currently available on Element.how. All future updates are included, but none are promised. You pay for what is available now, and the rest is a sweet extra.

    I will say that it is definitely my intention to keep adding tutorials to Element.how.
* All prices are USD. Applicable taxes will be charged at checkout. Have a question? See the FAQ or email me.

Element.how also provides premium tutorials showing awesome advanced designs, check them out here.

Looking for something else? Search across 2701 Elements right here:

Checkout the Elementor Addon Finder directly

78 Responses

    1. 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:

      selector {
      width: 70vw;
      max-width:70vw !important;
      min-width:70vw !important;
      }
      

      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!

  1. 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.

    1. 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".

  2. Hey Sandra!

    Try importing my template in a new page, and then swapping all the code in the HTML element with the GSAP code.

    Let me know if that works properly.

    1. 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.

    1. 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.

    1. 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!

      1. That sorted it! Thank you 🙂 Was my caching plugin as well I suspect - minifying CSS maybe, taken that off

    1. 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!

  3. 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?

    1. 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:

      let scrollSectionsAmount = parentOfStickySection.querySelectorAll('.horizontalScroll_translateContainer > .e-container').length;
      
      .horizontalScroll_innerWrapper>.horizontalScroll_translateContainer>.e-container {
      

      To work with Elementor 3.8 and above, they should be:

      let scrollSectionsAmount = parentOfStickySection.querySelectorAll('.horizontalScroll_translateContainer > .e-con').length;
      
      .horizontalScroll_innerWrapper>.horizontalScroll_translateContainer>.e-con {
      

      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.

      1. Hi Maxime,

        Thanks a lot for your answer. I'm going to put it in place right away.

  4. Hey Shahar! Hope you are well!

    Indeed I see the issue... it looks like it's from some brand new CSS Elementor added in 3.9.0 ! They added a transition on the containers, for the "transform" property, and it results in this little glitch. I updated the code in the tutorial to avoid this issue.

    Cheers!

    PS. Other readers seeing this: it's valid for the GSAP version only. Update your code if you have updated to 3.9.0 please.

  5. Hi Jay Vu,

    GSAP-version
    I noticed that there are more recent versions of the two JS files available here which seem to make the scrolling "less jittery".

    https://cdnjs.com/libraries/gsap

    However, when scrolling horizontally to the last container, it still (!) doesn't stop at the very end of the last container first before scrolling down.

    Cheers!

  6. Hi Jay Vu,

    Try to enable snapping (see Maxime's comment above), that seems to make the last container's behavior better.

    Cheers!

    1. 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.

  7. Greetings Steffen!

    It's unlikely that the Premium Addons version will be more performant on mobile. It's using GSAP as well, so the results should be similar.

    The most performant version should in fact be the raw JS version I provide in this article. However, it does not have 'easing', so if you want that, you need the GSAP version.

    Cheers!

  8. 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!

  9. Hey Jay Vu!

    1. Please see my answer below to Steffen
    2. Yea that's how GSAP works in this case... This is because of the easing. Try the straight JS version, this should be better, but there will be no easing.

    Hope this helps!

    Cheers!

  10. 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. 🙂

    1. 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.

  11. 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

  12. Hey Kniyashava!

    Change this line:

    x: () => -(translateXSection.scrollWidth - window.innerWidth),

    to

    x: () => (translateXSection.scrollWidth - window.innerWidth),

    I haven't tested but I think that should be it... let me know if that works!

  13. Hey there!

    How to eliminate the whitespace between last black container and first "section after" container?

    Greetings

    Stefan

      1. Hey Stefan!

        That's simply some bottom margin on the wrapper container. Remove through the Elementor UI.

      2. WTF. Sometimes you stand too close. Sorry and thank you at the same time!

  14. 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

    1. 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

  15. 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

    1. 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.

      const anchorLinks = document.querySelectorAll('a[href*="#"]');
      
      anchorLinks.forEach((link) => {
        link.addEventListener('click', function (event) {
          const href = this.getAttribute('href');
          const anchorIndex = href.lastIndexOf('#');
          const targetID = anchorIndex !== -1 ? href.substring(anchorIndex + 1) : '';
      
          const targetElement = document.getElementById(targetID);
      
          if (targetElement) {
            const translateContainer = targetElement.closest('.horizontalScrollTranslate');
      
            if (translateContainer) {
              event.preventDefault();
      
              let scrollParent = translateContainer.closest('.horizontalScrollWrapper');
      
              let scrollHeight = scrollParent.offsetHeight;
      
              let targetIndex = Array.prototype.indexOf.call(translateContainer.children, targetElement);
      
              let scrollDistance = (scrollHeight - translateContainer.parentElement.offsetHeight - 100) * ( targetIndex / (translateContainer.children.length - 1) );
      
              scrollDistance += scrollParent.getBoundingClientRect().top + window.scrollY;
      
              setTimeout(function () {
                jQuery('html,body').animate({ scrollTop: scrollDistance }, 1300);
              }, 100);
            }
          }
        });
      });
      

      Copy paste it directly below this line:

      /* END OF preload the images after the first image gets in the viewport */

      Cheers!

  16. 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

  17. 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

    1. 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.

    2. Hey Eytan!

      I improved the code to get it working in all scenarios, and added the instructions in the tutorial.

      Cheers!

      1. 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!

  18. 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.

    1. 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:

      if (window.innerWidth > 1024){

      to

      if (window.innerWidth > 1919){

      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!

  19. 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

    1. Greetings Eytan!

      Try this code for the anchor links, let me know if it works!

      /* anchor links support */
      const anchorLinks = document.querySelectorAll('a[href*="#"]');
      
      function scrollToTarget(targetID) {
          const targetElement = document.getElementById(targetID);
      
          if (!targetElement) return;
      
          const translateContainer = targetElement.closest('.horizontalScrollTranslate');
      
          if (!translateContainer) return;
      
          let scrollParent = translateContainer.closest('.horizontalScrollWrapper');
          let scrollHeight = scrollParent.offsetHeight;
          let scrollDistance = targetElement.offsetLeft / (translateContainer.offsetWidth - window.innerWidth) * (scrollHeight - translateContainer.parentElement.offsetHeight - 100);
          scrollDistance += scrollParent.getBoundingClientRect().top + window.scrollY;
      
          setTimeout(function () {
              jQuery('html, body').animate({ scrollTop: scrollDistance }, 1300);
          }, 100);
      
      }
      
      anchorLinks.forEach((link) => {
          link.addEventListener('click', function (event) {
              event.preventDefault();
              const href = this.getAttribute('href');
              const match = href.match(/#([^?]+)/);
              const targetID = match ? match[1] : '';
      
              scrollToTarget(targetID);
          });
      });
      
      /* From another page with a anchorID in the URL */
      window.addEventListener('load', () => {
          const anchorID = window.location.href.match(/#([^?]+)/);
          if (anchorID) {
              scrollToTarget(anchorID[1]);
          }
      });
      /* END OF anchor links support */
      

      Cheers!

      1. 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

      2. Yes, please try replacing it with what I sent in the comment...

  20. 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

    1. 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:

      /* anchor links support */
      const anchorLinks = document.querySelectorAll('a[href*="#"]');
      
      function scrollToTarget(targetID) {
          const targetElement = document.getElementById(targetID);
      
          if (!targetElement) return;
      
          const translateContainer = targetElement.closest('.horizontalScrollTranslate');
      
          if (!translateContainer) return;
      
          let scrollParent = translateContainer.closest('.horizontalScrollWrapper');
          let scrollHeight = scrollParent.offsetHeight;
          let scrollDistance = targetElement.offsetLeft / (translateContainer.offsetWidth - window.innerWidth) * (scrollHeight - translateContainer.parentElement.offsetHeight - 100);
          scrollDistance += scrollParent.getBoundingClientRect().top + window.scrollY;
      
          setTimeout(function () {
              jQuery('html, body').animate({ scrollTop: scrollDistance }, 1300);
          }, 100);
      
      }
      
      anchorLinks.forEach((link) => {
          link.addEventListener('click', function (event) {
              event.preventDefault();
              const href = this.getAttribute('href');
              const match = href.match(/#([^?]+)/);
              const targetID = match ? 'hr-' + match[1] : '';
              scrollToTarget(targetID);
          });
      });
      
      /* From another page with a anchorID in the URL */
      window.addEventListener('load', () => {
          let anchorID = window.location.href.match(/#([^?]+)/);
          if (anchorID) {
              anchorID = 'hr-' + anchorID[1];
              scrollToTarget(anchorID);
          }
      });
      /* END OF anchor links support */
      

      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!

  21. Hi C - any chance you can elaborate on how you made this work? I can't see "horizontalScroll_innerWrapper" in the template? Thanks!

  22. 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

    1. Greetings Eytan,

      No indeed you are right, the anchors won't work on mobile...

      To fix this, add

      if (window.innerWidth < 768) {
              /* scroll normally on mobile */
              targetElement.scrollIntoView({ behavior: 'smooth' });
              return;
          }
      

      directly below the line:

      if (!targetElement) return;

      Let me know if that works!

  23. 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

    1. Hey Eytan!

      Try this instead , replace everything in between the <script> tags with this:

      /* Code from https://element.how/elementor-horizontal-scroll-containers/
      * Copyright 2023 Element.How
      * Licensed for personal and commercial use for customers who purchased access
      * No redistribution or resale allowed
      */
      
      document.addEventListener('DOMContentLoaded', function () {
      
          if (window.innerWidth > 1024) {
      
      
              let horizontalScrollContainers = document.querySelectorAll('.horizontalScrollContainer');
              horizontalScrollContainers.forEach((horizontalScrollContainer) => {
      
                  let speedMultipliers = {
                      desktop: 1.4,
                      tablet: 1.2,
                      mobile: 1,
                  } /* greater value = faster, 1 = default */
      
                  let horizontalScrollTranslate = horizontalScrollContainer.querySelector('.horizontalScrollTranslate');
                  let horizontalScrollParent = horizontalScrollContainer.parentElement;
                  let scrolledRatio = 0;
                  let horizontalScrollContainerTop, horizontalScrollHeight, horizontalScrollTranslateWidth, widthToScroll, windowWidth, mult;
      
                  function updateValues() {
                      windowWidth = window.innerWidth;
                      windowWidth > 1024 ? mult = speedMultipliers.desktop : windowWidth > 767 ? mult = speedMultipliers.tablet : mult = speedMultipliers.mobile;
                      horizontalScrollTranslateWidth = horizontalScrollTranslate.offsetWidth;
                      horizontalScrollParent.style.height = window.innerHeight + horizontalScrollTranslateWidth / mult + 'px';
                      horizontalScrollHeight = horizontalScrollParent.offsetHeight;
                      widthToScroll = horizontalScrollTranslateWidth - windowWidth;
                      horizontalScrollContainerTop = (window.innerHeight - horizontalScrollContainer.offsetHeight) / 2;
                      horizontalScrollContainer.style.top = `${horizontalScrollContainerTop}px`;
                  }
                  updateValues();
      
                  /* update values on resize event */
                  window.addEventListener('resize', () => {
                      if (windowWidth !== window.innerWidth) updateValues();
                  });
      
                  let isUpdateScheduled = false;
      
                  function manageScroll() {
                      let horizontalScrollTop = horizontalScrollParent.getBoundingClientRect().top;
                      let windowHeight = window.innerHeight;
                      scrolledRatio = (horizontalScrollTop - horizontalScrollContainerTop) / (horizontalScrollHeight - horizontalScrollContainer.offsetHeight - 100) * -1; /* removing 100px to make it sticky a bit longer after it reaches the end, for better UX */
                      /* clamp scrolledRatio in between 0 and 1 */
                      scrolledRatio = Math.min(Math.max(scrolledRatio, 0), 1);
                      horizontalScrollTranslate.style.transform = `translateX(${scrolledRatio * widthToScroll * -1}px)`;
                      isUpdateScheduled = false;
                  };
      
                  /* Listen to the scroll event on the window object and schedule the update function using throttling */
                  window.addEventListener('scroll', () => {
                      if (!isUpdateScheduled) {
                          isUpdateScheduled = true;
                          requestAnimationFrame(manageScroll);
                      }
                  });
      
              });
      
          }
      
      
          /* preload the images after the first image gets in the viewport */
          (function () {
              let images = document.querySelectorAll('.horizontalScrollContainer img');
              let firstImage = images[0];
      
              let options = {
                  root: null,
                  rootMargin: '0px',
                  threshold: 0.3
              };
      
              let observer = new IntersectionObserver((entries, observer) => {
                  entries.forEach(entry => {
                      if (entry.isIntersecting) {
                          images.forEach(img => {
                              addPreloadLink(img);
                          });
                          observer.unobserve(firstImage);
                      }
                  });
              }, options);
      
              observer.observe(firstImage);
          })();
      
      
          function addPreloadLink(img) {
              let link = document.createElement('link');
              link.rel = 'preload';
              link.href = img.src || img.dataset.src;
              link.as = 'image';
              if (img.srcset) link.setAttribute('imagesrcset', img.srcset);
              if (img.sizes) link.setAttribute('imagesizes', img.sizes);
              document.head.appendChild(link);
          }
          /* END OF preload the images after the first image gets in the viewport */
      
          /* anchor links support */
          const anchorLinks = document.querySelectorAll('a[href*="#"]');
      
          function scrollToTarget(targetID) {
              const targetElement = document.getElementById(targetID);
      
              if (!targetElement) return;
      
              if (window.innerWidth < 1025) {
                  /* scroll normally on mobile */
                  targetElement.scrollIntoView({ behavior: 'smooth' });
                  return;
              }
      
              const translateContainer = targetElement.closest('.horizontalScrollTranslate');
      
              if (!translateContainer) return;
      
              let scrollParent = translateContainer.closest('.horizontalScrollWrapper');
              let scrollHeight = scrollParent.offsetHeight;
              let scrollDistance = targetElement.offsetLeft / (translateContainer.offsetWidth - window.innerWidth) * (scrollHeight - translateContainer.parentElement.offsetHeight - 100);
              scrollDistance += scrollParent.getBoundingClientRect().top + window.scrollY;
      
              setTimeout(function () {
                  jQuery('html, body').animate({ scrollTop: scrollDistance }, 1300);
              }, 100);
      
          }
      
          anchorLinks.forEach((link) => {
              link.addEventListener('click', function (event) {
                  event.preventDefault();
                  const href = this.getAttribute('href');
                  const match = href.match(/#([^?]+)/);
                  const targetID = match ? 'hr-' + match[1] : '';
                  scrollToTarget(targetID);
              });
          });
      
          /* From another page with a anchorID in the URL */
          window.addEventListener('load', () => {
              let anchorID = window.location.href.match(/#([^?]+)/);
              if (anchorID) {
                  anchorID = 'hr-' + anchorID[1];
                  scrollToTarget(anchorID);
              }
          });
          /* END OF anchor links support */
      
      
      
      });
      

      Cheers!

  24. 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?

    1. 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!

      1. 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.

    2. Hey Westbrook!

      I think I found a fix for this. Please add this CSS:

      @media (max-width: 1024px) {
      .horizontalScrollTranslate.e-con.e-con {
          transition: transform 0s;
      }
      }
      

      This should make it work really well on mobile. If you try it, let me know how it works for you!

      Cheers!

  25. 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.

Leave a Reply