kenwheeler / slick

the last carousel you'll ever need
kenwheeler.github.io/slick
MIT License
28.49k stars 5.89k forks source link

Slick Center Mode - Animations Bug between last and first slide #3271

Open SimonBak opened 6 years ago

SimonBak commented 6 years ago

Hello,

I'm using SLICK in center mode with some CSS animations but i have a bug, like a rebound of animations, between last and first slide. Do you have any idea to stop this rebound ? Thanks a lot ! Simon.

====================================================================

http://jsfiddle.net/SimonBak/fmo50w7n/1701/

rogerluiz commented 6 years ago

I have the same problem

emcarru commented 6 years ago

I have the same problem. To give the impression of being infinite, when you're on the last slide, slick needs to transition to a cloned slide (for the animation to work) and then "snap" back to the start. There seems to be some timing issue on when the active classes are set because you can see the "snap" back to the start.

For a dirty short term fix you can use beforeChange to check if you're on the last slide, and then add a custom 'active' class to the clone that you're sliding to. Then on afterChange you can remove your custom class. e.g.:

$('.slider').on('beforeChange', function(e, slick, currentSlide, nextSlide) {
  const slideCount = $originalSlides.length - 1
  const nextSlideIsFirst = currentSlide === slideCount
  const nextSlideIsLast  = nextSlide === slideCount
  const $activeSlide = $('.slide.slick-active')
  if (nextSlideIsFirst) {
    $activeSlide.next('.slide').addClass('slick-clone-current');
  }
  if (nextSlideIsLast) {
    $activeSlide.prev('.slide').addClass('slick-clone-current');
  }
})

// Remove your custom active class active slide finished
$('.slider').on('afterChange', function(e, slick, currentSlide, nextSlide) {
  $('.slick-clone-current').removeClass('slick-clone-current');
})

Then in your styles you can apply your 'active' animation to .slick-current as well as your custom class:

.slick-current,
.slick-clone-current
   // add whatever animation to the active slide you're doing here
   transform: translateY(-20px)
PleasantPeasant commented 6 years ago

that fix didn't help for me or i didn't apply it right.

PaulBarrett79 commented 6 years ago

I don't think it is the timing - it seems to be that the wrong clone is being given the slick-center class.

I've made a pen here:

https://codepen.io/PaulBarrett79/pen/aExKeq

And you can see that when transitioning from the last to the first slide, the SECOND slide clone is given the classes to make it looks like the centre before it is swapped out, then the correct slide is shown in the centre, presumably after the animations have taken place. If you have more than 5 slides in this example, you don't see the other clone get the classes, because it's offscreen / hidden. If you use 4 slides in this example, by fluke the correct clone gets the classes to give the illusion of being the non-clone.

I reckon this is the cause of the center mode glitches. It's either an incorrect count in slideHandler or setSlideClasses

fpurser commented 6 years ago

same issue over here. cant seem to find a fix.

fpurser commented 6 years ago

Hacky but it works using nth child.

To fix, find your "cloned" first slide in inspector.. right click on the li and choose copy css path. This should give you your nth child count. Now replace "customClass" with the li class you assigned for each slide, and also the nth child. Add this new style rule to your "animation" css property.

.customClass.slick-center, li.customClass:nth-child(19)[aria-hidden="true"]{ transform: scale(1.2); }

Hope this helps.

PaulBarrett79 commented 6 years ago

I think I found the line that fixes this, it's within setSlideClasses and it's the selector that pulls the slide out when the index is 0. It currently only works when there is 1 more slide than the slides to show.

I'll sort out a pull request tomorrow when I'm not using literally a Chromebook to debug this.

GoodProject commented 6 years ago

I have the same problem. Is there a solution to this problem?

PaulBarrett79 commented 6 years ago

@GoodProject look at my pull request #3307 the solution is in there

kirkbross commented 5 years ago

I'm still having issues with slide index 0 not receiving 'slick-current' positioning. If I set initialSlide: 0 the slide is off the screen, i.e. not active.

http://jsfiddle.net/kirkbross/mykcdjt4/

jemuel23euel commented 5 years ago

To anyone who is still having a problem with this, I fixed mine using these css selectors:

/* slide when not active/center*/ .slick-slide[aria-hidden="true"]:not(.slick-cloned) ~ .slick-cloned[aria-hidden="true"] { }

/* slide when active/center */ .slick-slide[aria-hidden="true"]:not([tabindex="-1"]) + .slick-cloned[aria-hidden="true"] { }

Here's a fork of @PaulBarrett79's pen with this fix https://codepen.io/jemuel23euel/pen/dybGqPj

ricebandit commented 5 years ago

Can I just say jemuel23euel is The Man? I'd give him a cookie!

artibaj commented 4 years ago
/* slide when not active*/ 
.slick-slide[aria-hidden="true"]:not(.slick-cloned) ~ .slick-cloned[aria-hidden="true"] {

}

/* slide when active (when play last to first) */ 
.slick-slide[aria-hidden="true"]:not([tabindex="-1"]) + .slick-cloned[aria-hidden="true"]  {

}
/* slide when active (when play first to last) */ 
.slick-slide[aria-hidden="true"] + .slick-cloned[aria-hidden="true"] {

}
mariohernandez commented 4 years ago

Keep in mind that by setting aria-hidden="true" you are hiding your slider from screen readers. Not good for accessbility.

luizwhite commented 4 years ago

Only this solution below worked for me:

    /* slide when active (when play last to first) */
    .slick-slide[aria-hidden="true"][tabindex="-1"] + .slick-center {
      transform: scale(1.2);
    }
    /* slide when active (when play first to last) */
    .slick-slide[data-index="-1"] .slick-center {
      transform: scale(1.2);
    }
alfieindesigns commented 3 years ago

This works in my case, targeting .slick-center instead as the default and also works when play first to last

/* slide when active (when play first to last) */
.slick-center {
...
}
/* slide when active (when play last to first) */ 
.slick-slide[aria-hidden="true"]:not([tabindex="-1"]) + .slick-cloned[aria-hidden="true"]  {
...
}
ethanloh95 commented 3 years ago

To anyone who is still having a problem with this, I fixed mine using these css selectors:

/* slide when not active/center*/ .slick-slide[aria-hidden="true"]:not(.slick-cloned) ~ .slick-cloned[aria-hidden="true"] { }

/* slide when active/center */ .slick-slide[aria-hidden="true"]:not([tabindex="-1"]) + .slick-cloned[aria-hidden="true"] { }

Here's a fork of @PaulBarrett79's pen with this fix https://codepen.io/jemuel23euel/pen/dybGqPj

Working fine, thanks so much for the solution

2dareis2do commented 2 years ago

I am experiencing an issue with the first and the last slide when using centre mode. If the number of items is the same as the maximum items shown. This is easily replicated taking a fork of the above.

https://codepen.io/twodareis2do/pen/oNoMMRy

slick-center class is added to first and last slides

ok I have raised separate bug for this here https://github.com/kenwheeler/slick/issues/4172

ZihadHosan commented 2 years ago

@jemuel23euel You just saved my day! The solution is working just fine. Many Thanks!!!!!

faisaljanjuah commented 1 month ago

Guys I know this is really old issue and may be it is out of date but just for help, The issue is when you target multiple classes for center like:

.slick-slide.slick-active.slick-current.slick-center {
    transform: scale(1.3);
}

this will cause issue.

solution is just target only center class like this

.slick-slide.slick-center {
    transform: scale(1.3);
}
.slick-slide {
    transition: all ease .3s;
}

look at demo: https://jsfiddle.net/faisaljanjuah/9fffrd1r/