kenwheeler / slick

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

Adaptive height slides with expanding content. #1320

Closed nerijusgood closed 9 years ago

nerijusgood commented 9 years ago

Hi, first of all great Slider, keep up the awesome work.

I am facing a situation where I have 1 Slide per screen slider with very different amount of content, thus adaptive height is necessary to avoid huge white space gaps.

On top of that, each slider has a toggle which shows/hides more content, which gives me an issue: adaptive height setting gives each slide a fixed height, thus making expandable extra content not fit the slide height and go under other elements.

How to address this issue? First ideas were to: 1) on toggle click, unslick to remove fixed height 2) init slick right after. Which is not working as expected.

Is there a proper way to recalculate height, reinit slick or solve adaptive height without setting height?

donum commented 9 years ago

Hi,

I have exactly the same problem I am currently working on.

What I just tried was to use the onAfterChange event to set the height of the outer container to auto after adaptive height has done it's job.

The only issue is, onAfterChange gets triggered before setPosition which will set the height. (link to source code)

That feels odd. One would expect this event to be fired after everything else is done.

edit Regarding your idea. It works if you do:

$slickSlider.find(".slick-slide").height("auto");
$slickSlider.slickSetOption(null, null, true);

This was mentioned before by @apfelbox and worked fine for me. In my use case it doesn't work nicely, because my slide content element collapses with an animation so I really would like to add height:auto to the outer container.

Best Regards, Daniel

nerijusgood commented 9 years ago

On the weekend ill try to make a live example and then we maybe could try various solutions.

donum commented 9 years ago

I already posted two solutions.

monkviper commented 9 years ago

I am not great on javascript but this is how I fixed the same issue. I had to put multiple slider and expanding content in the main slick slider.

https://gist.github.com/monkviper/3c58438f3592a4fd9b31

phylaxis commented 9 years ago

I know this is closed, but I am having a somewhat similar issue that I can't seem to solve and the onAfterChange fix is not working in my case. I have a page with two slick sliders. One for showing thumbnails and one that contains the full sized images in a Foundation 5 Reveal modal. I have some jQuery code that has an on.('click') event that determines the slide index of the slide that was clicked uses a slickGoTo event to advance the slide in the modal. I then open the modal. You can see a working example here: http://03c7bc9.netsolhost.com/listing/wailea-seashore-suite-k507/#photos. The issue I'm having (which you will likely see in the demo) is that most of the time the first slide appears with a collapsed height. If you advance the slide or even just resize the browser window the slide will open to it's full height and all is fine. I need a way to get the slide to refresh to the correct height reliably each time the modal is opened. Any ideas? Here is the full code I'm using to open the modal:

$('.lvh-slide-thumb').on('click', function() {

     var idx = $(this).data('slick-index');
     $(".lvh-listing-modal-slider").slick("slickGoTo", idx, false);
     $('#lvh-slider-modal').foundation('reveal','open').delay(500);
});
LiamTorrelli commented 6 years ago

Good day, everyone. I had the same issue, and actually there are two ways to resolve this.

  1. This way will work on desktop, unfortunately it does not solve the problem on mobile
    
    var sliderAdaptiveHeight = function() {
    var heights = [];
    let items = $('.slick-active')
    items.each(function() {
        heights.push($(this).height());
    });
    $('.slick-list').height(Math.max.apply(null, heights));
    }
    sliderAdaptiveHeight();

$('.train-right-slider').on('afterChange', function(event, slick, currentSlide, nextSlide){ sliderAdaptiveHeight(); });

2. This solution will also work on mobile

var sliderAdaptiveHeightMobile = function() { $slickSlider.find('.slick-slide').height('0'); $slickSlider.find('.slick-slide.slick-active').height('auto'); $slickSlider.find('.slick-list').height('auto'); $slickSlider.slick('setOption', null, null, true); }

khushbupatel24 commented 4 years ago

Hi,

I have exactly the same problem I am currently working on.

What I just tried was to use the onAfterChange event to set the height of the outer container to auto after adaptive height has done it's job.

The only issue is, onAfterChange gets triggered before setPosition which will set the height. (link to source code)

That feels odd. One would expect this event to be fired after everything else is done.

edit Regarding your idea. It works if you do:

$slickSlider.find(".slick-slide").height("auto");
$slickSlider.slickSetOption(null, null, true);

This was mentioned before by @apfelbox and worked fine for me. In my use case it doesn't work nicely, because my slide content element collapses with an animation so I really would like to add height:auto to the outer container.

Best Regards, Daniel

Hey, where should I include this line in my code?

$('.app_slider').slick({ dots: true, arrows: false, infinite: false, slidesToShow: 1, slidesToScroll: 1, adaptiveHeight: true, touchThreshold: 10 });

This is the slider code. I have a read more button in caption, which expand caption detail on click. For that, I want height auto of slick-list div.

ImraKocis commented 1 year ago

Is there any solution for this but with 'react-slick'.

Thanks in advance :smile:

kennigandira commented 11 months ago

Is there any solution for this but with 'react-slick'.

Thanks in advance 😄

I think I just found how to solve this in react-slick. This is how I solved it:

import Slider from 'react-slick'

// Somehow Slider's type doesn't have innerSlider even tho it actually has
interface ExtendedSlider extends Slider {
  innerSlider: {
    forceUpdate: () => void
  }
}

const sliderRef = useRef<Slider>(null)

......

<Slider ref={sliderRef}>
    {list.map((item) => (
        <ExpandableContentSliderItem
            onExpandContentClick={() => {
                // Access inner slider forceUpdate method in order to re-render the slick-list container's height
                (sliderRef.current as ExtendedSlider)?.innerSlider.forceUpdate()
             }}
        />
   ))}
ImraKocis commented 11 months ago

@kennigandira Thank u for replay. Sadly we had so much issues with react-slick and we decided to go in other direction so I can not try this. Hopefully it will help someone else :smile: