JJaun
JJaun

Reputation: 2020

Slick carousel - force slides to have the same height

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;
}

Upvotes: 104

Views: 208114

Answers (14)

Vishal Kumar
Vishal Kumar

Reputation: 1

.slick-slide {
&[aria-hidden='true'] {
  height: 0;
}}

I found an alternative solution that works well for me. I'm using Antd, which uses React Slick under the hood.

Upvotes: 0

AhmadKarim
AhmadKarim

Reputation: 905

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);

  });

}

Upvotes: 0

Lysak
Lysak

Reputation: 393

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;
}

Upvotes: 6

Damian Chudobiński
Damian Chudobiński

Reputation: 559

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%;
                }
            }
        }

Upvotes: 2

  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

Upvotes: 4

teenage vampire
teenage vampire

Reputation: 359

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;
}

Upvotes: 6

Jazz Macedo
Jazz Macedo

Reputation: 21

For future searches:

You can simply use:

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

Upvotes: 2

jnaklaas
jnaklaas

Reputation: 1769

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;.

Upvotes: 0

dodov
dodov

Reputation: 5884

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;
      }
    }
  }
}

Upvotes: 3

Artem Bruner
Artem Bruner

Reputation: 141

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;
}

Upvotes: 14

Phoenix
Phoenix

Reputation: 3242

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

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

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

Enjoy! :-)

Upvotes: 275

Damian Drozdowicz
Damian Drozdowicz

Reputation: 11

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'));

Upvotes: 1

Okan Kocyigit
Okan Kocyigit

Reputation: 13441

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>

Upvotes: 2

JJaun
JJaun

Reputation: 2020

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/

Upvotes: 34

Related Questions