Skip to content

Add an option to not always choose the shortest column. - #811

Open
dwilmer wants to merge 16 commits into
desandro:masterfrom
dwilmer:fuzzy-minimum
Open

dwilmer wants to merge 16 commits into
desandro:masterfrom
dwilmer:fuzzy-minimum

Conversation

@dwilmer

@dwilmer dwilmer commented Jan 27, 2016

Copy link
Copy Markdown

[@desandro edit: added text from #810 below]

This is a feature request to change the positioning algorithm. Currently, the algorithm works as follows:

  1. select the height of the shortest column
  2. Select the leftmost (or rightmost) column of the columns with that height.

I would like to propose another algorithm:

  1. Select the height of the shortest column
  2. Select the leftmost (or rightmost) column of the columns with height <= (min_height + e), where e is a small value which the user can set, for example three pixels.

An example where this use case would be nice, can be seen here: http://codepen.io/anon/pen/JGLQVp
In this example, the slightly larger box on the left causes the box on the next line to be positioned in the middle column, while a position in the left column would be more visually pleasing — especially since the small height difference between the columns is not noticeable, due to the gutters and margin.


As explained in issue #810 , I would like to see an element positioned in a column that is slightly longer than the shortest column, if that is more to the left.

I wrote an implementation in this pull request. It adds the option maxColumnHeightDifference. If this option is set and greater than zero, the first column with minimum height + this difference is chosen instead of the column with the minimum height.

Any feedback is welcome :)

@desandro

desandro commented Feb 1, 2016

Copy link
Copy Markdown
Owner

Wow, thanks so much for this contribution. This is a great feature as it resolves a pain point users have voiced: Masonry breaking horizontal order when there's a difference of 1 or 2 pixels. And it doesn't change the algorithm all that much, only looks out for the edge case.

I'd like to keep this PR open for a while to see other's interest in the feature. It's good, but I'm hesitant with changing Masonry base algorithm that's been in use for years.

Thanks again!


+1 or add 👍 reaction for this issue if you'd like to see this feature merged into Masonry.

+ ⬆️ Outlayer v2.1.0 for stagger option
+ 📦 ^ dependencies
+ 📝 README.mdown -> .md
+ 🛠 Fix vendor CSS properties. Fixes desandro#834
+ 🍹 Fix gulp version task
@anthonyjburch

Copy link
Copy Markdown

I looked for a long time how to solve this problem before it dawned on me to look at the pull requests. So glad I finally found it! I did find that it breaks things slightly however without changing line 129 to

var setHeight = colGroup[shortColIndex] + item.size.outerHeight;

Conflicts:
	dist/masonry.pkgd.min.js
@rosieleung

Copy link
Copy Markdown

In case anyone else stumbles on this trying to implement something similar, here's an example with updated code for masonry-layout 4.2.2: https://codepen.io/rosieleung/pen/bGKMZoy

oriolj added a commit to oriolj/masonry-pretext that referenced this pull request Apr 8, 2026
CLOSES desandro#811 (10 reactions, open since 2017).

NEW `pickColumn(colGroup) → index` option that lets users override the
default leftmost-shortest column-pick strategy. Common alternatives:
  - Rightmost shortest
  - Round-robin (counter closure)
  - Random
  - Content-aware (read item dataset/class)

The callback receives the colGroup array (Y values for each valid
horizontal position) and returns the chosen index. Default behavior
is preserved exactly when the option is unset.

ALSO accepted by Masonry.computeLayout — server and client share the
same picker logic for SSR / pure-Node usage.

NEW indexOfMin helper replaces the previous Math.min.apply + indexOf
two-pass pattern with a single-pass loop. Bonus perf win on the
layout hot path.

DISCRIMINATING FIXTURE: test/visual/pages/pick-column.html
  4 items in a 3-col 180px container with a RIGHTMOST-shortest picker.
  Items walk right-to-left because every tie resolves to the highest
  index — opposite of the default leftmost picker. Item 0 lands at
  left=120 (col 2) instead of left=0 (col 0).

  +163 B raw / +46 B gz / +33 B brotli on dist/masonry.pkgd.min.js
  12/12 visual + 9/9 compute-layout + 4 gates green
  -201 B gz vs upstream-frozen v4.2.2 (still 2.73% smaller)

Full record: improvements/032-column-pick-strategy.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants