Search code examples
javascripthtmlcsscarouseltransform

Transitions not working while changing the transform property of an element using JavaScript


I've been trying to create a simple carousel with multiple items.

The idea is to use the transform property to move the carousel slide left or right, depending on which button the user clicks. I use the append and prepend methods to achieve the "infinite slide" effect.

My main issue is that the transition property doesn't trigger and the carousel just keeps snapping to the next item. Also, the console logs an error which says something along the lines of "there has been an error while loading transform value" (I'm not pasting the entire error because my browser doesnt use english as it's default language). I'm not sure what this error means since the carousel moves despite the error.

These are the functions used to use the carousel:

const slideWidth = document.querySelector('.carouselItem').clientWidth;
let distance = 0;


function moveToPrevious() {
  distance += slideWidth;
  carouselSlide.prepend(carouselSlide.lastElementChild);
  carouselSlide.style.transform = 'translateX(' + distance + 'px)';
}

function moveToPrevious() {
  distance += slideWidth;
  carouselSlide.prepend(carouselSlide.lastElementChild);
  carouselSlide.style.transform = 'translateX(' + distance + 'px)';
}

The whole codepen: https://codepen.io/antonlovric/pen/OJxOyyL


Solution

  • I think it's better to use a css variable instead of changing the whole property value, I think it's more clear:

    .carouselSlide {
      display: flex;
      height: 100%;
      --translate-x: 0px;
      transition: 0.5s all ease-in;
      transform: translateX(var(--translate-x));
    }
    
    function moveToPrevious() {
      distance += slideWidth;
      document
        .querySelector('.carouselSlide')
        .prepend(carouselSlide.lastElementChild);
      carouselSlide.style.setProperty('--translate-x', distance + 'px');
    }
    

    see that I'm setting the value of --translate-x instead of changing style.transform.

    With your code, the transform property is not even changing if you inspect the element.

    Though you have another problem to fix first, after fixing the transition of the translateX, you have an issue with WHEN you remove elements. As soon as you remove the first element to put it at the end of the carrousel, the content will shift to the left because you removed an element, and that will have no transition.

    Your algorithm should be more complex. Let's say you want to move to the next element, so:

    • first you do the translateX
    • then, when the transition ends, you do 2 things:
      • reset the translateX
      • move the first element to the end

    You can listend to the transitionEnd event to do that.

    One thing I'd suggest to simplify the logic is to always have one extra element at the left and one extra element at the right, that way you can always start the algorithm with changing the translateX value and then adjusting the elements (if you show the first 3 elements, you'll have to make a more complex algorithm to go back to the previous slide)