Search code examples
jquerycssslick.js

slick slider - css transition infinite loop bug


I've got a slider set up using slick slider. When using the next and previous buttons, the item comes in to view with a nice transition. The problem I'm having is that when it restarts its cycle, the first item "snaps" into view, instead of doing the transition. Furthermore it seems like it loses it's internal indexing, as the css "odd" and "even" classes are changed. See snippet below:

$(document).ready(function() {
    $('.items').slick({
        slidesToShow: 2,
        speed: 500
    });
});
* {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
  height: 150px;
}

.slick-list, .slick-track {
  height: 100%;
}

ul li {
  width: 350px;
  height: 100%;
}

ul li .content {
  width: 100%;
  height: 100%;
  transition: transform 0.5s linear;
  text-align: center;
}

ul li .content span {
  color: #fff;
  font-size: 50px;
  font-family: Arial;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  display: block;
}

ul li:nth-child(odd) .content {
  background-color: red;
}

ul li:nth-child(even) .content {
  background-color: green;
}

ul li:not(.slick-current) .content {
  transform: scale(0.9);
}
<link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<ul class="items">
  <li class="item">
    <div class="content">
      <span>1</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>2</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>3</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>4</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>5</span>
    </div>
  </li>
</ul>

I think I know why it's doing this, it's because it has to create "cloned" items for the infinite loop functionality to work. I've tried a few different slider plugins and they all seem to have similar issues.

Does anyone know how I can fix this? jsfiddle here: https://jsfiddle.net/7kdmwkd9/1/


Solution

  • Solution 1 - Use Flickity

    If you want to try another carousel control, you can have a look at Flickity. According to my tests with the wrapAround option, it does not "snap" the first item back into position when the full cycle is complete; the transition goes on smoothly. You can see it at work in this jsfiddle.

    As for the problem with formatting the items according to their even/odd index, it happens only when you have an odd number of items. One solution would be to duplicate the list of items. Intead of

    Item 1 / Item 2 / Item 3 / Item 4 / Item 5
    

    you could define

    Item 1 / Item 2 / Item 3 / Item 4 / Item 5 / Item 1 / Item 2 / Item 3 / Item 4 / Item 5
    

    That would ensure that you work with an even number of items.


    Solution 2 - Slick Slider: add transition delay

    With Slick Slider, adding a delay to the transition helps to make it smoother when the cycle completes. In the code snippet below, I replaced:

    ul li .content {
      transition: transform 0.5s linear;
      ...
    }
    
    ul li:not(.slick-current) .content {
      transform: scale(0.9);
    }
    

    with

    ul li .content {
      transition: transform 0.3s linear;
      transition-delay: 0.5s;
      ...
    }
    
    ul li:not(.slick-current) .content {
      transform: scale(0.9);
      transition-delay: 0s;
    }
    

    $(document).ready(function() {
      $('.items').slick({
        infinite: true,
        speed: 500,
        slidesToShow: 2,
        variableWidth: false
      });
    });
    * {
      margin: 0;
      padding: 0;
    }
    
    ul {
      list-style: none;
      height: 150px;
    }
    
    .slick-list,
    .slick-track {
      height: 100%;
    }
    
    ul li {
      width: 350px;
      height: 100%;
    }
    
    ul li .content {
      width: 100%;
      height: 100%;
      transition: transform 0.3s linear;
      transition-delay: 0.5s;
      text-align: center;
    }
    
    ul li .content span {
      color: #fff;
      font-size: 50px;
      font-family: Arial;
      position: relative;
      top: 50%;
      transform: translateY(-50%);
      display: block;
    }
    
    ul li:nth-child(odd) .content {
      background-color: red;
    }
    
    ul li:nth-child(even) .content {
      background-color: green;
    }
    
    ul li:not(.slick-current) .content {
      transform: scale(0.9);
      transition-delay: 0s;
    }
    <link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
    <ul class="items">
      <li class="item">
        <div class="content">
          <span>1</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>2</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>3</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>4</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>5</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>1</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>2</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>3</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>4</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>5</span>
        </div>
      </li>
    </ul>