packery icon indicating copy to clipboard operation
packery copied to clipboard

Centered Layout

Open davidmerrique opened this issue 12 years ago • 25 comments

Are there any plans to add a "centered" option? Like the "Centered Masonry" in Isotope?

http://isotope.metafizzy.co/custom-layout-modes/centered-masonry.html

That's the only thing that's missing for me right now.

davidmerrique avatar Apr 16 '13 18:04 davidmerrique

Nope. If you want to center your layout, you can just do that with your own CSS.

http://codepen.io/desandro/pen/xEzKo

This feature made sense if you use explicit widths for columns. But with Packery, columns can be fluid. Most likely, this feature will be removed from Isotope and from Masonry.

desandro avatar Apr 16 '13 21:04 desandro

Sorry for responding to a closed issue, but I wonder what the rationale behind abandoning the isFitWidth feature in Masonry is.

You're right that CSS can be used with fluid columns, but what about fixed size columns? At the moment, the only solution that comes to mind in order to remove surplus space is to use a lot of css media queries to resize the container in correspondence to the number or columns. This seems a bit cumbersome.

jnns avatar Apr 22 '13 10:04 jnns

I'm happy to keep this discussion going :wind_chime:

what the rationale behind abandoning the isFitWidth feature in Masonry is

  1. isFitWidth will not work with element sizing because of circular logic with percentage width columns.
  2. I could add isFitWidth feature and then add a disclaimer that it only works with fixed-sized columns. But I see this as more problematic than just removing the feature all together.

If you do need isFitWidth, you can implement it with some JS. See http://codepen.io/desandro/pen/chisC

desandro avatar Apr 22 '13 11:04 desandro

Thank you very much for the quick response, David.

I see your point. Your JS solution is really nice; maybe you can link to your codepen snippet in the docs once you remove the feature.

jnns avatar Apr 22 '13 12:04 jnns

Thanks for the JS solution for fixed elements.

ScotterC avatar May 15 '13 14:05 ScotterC

I note on first loading the page in your example, http://codepen.io/desandro/pen/chisC , the items are not centered initially but do center when the window size is changed slightly. I see this in Firefox 22 on Mac and Windows.

macsupport avatar Jun 04 '13 16:06 macsupport

Good catch. I've updated it with a missing onResize()

http://codepen.io/desandro/pen/chisC

desandro avatar Jun 04 '13 17:06 desandro

Hi, does this centered fix work with jquery packery objects?

squidis avatar Jun 27 '13 09:06 squidis

Here's the example using jQuery http://codepen.io/desandro/pen/nfkth

desandro avatar Jun 27 '13 11:06 desandro

Thanks for the fix, took me a while but I have it working.

squidis avatar Jun 28 '13 15:06 squidis

In case anyone stumbles on this looking for centered layout issues. Here's a codepen using a 960px container with 4 columns and 4 different box sizes.

http://codepen.io/anon/pen/bBAiw

markgarrigan avatar Jul 31 '13 17:07 markgarrigan

Thinking of adding isFitWidth to Packery.

desandro avatar Sep 04 '13 01:09 desandro

Hi desandro, thanks for your excellent work with your packery script. I've found a bug in the function _getContainerSize in case you want to center the container under certain conditions. Consider this codepen

http://codepen.io/anon/pen/GFsEy

As you can see, if there is an empty space at y = 0 that can't be filled with any element, the function fails and the container is shrinked, I suggest to modify the function _getContainerSize like this:

Packery.prototype._getContainerSize = function() {
  // remove empty space from fit width
  var emptyWidth = 0;
  var maxFill = 0;
  for ( var i=0, len = this.items.length; i < len; i++ ) {
    var item = this.items[i];
    if((item.position.x + item.rect.width) > maxFill) {
        maxFill = item.position.x + item.rect.width;
    }
  }
  for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
    var space = this.packer.spaces[i];
    if ( space.y === 0 && space.x > maxFill) {
      emptyWidth += space.width;
    }
  }

  return {
    width: this.fitWidth - emptyWidth - this.gutter,
    height: this.maxY - this.gutter
  };
};

marcotisi avatar Apr 01 '14 15:04 marcotisi

Hi @mtisi! Thanks for catching this a bug. I believe this was a problem with not factoring in gutter. I've refactored the code.

Here's your example http://codepen.io/desandro/pen/kbchD

The previous examples have been updated.

  • jQuery http://codepen.io/desandro/pen/nfkth
  • vanilla JS http://codepen.io/desandro/pen/chisC

desandro avatar Apr 01 '14 23:04 desandro

May i suggest this slight alteration/addition so that it will stay centered even when there are not enough items to fill a full width row
At the end of the Packery.prototype._getContainerSize method

var itemsWidth = 0;
$.each(this.items, function(idx,item){itemsWidth += item.rect.width}); 
return {
  width: Math.min(itemsWidth, this.fitWidth - this.gutter),
  height: this.maxY - this.gutter
};

Demo at http://codepen.io/gpetrioli/pen/oaqbI

gpetrioli avatar Jul 01 '14 12:07 gpetrioli

I think the CodePen has a regression in the _getContainerSize function. The emptyWidth variable is calculated but never used. I think it should be:

Packery.prototype._getContainerSize = function() {
  // remove empty space from fit width
  var emptyWidth = 0;
  for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
    var space = this.packer.spaces[i];
    if ( space.y === 0 && space.height === Number.POSITIVE_INFINITY ) {
      emptyWidth += space.width;
    }
  }

  return {
    width: this.fitWidth - this.gutter - emptyWidth,
    height: this.maxY - this.gutter
  };
};

At least that's what makes it work correctly for the project I'm working on.

jkrehm avatar Oct 30 '14 17:10 jkrehm

@jkrehm Thanks! I've updated the CodePen http://codepen.io/desandro/pen/chisC

desandro avatar Oct 31 '14 15:10 desandro

@desandro Thanks a lot for this brilliant work with packery script, it's magic :) I have a question about isotope+packery centering. Is it possible to merge this js http://codepen.io/desandro/pen/chisC and packery-mode.pkgd.min.js (not packery.pkgd.js) right? Because it's not working together.

voltmn avatar Mar 02 '15 16:03 voltmn

@voltmn Sure thing. Use this CodePen: http://codepen.io/desandro/pen/wBxvKe

// overwrite Packery methods
var PackeryMode = Isotope.LayoutMode.modes.packery;
var __resetLayout = PackeryMode.prototype._resetLayout;
PackeryMode.prototype._resetLayout = function() {
  __resetLayout.call( this );
  // reset packer
  var parentSize = getSize( this.element.parentNode );
  var colW = this.columnWidth + this.gutter;
  this.fitWidth = Math.floor( ( parentSize.innerWidth + this.gutter ) / colW ) * colW;
  this.packer.width = this.fitWidth;
  this.packer.height = Number.POSITIVE_INFINITY;
  this.packer.reset();
};

PackeryMode.prototype._getContainerSize = function() {
  // remove empty space from fit width
  var emptyWidth = 0;
  for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
    var space = this.packer.spaces[i];
    if ( space.y === 0 && space.height === Number.POSITIVE_INFINITY ) {
      emptyWidth += space.width;
    }
  }

  return {
    width: this.fitWidth - this.gutter,
    height: this.maxY - this.gutter
  };
};

// always resize
PackeryMode.prototype.needsResizeLayout = function() {
  return true;
};

desandro avatar Mar 02 '15 17:03 desandro

Wow, so easy! Thanks!

voltmn avatar Mar 02 '15 17:03 voltmn

I tried to use that hack, but it looks like Packery.prototype.resize does not call the .needsResizeLayout() method defined in Outlayer. Hence, overriding Packery.prototype.needsResizeLayout as done is the CodePen does not work : the function simply does not get called.

As a result, the layout resize does not always happen because the return in Packery.prototype.resize acts as a shortcircuit. I hope my explanations are clear enough. Do you see a way to solve this issue ?

Also, are you still considering to implement that behaviour as a functionality of Packery ? Because else such a hack will be difficult to maintain as Packery's code evolve.

Lucas-C avatar Apr 21 '15 12:04 Lucas-C

I could add isFitWidth feature and then add a disclaimer that it only works with fixed-sized columns. But I see this as more problematic than just removing the feature all together.

I disagree with this, a functioning integrated option that doesn't work in a situation thats in the documentation, thats fine.

Currently am using isotope via a vue wrapper and can't get you js solutions working via that.

n8-dev avatar Sep 08 '17 01:09 n8-dev

+1

sometimes things just need to be centered :)

Struggling to get the codepen examples working, but I'm sure i'll get there eventually...

NBurke1 avatar Feb 09 '18 13:02 NBurke1

Unfortunately, none of these examples is working properly. As soon as you put a max-width in the container, it blows

xe4me avatar Jun 05 '19 04:06 xe4me

At present, web site(https://packery.metafizzy.co/extras)'s pointed solution (https://codepen.io/desandro/pen/chisC) works only fixed width.

This hack worked nice for me:

  • css:
:root{
  --card-width: 25vw;
  --card-height: calc(var(--card-width) * 1.5);
}
#template_item{
  width: var(--card-width);
  height: var(--card-height);
  display: none;
}
  • html
<div id="template_item"></div>
  • javascript (at initializtion of pckry)
...
columnWidth: document.getElementById("template_item").style.pixelWidth,
....

tolgaulas avatar Jun 24 '24 19:06 tolgaulas