Simple masonry layout in 50 lines of Elm code

Lucamug
4 min readNov 24, 2019

Demo: http://elm-masonry.surge.sh/

Code: https://github.com/lucamug/elm-masonry/

The end result. With some extra code is possible to make the Masonry layout responsive

A Masonry layout is a way to fit together elements of possibly different sizes without gaps.

There are many different way to implement masonry layout, using CSS and/or Javascript. It is a kind of bin packing problem.

The method that we will use in this exercise is simple. Adding elements from left to right in a set of columns. Each element is added in the column that has shorter height.

Let’s start digging in the code. We want to transform a list of heights into a two dimensional matrix that represent the columns of the final layout:

So from this data:

items = [ 250, 200, 300, 200, 450, 200, 300, 500, 300, 250, 200, 150, 200 ]
columns = 4

to this matrix:

[ [ (11, 150 ), ( 8, 300 ), ( 5, 200 ), ( 3, 200 ) ]    X
, [ ( 7, 500 ), ( 2, 300 ) ] ^
, [ (10, 200 ), ( 4, 450 ), ( 1, 200 ) ] │
, [ (12, 200 ), ( 9, 250 ), ( 6, 300 ), ( 0, 250 ) ] │
] │
Y <───────────┼

That will show up flipped on screen:

╔════════════════════════════════════════════════════╗
║ ( 0, 250 ) ( 1, 200 ) ( 2, 300 ) ( 3, 200 ) ║
║ ( 6, 300 ) ( 4, 450 ) ( 7, 500 ) ( 5, 200 ) ║
║ ( 9, 250 ) ( 10, 200 ) ( 8, 300 ) ║
║ ( 12, 200 ) ( 11, 150 ) ║
╚════════════════════════════════════════════════════╝

the first value of the tuples in the matrix is the position in the initial list, the second is the height.

Note that the matrix is filled from the bottom right with element 0 and that rows in the matrix will be columns in the layout.

The idea is that each item will be added to the matrix row that has a smaller value, where the value is the sum of all items already present in the row.

--

--