kenwheeler / slick

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

Chrome 61 - Inconsistent values from Slick.prototype.setDimensions when using centerMode #3173

Open damanic opened 7 years ago

damanic commented 7 years ago

I found a strange issue with Chrome where clean page loads (CTRL F5) would calculate one set of dimensions and a browser cached page load would produce another. This relates to the centerMode option where CSS padding is added to the slick container. The addition of padding normally reduces the elements width() and keeps the innerWidth() the same. However in Chrome it was increasing the innerWidth and keeping the width() the same. This only occurred on the browser cached refreshes.

The only way I could get around the problem was to update the function as follows:

   Slick.prototype.setDimensions = function() {

        var _ = this;

         var overrideWidth = false;
        if (_.options.vertical === false) {
            if (_.options.centerMode === true) {

              var listWidth = _.$list.width();
              var listInnerWidth = _.$list.innerWidth();

              _.$list.css('padding' ,'0px ' + _.options.centerPadding)

              var paddingAppliedLeft = parseFloat(_.$list.css('padding-left'));
              var paddingAppliedRight = parseFloat(_.$list.css('padding-right'));
              var paddingAppliedTotal =  paddingAppliedLeft + paddingAppliedRight;
              var newListInnerWidth = _.$list.innerWidth();

              var hasEnlargedElement = newListInnerWidth > listInnerWidth;

              if(hasEnlargedElement){
                //chrome bug?
                console.log('chrome bug?');
                var resetWidth = listWidth - paddingAppliedTotal;
                _.$list.width(resetWidth);
                _.listWidth = resetWidth;
                overrideWidth = true;
              }

            }
        } else {
            _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
            if (_.options.centerMode === true) {
                _.$list.css({
                    padding: (_.options.centerPadding + ' 0px')
                });
            }
        }

        if(!overrideWidth){
          _.listWidth = _.$list.width();
        }
        _.listHeight = _.$list.height();

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

        } else if (_.options.variableWidth === true) {
            _.$slideTrack.width(5000 * _.slideCount);
        } else {
            _.slideWidth = Math.ceil(_.listWidth);
            _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
        }

        var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
        if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);

    };

Steps to reproduce the problem

  1. Console log innerWidth() and width() results from Slick.prototype.setDimensions
  2. Set up a simple scroller in a fluid box that has the centerMode option,
_this.sliders.slick({
            variableWidth : false,
            centerMode    : true,
            centerPadding : '15%',
            slidesToShow  : 1,
            rows : 0,
            nextArrow     : '<button type="button" class="slick-next"><span class="sr--only">Next</span></button>',
            prevArrow     : '<button type="button" class="slick-prev"><span class="sr--only">Previous</span></button>',

          });
  1. Look for varied results in the Chrome 61 console log when refreshing the browser F5 vs cached

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

What is the expected behaviour?

innerWidth() and width() should return consistent results

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

What is observed behaviour?

innerWidth() and width() return inconsistent results

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

Found on

mikemccaffrey commented 5 years ago

I was having the same issue, where chrome was intermittently showing our gallery images as way too large. I ended up adding this additional check to the Slick.prototype.setDimensions function:

_.listWidth = _.$list.width();
_.listHeight = _.$list.height();

// If the carousel is larger than the browser window, we are experiencing the chrome width issue.
if (_.listWidth > $(window).width()) {
  _.listWidth = $(window).width() - parseInt(_.$list.css('padding-left')) - parseInt(_.$list.css('padding-right'));
}

That is just a band-aid, but seems to get things working fine on our site.