89

I'm having trouble with the Slick carousel JS plugin with multiple slidesToShow which have different heights.

I need the Slides to have the same height, but with CSS flex-box it doesn't work as the slides have conflicting CSS definitions.

Also, I didn't find anything useful in the forums and on the web.

HTML

<div class="slider">
  <div class="slide">
    <p>Lorem ipsum.</p>
  </div>
  <div class="slide">
    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua</p>
  </div>
  <div class="slide">
    <p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
  </div>
  <div class="slide">
    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
  </div>
</div>

JS

$('.slider')
.slick({
    autoplay: false,
    dots: false,
    infinite: false,
    arrows: false,
    slidesToShow: 2,
    slidesToScroll: 2,
    rows: 0
});

CSS

.slide {
  height: 100%;
  background-color: #ccc;
  padding: 10px;
}
Null
  • 1,950
  • 9
  • 30
  • 33
JJaun
  • 1,690
  • 2
  • 10
  • 16

13 Answers13

234

Add a couple of CSS styles and it will be ready:

.slick-track
{
    display: flex !important;
}

.slick-slide
{
    height: inherit !important;
}

Enjoy! :-)

Phoenix
  • 2,796
  • 5
  • 17
  • 21
  • 6
    Great! This code is working like a charm with the new version (1.9.0). – Reza Mamun Nov 08 '18 at 15:01
  • 7
    Works great. I added some extra flex declarations for 2D centering of image of different sizes: `.slick-track { display: flex !important; } .slick-slide { height: inherit !important; display: flex !important; justify-content: center; align-items: center; } ` – Stuart Cusack Apr 23 '19 at 15:25
  • 19
    This is a much simpler solution. I also had to add `.slick-slide > div { height: 100%; }` to account for the auto-generated div element. – Luke Jun 02 '19 at 08:30
  • 2
    This is what everybody needs. +1 – Nandesh Sep 24 '19 at 17:23
  • 1
    This is the exact solution I was looking for. Using the Slick JS params, does height animation transitions that are a no-go. – Marko Bajlovic May 21 '20 at 19:45
  • this is the CSS only solution to go, just in my case it didnt work with flex as i mentioned in the original post – JJaun Aug 25 '20 at 14:08
  • 4
    In my case, there were **two** more `divs` between the `track` and `slide` class div. To make it work, I set `height: 100%` for them too, similar to what @Luke said :) – João Vitor Veronese Vieira Jun 02 '21 at 20:26
  • 1
    Why height: inherit works and not height: 100% I don't understand, but this is great. – pinksharpii Jun 08 '21 at 15:20
  • Why does `height:inerhit` only work when the parent is `flex` and not `block`? – Scott Coates Jan 11 '23 at 19:02
32

Ok guys i found an easy solution. Just add a setPosition callback function (fires after position/size changes) which sets the height of the slides to the height of the slider (slideTrack):

JS

$('.slider').slick({
    autoplay: false,
    dots: false,
    infinite: false,
    arrows: false,
    slidesToShow: 2,
    slidesToScroll: 2,
  rows: 0
})
.on('setPosition', function (event, slick) {
    slick.$slides.css('height', slick.$slideTrack.height() + 'px');
});

Dont forget that your slides need to have full height:

CSS

.slide {
  height: 100%;
}

Here is a little jsFiddle to demonstrate: https://jsfiddle.net/JJaun/o29a4q45/

JJaun
  • 1,690
  • 2
  • 10
  • 16
  • 1
    I'm having a similar issue with a carousel. I tried to apply the `setPosition` fix to my script but it just breaks it. Can you see where I'm going wrong? https://codepen.io/moy/pen/KBZbZL – user1406440 Jul 30 '18 at 21:58
  • You should update this answer to first set the $slides height to "auto" otherwise on resize your height measurements will be inaccurate since your $slideTrack height will be off because it's children $slides have a fixed pixel height. – jdbosley Oct 04 '18 at 18:13
  • 3
    You should update the answer to use `slick.$slideTrack.find('.slick-slide')` as cloned elements do not have the same height whilst transitioning. – minlare Dec 06 '18 at 10:40
12

The js solution from @JJaun is not perfect, because you see the height jumping if you use an background image for the slides. This worked for me:

.slick-track {
  display: flex !important;
}

.slick-slide {
  height: auto;
}
Artem Bruner
  • 121
  • 1
  • 3
6

As answered above.works fine on slick slider

.slick-track
{
    display: flex !important;
}

.slick-slide
{
    height: inherit !important;
}

but, i have an issue when using slick sync navigation

simple put below css to cover it.

.slick-slide {
    margin-bottom: 0;
    object-fit: cover;
}
teenage vampire
  • 339
  • 1
  • 5
  • 13
4

Solution on pure css

.slick-track {
    display: flex;
}

.slick-track .slick-slide {
    display: flex;
    height: auto;
}

.slick-slide img {
    height: 100%;
    object-fit: contain;
    object-position: center;
}
Lysak
  • 333
  • 1
  • 4
  • 7
3

Here's an SCSS-only solution if you're OK with using object-fit:

.slick {
  .slick-track {
    display: flex;

    .slick-slide {
      display: flex;
      height: auto;

      img {
        height: 100%;
        object-fit: cover;
        object-position: center;
      }
    }
  }
}
dodov
  • 5,206
  • 3
  • 34
  • 65
3
  1. .slick-track { display: flex; align-items: stretch; }

  2. .slick-slide { height: auto; flex: 1; }

  3. And, if you want to stick the last element in the bottom of the block, add display: flex for wrapper and margin-top: auto; to last element

2

I've another css-only solution. you can override floated elements with table/table-cell.

$(function() {
  $('.slider')
    .slick({
      autoplay: false,
      dots: false,
      infinite: false,
      arrows: false,
      slidesToShow: 2,
      slidesToScroll: 2,
      rows: 0
    });
})
.slide {
  background-color: #ccc;
  padding: 10px;
  display: table-cell !important;
  float: none !important;
}

.slick-track {
  display: table !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>


<div class="slider">
  <div class="slide">
    <p>Lorem ipsum.</p>
  </div>
  <div class="slide">
    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua</p>
  </div>
  <div class="slide">
    <p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
  </div>
  <div class="slide">
    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</p>
  </div>
</div>
Okan Kocyigit
  • 13,203
  • 18
  • 70
  • 129
  • in my actual usecase i have to build this in a finished bootstrap layout which i can not really change...here i have bootstrap columns with cards inside and those cards are not the same hight as the actual slides...something linke this https://jsfiddle.net/JJaun/o29a4q45/22/ got an idea how to fix it? – JJaun Feb 28 '18 at 13:20
  • @JJaun, hımm nested elements, it's getting complicated with css. Than you should do it with your js way (calculating height), here is the updated one, https://jsfiddle.net/o29a4q45/43/ – Okan Kocyigit Feb 28 '18 at 14:00
  • setting height of content triggers `setPosition` again. i've added a fix. check it again https://jsfiddle.net/o29a4q45/49/ – Okan Kocyigit Feb 28 '18 at 14:10
  • yea i see, there is indeed no need to set the height on every setPosition event. thanks. – JJaun Mar 01 '18 at 07:40
  • @ocanal I tried to apply this to a problem I'm having but the code seems to break, can you see why? https://codepen.io/moy/pen/KBZbyL – user1406440 Jul 30 '18 at 21:56
  • @user1406440, your codepen has js syntax error and missing slick reference file, here is the updated fiddle for your use case, https://jsfiddle.net/o29a4q45/128/ – Okan Kocyigit Jul 30 '18 at 22:15
  • Doh! Sorry @ocanal, I posted that quickly before I went to bed. So it just looks like (when Slick was included) I just needed to remove the `;` before the additional code? I realised I'd amended my markup sightly, I've got rid of the JS breaking but I don't get the 100% height - can you see why? https://codepen.io/moy/pen/mjXyPM – user1406440 Jul 31 '18 at 07:09
  • 1
    @user1406440, i've changed `resort` to `tile`, and some minor fixes, updated one is here, https://codepen.io/anon/pen/QBQjWp – Okan Kocyigit Jul 31 '18 at 08:09
  • Awesome, that's such a simple change to your first example - I'm clearing not thinking straight today! So all the markup/css was ok it was just the additional bit of js referencing `slick-slide` rather than `resorts`? Thanks again for your help! – user1406440 Jul 31 '18 at 10:44
  • One last quick question actually, I've amended the code to `slick.$slideTrack.height() - 30 + 'px'` as I have a top/bottom margin on the track. Is that the best way or is there a `height` value that subtracts any margin from it? I know `heightOuter` etc but that's just for adding on padding. – user1406440 Jul 31 '18 at 18:33
  • @JJaun I'm unsure whether the JsFiddle is just old or whether the setPosition is buggy. I've tried implementing that code and played with the fiddle and found that if you were to include the dots or arrows and change slides with them, the height grows 5-10px on every click. – mckenna May 07 '19 at 14:45
2

For future searches:

You can simply use:

$('.slick').slick({ 
      /* your config */ 
 }).on('setPosition', function (event, slick) {
      slick.$slides.css('height', slick.$slideTrack.height() + 'px');
 });
1

I've wrote a quick JS hack to make a gallery with different images heights to look a little neater.

It does the following:

  1. Get slider instance
  2. Find out it's height - images height will be set to that
  3. Get the src attr for each image and hide it
  4. Set src attr to image's parent as a background image together with some CSS.

    function equalizeImagesHeight(slider) {
        const slides = slider.find('.slick-slide');
        const imgHeight = $(slider)[0].clientHeight;
        slides.each(function(slide){
            const src = $(this).find('img').hide().attr('src');
            $(this).css({
                backgroundImage:'url('+src+')',
                minHeight: imgHeight,
                backgroundSize: "cover",
                backgroundPosition: "center"
            });
        });
    };
    

    equalizeImagesHeight($('.my-slider'));

1

For me with latest version of slick in 2021 slick keep wrap my item's with additional div

So i do:

        .slick-track
        {
            display: flex !important;
            height: 100%;
        }

        .slick-slide
        {
            height: auto;

            .slick-slide> div
            {
                height: 100%;

                .myItemClass
                {
                    height: 100%;
                }
            }
        }
0

Above suggestions didn't work for me. My slider images are al portrait but might have different h/w aspect ratios. I fixed it using js. Feels ugly though, wish I found something cleaner.

$carousel.on('setPosition', function (event, slick) {
      const $slideImages = slick.$slideTrack.find('.slick-slide-img');
      if($slideImages.first()[0].clientHeight >= $slideImages.first()[0].naturalHeight) return;
      $slideImages.height('auto');
      $slideImages.width('100%');
      const imgHeights = $slideImages.map(function(){
        return this.clientHeight;
      }).get();
      const maxHeight = Math.max.apply(null, imgHeights);
      $slideImages.height(maxHeight);
      $slideImages.width('auto');
    }

I had to use the setPosition event eventhough the code only needs to be executed once, after initialising slick. The init event doesn't work because the image heights on init are way off. Same for the first one or two setPosition events - hence the if($slideImages.first()[0].clientHeight >= $slideImages.first()[0].naturalHeight) return;.

jnaklaas
  • 1,619
  • 13
  • 16
0

Here is a jQuery approach to make the slides equal in height.

$('.slick-elem').on('init reInit', function(event, slick, currentSlide, nextSlide) {

  setSlidesHeight(event);

});

function setSlidesHeight(event) {

  let $ = jQuery;
  let slickEl = $(event.target);
  let slidesEl = slickEl.find('.slick-slide');
  let maxHeight = -1;

  slidesEl.each(function(index, el) {

    maxHeight = maxHeight > $(el).height() ? maxHeight : $(el).height();

  });

  slidesEl.each(function(index, el) {

    $(el).height(maxHeight);

  });

}
AhmadKarim
  • 899
  • 1
  • 7
  • 16