New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Equal height slides #179

Closed
LMBE opened this Issue Apr 25, 2014 · 43 comments

Comments

Projects
None yet
@LMBE
Copy link

LMBE commented Apr 25, 2014

Be nice to have the option to set smaller slides to the height of the tallest.

@kenwheeler kenwheeler added the wontfix label Apr 29, 2014

@kenwheeler kenwheeler closed this Apr 29, 2014

@LMBE

This comment has been minimized.

Copy link

LMBE commented Apr 30, 2014

3c21f4fd695b25c131acb84018d3586e

@kenwheeler

This comment has been minimized.

Copy link
Owner

kenwheeler commented Apr 30, 2014

Lol! Can't you just do that with css?

@LMBE

This comment has been minimized.

Copy link

LMBE commented Apr 30, 2014

Not unless you use flex box. I've added a separate bit of js to loop through and set heights now. Great plugin btw!

@kenwheeler

This comment has been minimized.

Copy link
Owner

kenwheeler commented Apr 30, 2014

Thanks! Have you tried the top: 0; bottom: 0; trick?

@LMBE

This comment has been minimized.

Copy link

LMBE commented Apr 30, 2014

Not as far as I'm aware! It would if each slide was absolutely positioned but relative is applied inline. Another way would be to use table positioning, but that's just wrong.

@kenwheeler

This comment has been minimized.

Copy link
Owner

kenwheeler commented Apr 30, 2014

Lol

@neilbaylorrulez

This comment has been minimized.

Copy link

neilbaylorrulez commented May 5, 2014

This is deinitely impossible with pure CSS (without flexbox or display table-cell, which each have their own implications) - I am using something like:

function updateRotatorHeight(selector) {
        var maxHeight = -1,
            $items;
        $items = $rotator.find(selector).each(function (i, item) {
            var height;
            item.style.height = '';
            $(item).children().first().css('paddingTop', '');
            if((item.curHeight = item.scrollHeight) > maxHeight) {
                maxHeight = item.curHeight;
            }
        }).each(function (i, item) {
            $(item).css('height', maxHeight).children().first().css('paddingTop', (maxHeight - item.curHeight) / 2);
        });

        rotatorHeight = maxHeight;
    }

//you should debounce this
$window.on('resize', updateRotatorHeight.bind(null, '.slick-track > li'));
@akrawchyk

This comment has been minimized.

Copy link
Contributor

akrawchyk commented Jul 18, 2014

I see this in the context of onBeforeChange and onAfterChange has property listHeight which could be useful here. I believe that value corresponds to the height of the slick track, so it could be possible to update that value on multiple browser events and use it to equalize slide heights. For now, I solved this with a similar approach to @neilbaylorrulez:

jQuery('.js-slider').slick(slickOptions).each(function() {
  function equalizeHeights() {
    var $this = $(this);
    var $track = $this.find('.slick-track');
    var $slides = $track.children();

    // layout thrashing here, can't help it since we need to remove
    // min-height to have the layout recalculate the auto height of the
    // slick track
    $slides.css('min-height', '');
    var minSlideHeight = $track.height();
    $slides.css('min-height', minSlideHeight);
  }

  var equalizeSlideHeights = throttle(equalizeHeights.bind(this), 250, true);
  $window.on('DOMContentLoaded load resize', equalizeSlideHeights);
});
@phylaxis

This comment has been minimized.

Copy link

phylaxis commented Apr 17, 2015

@akrawchyk I am attempting to use your solution, but get this error:

ReferenceError: Can't find variable: throttle

Do you have a throttle function you created, but is missing from your sample here?

@akrawchyk

This comment has been minimized.

Copy link
Contributor

akrawchyk commented Apr 27, 2015

@phylaxis I think you can remove the throttle part and use $window.on('DOMContentLoaded load resize', equalizeHeights); instead if you don't need it. Regardless, here is the throttle function:

// performant throttle implementation http://jsperf.com/throttle
function throttle(fn, frequency) {
  'use strict';

  frequency = frequency || 100;
  var timeout = false;

  return function() {
    if (timeout) {
      return;
    }

    timeout = setTimeout(function() {
      timeout = false;
    }, frequency);

    fn.apply(this, arguments);
  };
}

Hope that helps :)

@dewwwald

This comment has been minimized.

Copy link

dewwwald commented Jun 11, 2015

@LMBE Its not table positioning, it is table display properties, and its not bad, its not bulking up markup its only presentation.

@lschneiderman

This comment has been minimized.

Copy link

lschneiderman commented Nov 16, 2015

I do it this way:

var stHeight = $('.slick-track').height();
$('.slick-slide').css('height',stHeight + 'px' );

@jdmagic21

This comment has been minimized.

Copy link

jdmagic21 commented Dec 30, 2015

@lschneiderman +1

@nickfmc

This comment has been minimized.

Copy link

nickfmc commented Feb 9, 2016

@lschneiderman +1 Thanks for that simple solution, one limitation unless inside a function checking for change in the .slick-track height is that is will only size your height on page load not on mobile screen rotation for example.

@ramonleenders

This comment has been minimized.

Copy link

ramonleenders commented Apr 2, 2016

As said, that will only work on page load. I've used the "setPosition" event from Slick slider here.

$('.your-selector.').on('setPosition', function () {
$(this).find('.slick-slide').height('auto');
var slickTrack = $(this).find('.slick-track');
var slickTrackHeight = $(slickTrack).height();
$(this).find('.slick-slide').css('height', slickTrackHeight + 'px');
});

Somehow my code is not formatting, that's why I'm using a blockquote instead.

@mateuspaulino

This comment has been minimized.

Copy link

mateuspaulino commented May 10, 2016

Thanks a lot @ramonleenders and @lschneiderman

@Jakobud

This comment has been minimized.

Copy link

Jakobud commented Jun 13, 2016

This should be included in the core code as an option. equalizeHeight: true/false or something like that.

@JamesIves

This comment has been minimized.

Copy link

JamesIves commented Jul 1, 2016

Completely agreed @Jakobud

@leggomuhgreggo

This comment has been minimized.

Copy link
Collaborator

leggomuhgreggo commented Jul 1, 2016

I know foIks have mentioned this already, but here's how to get it done with flexbox:

.slick-track{
    display: flex;

    .slick-slide{
        display: flex;
        height: auto;
        align-items: center; //optional
        justify-content: center; //optional
    }
}

pen

Alternatively, the JS @ramonleenders wrote will do the trick.

Hope this is helpful

@shaynestatzell

This comment has been minimized.

Copy link

shaynestatzell commented Sep 28, 2016

Thanks @leggomuhgreggo additionally add flex-direction: column; to .slick-slide if slides contain multiple elements, this will stack them vertically.

@rabelBB

This comment has been minimized.

Copy link

rabelBB commented Nov 9, 2016

Thanks @ramonleenders saved me lots of stress with that solution!

@leggomuhgreggo

This comment has been minimized.

Copy link
Collaborator

leggomuhgreggo commented Dec 9, 2016

@ramonleenders

This comment has been minimized.

Copy link

ramonleenders commented Dec 9, 2016

Use my Javascript variant instead (posted 2 Apr), and drop the Flexbox code?

@wking-io

This comment has been minimized.

Copy link

wking-io commented Feb 22, 2017

You can have the function reload on page resize using this function. (Only runs when resize stops so it is not pushing a ton of JS calls)

var stHeight = $('.slick-track').height(),
      timeout = false, // holder for timeout id
      delay = 250; // delay after event is "complete" to run callback

function refreshSlickHeight() {
      $('.slick-slide').css('height', stHeight + 'px' );
}

// window.resize event listener
window.addEventListener('resize', function() {
      // clear the timeout
      clearTimeout(timeout);
      // start timing for event "completion"
      timeout = setTimeout(refreshSlickHeight, delay);
});
@sunnypuma

This comment has been minimized.

Copy link

sunnypuma commented Mar 6, 2017

front-end, finding job qq group: 365563094

@artursopelnik

This comment has been minimized.

Copy link

artursopelnik commented Apr 26, 2017

@ramonleenders if you use it with adaptiveHeight together...

var slickSlide = el.find('.slick-slide');
if (slickSlide.filter('.slick-active').length > 1) {
slickSlide.css('height', 'auto').css('height', el.find('.slick-track').height() + 'px');
}

@ramonleenders

This comment has been minimized.

Copy link

ramonleenders commented Apr 26, 2017

Would be nice if a JS solution will be provided within the plugin itself. That way we don't need to search for workarounds NOR write the CSS. Only a boolean in the config and done.

@artursopelnik: the code you provide is working or it isn't? Not sure if you are asking or just suggesting code here haha. And if it does work, it also still works when adaptiveHeight is set to false?

@giovannibr

This comment has been minimized.

Copy link

giovannibr commented Jul 25, 2017

Cmon @kenwheeler , it could be done just adding:
_.$slideTrack.height(_.$slideTrack.outerHeight());
Inside your Slick.prototype.setDimensions function.
Once the parent (track) has a defined height, the children (slides) already have the property height to 100%, and it works like charm.
Maybe you can create a property "fixedHeight" that only works with "adaptativeHeight" false.

@drducmanh

This comment has been minimized.

Copy link

drducmanh commented Dec 12, 2017

I use litle css to equal height.
"align-items:stretch" property apply to parent

.slick-track{
    display: flex;
     align-items: stretch; 
     justify-content: center;
    .slick-slide{
        height: auto;       
    }
}

readmore about flexbox here https://css-tricks.com/snippets/css/a-guide-to-flexbox/

@pjatx

This comment has been minimized.

Copy link

pjatx commented Dec 30, 2017

@ramonleenders Thanks! Using a complex flexbox layout and the pure CSS solutions just blowup my slides.

@verybigelephants

This comment has been minimized.

Copy link

verybigelephants commented Jan 24, 2018

so will there be an option for this or no?

this is definitely a real word scenario that appears over and over

btw this is nice, but you have to include it in the resize function as well https://gist.github.com/proweb/7c872c02646659e45084c1d51dfc3018

@LMBE

This comment has been minimized.

Copy link

LMBE commented Jan 24, 2018

Hi all, it's me, the okay guy from 2014 and original poster.

After years of using this great plugin and seeing people revisit this post I thought I'd chime back in.

The reality is that Ken adding an equalize heights option to the plugin is an overhead that could be better integrated elsewhere in your code. Instead, setup a global function you can use umpteen times over on different modules and save yourselves some kb's. If you're using foundation use the data-equalize attributes, if you want something more custom try something like this.

After that add a little flexbox spice to your content to vertically align anything you might have inside your banner and the jobs a gooden.

Keep up the great work @kenwheeler I've used this hundreds of times now and it's never let me down

@UnionDesign

This comment has been minimized.

Copy link

UnionDesign commented Feb 14, 2018

If you're just trying to vertically centre the slides with each other maybe they don't need to be equal height... maybe all you need it this:

.slick-track { display: flex; align-items: center; }

@raffi-ecomz

This comment has been minimized.

Copy link

raffi-ecomz commented Mar 22, 2018

i'm using adaptive height and have a bootstrap collapse element inside a slide.
when the element expands the slick isn't changing its height to the new one so only a part of the element is visible.
how can i make the whole element be visible?

@Preen

This comment has been minimized.

Copy link

Preen commented Apr 11, 2018

I used https://www.npmjs.com/package/jquery-match-height and solved it with the help of @ramonleenders code:

$(el).on('setPosition', function () {
    $(el).find('.slick-slide').matchHeight();
})
@karbecker

This comment has been minimized.

Copy link

karbecker commented May 15, 2018

Hi @Preen could you help me out where to insert https://www.npmjs.com/package/jquery-match-height and @ramonleenders code? I’m trying to archive equal height for all slides using SlickSlider in Wordpress (https://de.wordpress.org/plugins/slick-slider/).

Thanks for your help!

@flewid-cd

This comment has been minimized.

Copy link

flewid-cd commented May 15, 2018

@karbecker You need to write the above code but I guess that if you use a plugin it might have its own actions on when/where to trigger and initialize slick-slider. So I would ditch that plugin and just use slick manually with jquery match height.

@karbecker

This comment has been minimized.

Copy link

karbecker commented May 16, 2018

Thanks @flewid-cd! That’s true, the plugin acts as a wrapper to load slick-slider. Will try to use it manually.

@jschaefer-workmatrix

This comment has been minimized.

Copy link

jschaefer-workmatrix commented Jun 5, 2018

If you are using griddy slick slider (I am using a responsive setup w/ variable grids calculated by slide count via slidesPerRow) the following may help:

$.fn.equalHeightSlickSlider = function() {
	var
		$slider = $(this),
		$slides = $('.slick-slide', $slider),
		$slideitems = $('> div', $slides),
		slideCount = $slides.first().find('> div').length,
		slideHeight = 0
	;

	console.log(slideHeight);

	$slides.each(function(){
		slideHeight = Math.max($(this).outerHeight(), slideHeight); 
		slideCount = Math.max(slideCount, $(this).children().length);
	});

	$slideitems.height(slideHeight / slideCount);		

	return $(this);
}

var $slider = $('.slick-slider');

var equalizeSliderHeights = function(){

  var
  frequency = 250,
  	timeout = false
  	;

  return function() {
    if (timeout) {
      return;
    }

    timeout = setTimeout(function() {
      timeout = false;
    }, frequency);

    $slider.equalHeightSlickSlider();
  };
};

$(window).on('DOMContentLoaded load resize', equalizeSliderHeights());	

Inspired by @akrawchyk (thanks).

Can also by found here: https://gist.github.com/jschaefer-workmatrix/346ec9f1c6fae6e12408b060a5ed0eb1

@maketroli

This comment has been minimized.

Copy link

maketroli commented Aug 30, 2018

I use a function someone mentioned above and it works cool:

    var handleEqualHeightSlides = function () {
        var slickTrackHeight = $('.slick-track').height();
        $('.slick-slide').css('height', slickTrackHeight  + 'px' );
    }

And if you want to call it on resize or orientation change, there you go:

    var handleEqualHeightSlides = function () {
        var slickTrackHeight = $('.slick-track').height();
        $('.slick-slide').css('height', slickTrackHeight  + 'px' );
    };

    var reInitSlickOnResize = function () {
        $slick.slick('resize');
        handleEqualHeightSlides();
    };

    $(window).on('resize orientationchange', reInitSlickOnResize);
@JurajVajda

This comment has been minimized.

Copy link

JurajVajda commented Sep 25, 2018

The flexbox solution doesn't work in Edge, also some vanilla JS solution would be nice - if still anyone knows what that is :)

@mikemfleming

This comment has been minimized.

Copy link

mikemfleming commented Dec 11, 2018

@JurajVajda here is how i would go about a vanilla solution. It's definitely missing something in the makeEqualHeight function because the carousel seems to resize itself. But it's basically how I would go about it.

    var productCarousel = document.getElementById('productCarousel')
    var productCarouselHeight = productCarousel.offsetHeight
    var productCarouselSlides = Array.prototype.slice.call(
        document.getElementsByClassName('productCarousel-slide')
    )

    productCarouselSlides.forEach(makeEqualHeight)

    function makeEqualHeight (element) {
        element.style.height = `${productCarouselHeight}px`
    }
@JurajVajda

This comment has been minimized.

Copy link

JurajVajda commented Dec 13, 2018

Thanks..ended up using Es6 Js class for it in the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment