flickity icon indicating copy to clipboard operation
flickity copied to clipboard

Equal height cells

Open illycz opened this issue 7 years ago • 47 comments

Test case: http://codepen.io/illycz/pen/yMEvoG

How to make all cells equal height? I tried solutions with gallerySize true and false too, but I can't figure it out.

A need solution which working in responsive fluid layout... I also change number of "visible" cells.

Thanks

illycz avatar Mar 24 '17 12:03 illycz

Hmm, I'm afraid this sort of layout is not possible with Flickity. It looks like it's best achieved with flex box CSS, but flex box is not compatible with Flickity. I'm sorry I cannot provide a good solution here.

desandro avatar Mar 24 '17 13:03 desandro

Hm, that's sad... I think that product carousel within equal height boxes is common requirement, no?

illycz avatar Mar 24 '17 16:03 illycz

try adding: .carousel-cell {min-height:100%}

I haven't tested it across absolutely every browser but it works on the most common ones. It should work since it's in a parent element with a height.

eldub2001 avatar Mar 30 '17 21:03 eldub2001

@eldub2001 thanks, I'll try...

illycz avatar Mar 30 '17 22:03 illycz

@eldub2001 not working for me :(

illycz avatar Apr 03 '17 12:04 illycz

I'm struggling with this as well. Adding height: 100%; works if done in the browser after render, but it results in the parent collapsing to zero height if done in the stylesheet.

I was hoping for an initial render callback, on which I could set the slide height, but no luck there either.

isherwood avatar May 05 '17 15:05 isherwood

@isherwood Running into the same issue, bummer.

alexcarpenter avatar Jun 09 '17 18:06 alexcarpenter

Try this:

.carousel-cell[style*='left'] {
  top: 0;
  bottom: 0;
}

or

.carousel-cell[style*='left'] {
  height: 100%;
}

dennisfrank avatar Jun 22 '17 23:06 dennisfrank

Hm, my solution isn’t fluid. The cells don’t resize vertically.

dennisfrank avatar Jun 22 '17 23:06 dennisfrank

For simple backgrounds you could add a very tall pseudo element:

.carousel-cell::before {
  content: "";
  position: absolute;
  z-index: -1;
  right: 0;
  left: 0;
  height: 1000vh;
  background: red;
}

dennisfrank avatar Jun 22 '17 23:06 dennisfrank

@desandro It would be cool if Flickity could add a special class (.flickity-ready) to the carousel element after initializing. This class should be removed while cells are being resized/repositioned and added back when finished.

I think this could be used as hook for different things. Like resizing all cells to the same height:

.flickity-ready .carousel-cell {
  height: 100%;
}

dennisfrank avatar Jun 22 '17 23:06 dennisfrank

I came across this one today as well. The min-height: 100% won't work because of the way the cell content is nested:

<div class="carousel-cell">
    <div class="Plan">
        ...
    </div>
</div>

The .Plan div won't grow to the height of the cell since min-height + a nested height.

I'm not seeing a clean way to add the height: 100% to each cell without relooping after it's active, but that's not fool proof if there are images inside the cell. I agree a flickity-ready or potentially an autoHeight configuration that would auto add the height: 100% to each cell after ready (since that's kind of the default expectation I think?). The autoHeight could even be off by default and set if the cell has a style height of 100%, like what's happening with display: none:

https://github.com/metafizzy/flickity/blob/c21fdfe6231535eb0ac98b90d81ba6593e167fb6/dist/flickity.pkgd.js#L423-L425

spentacular avatar Sep 11 '17 18:09 spentacular

@dennisfrank Thanks for idea. Here's my hacked solution demo

Flickity.prototype._createResizeClass = function() {
  this.element.classList.add('flickity-resize');
};

Flickity.createMethods.push('_createResizeClass');

var resize = Flickity.prototype.resize;
Flickity.prototype.resize = function() {
  this.element.classList.remove('flickity-resize');
  resize.call( this );
  this.element.classList.add('flickity-resize');
};
/* add this CSS */
.flickity-resize .carousel-cell {
  min-height: 100%;
}

This demo has been added to the Extra demos

desandro avatar Sep 12 '17 13:09 desandro

@desandro I'm still having some trouble on initial load with that one (but I don't think it was meant to fix it specifically).

The problem I keep circling back to is you can't use the flickity-enabled class to setup height: 100% because it comes a few lines before the cells are calculated and arranged:

https://github.com/metafizzy/flickity/blob/7491e020d35806ed99f6d4f590ae3d2c59c1b55e/dist/flickity.pkgd.js#L1321-L1339

Having a flickity-ready after that reloadCells would solve the problem I think?

spentacular avatar Sep 12 '17 18:09 spentacular

Still no solution for this problem? @desandro Your example doesn't work, because on initial load it is not added.

datune avatar Sep 28 '17 12:09 datune

@datune Updated code to fix the initial sizing.

desandro avatar Sep 28 '17 19:09 desandro

@desandro Thank you, much appreciated.

datune avatar Sep 30 '17 18:09 datune

Hello, this feature would be really useful in a number of applications. I have attempted to implement your hacked solution @desandro however it isn't working as expected for me. I can see the new class of .flickity-resize being added upon resize, however the min-height css has no effect? Has anything changed since the example was posted?

kaleidografik avatar Nov 07 '17 12:11 kaleidografik

This feature is pretty important... Unfortunately, the JS hack above isn't working for me using React. Please build this option into the library whenever you can (i.e. toggle equal height cells via a boolean setting).

ooloth avatar Nov 14 '17 22:11 ooloth

Where in the original file do you add the extra code? Its not picking it up

GiraffeCoding avatar Nov 15 '17 11:11 GiraffeCoding

Simple way to use flexbox for equal height columns: https://codepen.io/anon/pen/NMWOxW Probably won't work in some specific cases, but it might be that little stepping stone for Flickity to start implementing flexbox support ;)

joshas avatar Apr 18 '18 18:04 joshas

@joshas Nice work. But flex-box is likely incompatible with wrapAround. From https://github.com/metafizzy/flickity/issues/564#issuecomment-305039376

Having all items be position: absolute makes it easier to move them around for wrapAround behavior.

desandro avatar Apr 18 '18 19:04 desandro

I had trouble with the cell height when Flickity was initialised. Added a little setTimeout which fixed this:

Flickity.prototype._createResizeClass = function() {
    setTimeout(() => {
        $(this.element).addClass('flickity-resize');
    });
};

Flickity.createMethods.push('_createResizeClass');

const resize = Flickity.prototype.resize;

Flickity.prototype.resize = function() {
    const $element = $(this.element);

    $element.removeClass('flickity-resize');
    resize.call( this );
    $element.addClass('flickity-resize');
};

Happy about feedback. Hope this helps.

Looking forward to a non hacky solution. Maybe some new major version? 😁

lennerd avatar Jun 13 '18 14:06 lennerd

Having all items be position: absolute makes it easier to move them around for wrapAround behavior.

@desandro What about order?

lennerd avatar Jun 13 '18 14:06 lennerd

@lennerd Flickity uses absolute positioning. It's reliable and has a long history. From my perspective, there are too many unknowns and gotchas with switching over to flex box. If you're interested in re-hauling Flickity's layout behavior to use flex box, you can do so by forking the project.

desandro avatar Jun 14 '18 15:06 desandro

@desandro True. Run into many quircks myself with flexbox.

What about setting the height of the cells instead? Wouldn't that fix the problem somehow? Not as elegant as setting the height of the viewport, but maybe … an option of some sort?

Anyway. Great work you've done with flickity. Love the interactions and API of the library.

lennerd avatar Jun 14 '18 17:06 lennerd

@lennerd An interesting suggestion. I feel this could be done with the Flickity API. I'll leave implementation up to any adventurous developer.

desandro avatar Jun 15 '18 19:06 desandro

@desandro

The way I've done such things without flexbox is as follows:

On initialisation, take the height of the tallest slide, and then apply that height to all slides. And then on resize, all you need do is remove that set height such that they sit at their natural size again, and then repeat the same initialisation process.

It could exist as an option, such as equalHeight.

Pseudo-code:

if (this.options.equalHeight) {
    this.slides.forEach(slide => slide.style.height = '');
    
    let heights = this.slides.map(slide => slide.offsetHeight),
        max = Math.math.apply(Math, heights);
    
    this.slides.forEach(slide => slide.style.height = max + 'px');
}

That really is pretty simple, wherever that code would slip in, I'm not sure, I'm not familiar with the codebase.

CaelanStewart avatar Jun 28 '18 10:06 CaelanStewart

Flickity triggers an internal resize event (vanilla JS only) when its resize method is triggered. (It's not documented as I haven't seen that much use for it for users). You could use this event:

flkty.on( 'resize', function() {
    flkty.slides.forEach(slide => slide.style.height = '');
    
    let heights = flkty.slides.map(slide => slide.offsetHeight),
        max = Math.math.apply(Math, heights);
    
    flkty.slides.forEach(slide => slide.style.height = max + 'px');
});

desandro avatar Jun 29 '18 14:06 desandro

@desandro, that's great. Thank you for letting me know of that!

CaelanStewart avatar Jul 06 '18 15:07 CaelanStewart