clock menu more-arrow no yes mobile

Filed under:

Algorithmic design: How Vox picks a winning layout out of thousands

Vox was built in a relatively short amount of time, about nine weeks. Many of its features were borrowed from what already existed in Chorus  a module here, a component there. The plan was to launch as quickly as possible and add new stuff as we went along.

For the Vox team, perhaps one of the most sought-after feature was their own front page. We basically reused the SB Nation layout system  internally called "the river"  built in 2012 for the United project. The river had been battle tested for nearly two years on more than 300 of our sports blogs. So naturally it became the foundation from which we built the new Vox river to better fit the experience of the Vox brand.

Part of that experience is a different view as the day progresses. If you visit the Vox front page in the morning, an article may be nestled somewhere in the corner of the page. Come back at noon and that same article might span an entire row. Rarely will you see the same layout twice. The reason is because every layout is now algorithmically generated based on the content on the page.

A river runs through it

The original SB Nation river displays entries in a top-down, reverse-chronological fashion (or whatever ordering an editor specifies). Content flows around "rocks" and "breakers", which are modules such as a "Most Commented" list or a row of "Popular Videos". Many of these behaviors remain in the new layout system, but the key difference is an added contextual layer. Elements in the river are laid out to better highlight the diversity of content on Vox  articles, features, videos, editorial apps, card stacks, to name a few. Each one displays differently depending on its type and neighboring entries.

The basis for generating the new river can be broken down into three steps. The first is to find every possible layout that is valid. Next, each layout is examined and scored based on certain traits. And finally, the generator selects the "best" layout, basically the one with the highest score.

Step 1: Finding all layouts

The river is built on a responsive grid system that scales up to four columns. An article, for example, can use up to two columns. But a long feature is allowed more space, up to four, so we can show off its beautiful cover photo. For each entry type, we define a range that specifies how many columns it can occupy. The generator then finds all possible layouts based on one criteria: every column in each row must be filled.

For example, if you had three entries on a front page (imagine a tiny front page), a valid layout could be one where each entry spans four columns (creating three rows).

Or another layout could show the first two spanning two columns and the last spanning four (creating two rows). But the previous example would be invalid if the last entry spanned only three columns because there would be one unfilled column in its row.

The system generates thousands of layouts as it runs through all the possible permutations of occupiable columns.

Step 2: Scoring all layouts

Once we have a set of layouts, how do you pick the best one? This is when we deferred to our designers, who came up with a list of traits to look for. Here are some:

  • Give more points to layouts where features and videos take up a lot of space.
  • Adjacent rows that all look the same are ugly, so deduct points from those.
  • Asymmetry looks awesome, so give more points if adjacent rows are inverses of each other.
  • Some imbalance is aesthetically pleasing. Give points to layouts where one row with few entries is followed by another with many entries.

Step 3: Selecting a layout

The last step is the easiest: sort by score and choose the layout with the most points.

Although the steps are straightforward, the generator does a lot of calculations under the hood. Therefore, we employ a few techniques to make it run faster. One is to split the first step into several sub-problems. The front page usually contains around 25 entries at any given moment. It would take far too long to find the permutations for all 25 entries at once. Instead, we divide the entries into groups as if we were solving for many smaller layouts.

Another technique is caching. We cache the results and invalidate it only when something changes on the front page, such as when a new article is published or an editor reorders the entries.


Similar to the original river, the Vox version is responsive and optimized for different screen sizes. As previously mentioned, the layout grid is four columns at the widest breakpoint (e.g., desktop monitor) and one at the smallest (e.g., smartphone). The layout selected by the generator is the "best" only at the four-column breakpoint. We then use Javascript to rescale each row/column for smaller breakpoints. For example, a row containing a three-column feature and a one-column article will scale down to a two-column feature and one-column article at the three-column breakpoint.

Advertisements in the river

The river also contains advertisements, which the system treats like any other content type when generating a layout. But there are a few caveats regarding ads, specifically the inflexible dimensions and where it’s placed. We get around the first requirement by restricting the range of the ad to only one column. This way, a medium-rectangle banner, for instance, will never expand to more than a single column. Ad placement is slightly trickier. We may want the banner to appear only on the right side of the screen and nowhere else. To ensure this, we use Javascript for repositioning. However, it’s worth noting that we don’t actually reposition the ad but the content around it, instead. Because once an ad has rendered, performing DOM manipulation directly on it creates unwanted behaviors like creating tracking inaccuracies or causing the ad to disappear.

Well, that’s how the Vox front page works in a nutshell. It's been running in the wild for the past few months, and we're pretty happy with how it turned out. Sound like something you'd be interested in working on? Oh, hey look! We're also hiring.