slick icon indicating copy to clipboard operation
slick copied to clipboard

Slide width incorrect with slides to show greater than 2

Open jimmymorris opened this issue 9 years ago • 23 comments

The slide width seems to be off a few pixels when slidesToShow is set to something other than the default. I added a border to the slides to help better show that the last slide's width is seemingly being cropped a few pixels.

I'm able to resize the browser and it'll show the full slide. Browser doesn't seem to matter.

jsFiddle link: https://jsfiddle.net/headunderwater/mz8knxw1/

Steps to reproduce the problem

  1. Have the slide number be greater that the slide to show.
  2. Set the slidesToShow option to any number greater than 2

jimmymorris avatar Feb 26 '16 01:02 jimmymorris

The width of slick-slide is rounded, If rounded up these pixel are missing.

Maybe there is another way to calculate the slide width in %.

Bjoernstjerne avatar Feb 26 '16 20:02 Bjoernstjerne

I don't think so, Mazzaker. However, it's been about a year now since browsers implemented crazy floating-point pixels... Slick should adapt and at least go down to 3 points of precision, I think?

simeydotme avatar Feb 28 '16 13:02 simeydotme

@jimmymorris ... can I ask why you've minified the Slick resources in your Fiddle? I can not debug and manipulate them.

simeydotme avatar Feb 28 '16 13:02 simeydotme

@simeydotme Sorry about that! Not sure why it minified, I swore I forked it from http://jsfiddle.net/simeydotme/fmo50w7n/ need me to recreate?

jimmymorris avatar Feb 29 '16 01:02 jimmymorris

In setDimensions:

if (_.options.vertical === false && _.options.variableWidth === false) {
    _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
    _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
}

Change first .ceil to .floor -> Fiddle

But this is not better either. I can try to calculate the width in % this should be more accurate in modern browser.

Bjoernstjerne avatar Feb 29 '16 06:02 Bjoernstjerne

Because we don't support IE8 for our clients, I've forked slick to use getBoundingClientRect to get the list width, and then removed calls to Math.ceil when determining slide width. That way the pixel width of the slides is fractional and exact. Here are my changes:

https://github.com/jonscottclark/slick/commit/180c9994a43633aae9db0fa0f2286489d1cd61f2

But this means you'd have to drop support for IE8 altogether.

Or.. you could potentially use this method of simulating getBoundingClientRect: https://github.com/zeroclipboard/zeroclipboard/blob/be4573579f9dbccad4280bd06e2e72c896fa5c66/ZeroClipboard.js#L124-L155

Then, the list width would be precise, meaning that your precise-width slides (with Math.ceil removed) would also fit perfectly.

I had the exact issue as OP and these changes solved it for me in all browsers (except IE8, of course)

jonscottclark avatar Feb 29 '16 15:02 jonscottclark

@jonscottclark I tried using your fork and it made it more accurate by a pixel but still showing a sliver of the next slide, as well as now showing a pixel sliver on the left as well. Also I am only showing 1 slide per as opposed to multiple which is what this bug reports. screen shot 2016-03-03 at 6 03 32 pm

dankram avatar Mar 04 '16 02:03 dankram

@dankram Since you mentioned it I went to verify, and you're right, there are more changes that are needed. The translate3d value, called targetLeft still gets floored/ceiled, and even if it's changed in the CSS to the exact value it needs to be (some fractional value), you'll still see slivers (on retina, at least).

Here's my test run where you can see the issues happening: https://jsfiddle.net/jonscottclark/aym5aaj5/3/

Forgive me for assuming I had a legit fix — I think it worked in the situation when I needed it, and I didn't see any negative side effects, and didn't test it out rigorously enough. Hm.

jonscottclark avatar Mar 04 '16 02:03 jonscottclark

No worries! If you come up with a more comprehensive solution I'd love to see it. We are launching our product in a month. :fire:

dankram avatar Mar 04 '16 02:03 dankram

I have disabled transform3d on the list element. This resolved it to me.

.slick-slider .slick-list {
    transform: none;
}

It's more of a hotfix, of course.

max-ch9i avatar Mar 11 '16 09:03 max-ch9i

Hello, since most people here are proposing a floating-point solution, I would like to share a suggestion I made in my closed duplicate issue. The issue is with the use of Math.ceil in the line that determines slideWidth (see it here). I suggest:

  • Use Math.floor instead so that the rounding errors don't cause the slides to leave the parent element. This technically eliminates the problem of those getting cut off, but it introduces a new problem - extra partial slides might appear at the right edge. So,
  • Compute a width for some intermediate element (maybe .slick-list) as slideWidth times the number of slides, and use that to crop the carousel to the correct width, hiding the extra slides.

pdg137 avatar Jun 29 '16 01:06 pdg137

I have the same problem. Please just remove Math.ceil completely from the setDimensions method. Current slide width calculation with the Math.ceil is inaccurate if Slick container is fluid.

artuska avatar Jul 13 '16 11:07 artuska

I seem to be having the same issue with a vertical slider as it shows the next slide underneath the current slider by about 3 or 4 pixels which is quite off putting when you actually notice it.

Couldn't figure out a CSS method that would fix it other than forcing the height through some sort of external JavaScript means. Any help on this?

danieltj27 avatar Oct 05 '16 15:10 danieltj27

@leggomuhgreggo we had so many issues with this , can you please explain why is Math.ceil used in setDimensions. I removed it and there are no problems with widths and borders.

danyj avatar Dec 10 '16 12:12 danyj

+1

mikeploeger avatar Jul 03 '18 08:07 mikeploeger

+1

ewessolek avatar Jul 04 '18 09:07 ewessolek

Still open?

CptKicks avatar Mar 08 '19 22:03 CptKicks

+1

tindl88 avatar Apr 12 '19 09:04 tindl88

  .slick-list {
      overflow: inherit;
    }

Fixed it for me!!!

chadlof avatar May 20 '19 21:05 chadlof

Bump, still having issue with this one in 2021.

alenvuletic avatar Dec 20 '21 09:12 alenvuletic

I also experienced this problem short time ago with combination of bootstrap. The problem was putting slick as direct child of bootsrap's .row couses miscalculation of width when slide count is not equal to slidesToShow option. Writing here so someone else facing this might find it useful.

safarovitch avatar Jun 14 '22 13:06 safarovitch

If I'm correct the main issue here is that usually slick-list has lower width than its child slick-slide and it's around 1px with a variable amount of digits after the comma because of the Math.ceil() rounding. The easiest workaround solution that I came up with is that all of my slide content wrapped in the child of slick-slide called for instance cmp-carousel__slide-item, I just set the width of that child to calc(100% - 1px) !important(you can play with the number of pixels here) and everything seems to be working fine with the responsive carousel layout.

See screenshots: image image

m3ltman avatar Feb 14 '23 13:02 m3ltman

I change the lines:

if (_.options.vertical === false && _.options.variableWidth === false) {
    _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
    _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
}

for

if (_.options.vertical === false && _.options.variableWidth === false) {
    _.slideWidth = (_.listWidth / _.options.slidesToShow).toFixed(1); // Replace Math.ceil to toFixed
    _.$slideTrack.width(_.slideWidth * _.$slideTrack.children('.slick-slide').length + 1); // Remove Math.ceil and Add +1px to ensure plenty of width    
}

ribeiroeder avatar Apr 01 '24 15:04 ribeiroeder