Skip to content

Instantly share code, notes, and snippets.

@c6p
Last active January 11, 2026 06:50
Show Gist options
  • Select an option

  • Save c6p/463892bb243f611f2a3cfa4268c6435e to your computer and use it in GitHub Desktop.

Select an option

Save c6p/463892bb243f611f2a3cfa4268c6435e to your computer and use it in GitHub Desktop.
Reddit Multi Column
// ==UserScript==
// @name Reddit Multi Column
// @namespace https://gist.github.com/c6p/463892bb243f611f2a3cfa4268c6435e
// @version 0.2.6
// @description Multi column layout for reddit redesign
// @author Can Altıparmak
// @homepageURL https://gist.github.com/c6p/463892bb243f611f2a3cfa4268c6435e
// @match https://www.reddit.com/*
// @match https://new.reddit.com/*
// @grant none
// @downloadURL https://update.greasyfork.org/scripts/371490/Reddit%20Multi%20Column.user.js
// @updateURL https://update.greasyfork.org/scripts/371490/Reddit%20Multi%20Column.meta.js
// ==/UserScript==
/* jshint esversion: 6 */
(function() {
'use strict';
const MIN_WIDTH = 400;
const COLUMNS = 4;
let columns = COLUMNS;
let cleanup = null;
let parent = null;
const cardIcon = () => document?.querySelector('shreddit-sort-dropdown[header-text="View"]')?.shadowRoot?.querySelector('svg');
const shouldClean =(icon) => icon === undefined ? false : icon.getAttribute('icon-name') !== "view-card-outline";
cleanup = shouldClean()
let postMap = new Map()
const indexOfSmallest = function (a) {
let lowest = 0;
for (let i = 1; i<a.length; i++) {
if (a[i] < (a[lowest]-1)) lowest = i;
}
return lowest;
};
const makeLayout = function(changes=[]) {
if (cleanup) return;
if (!parent) return;
if (parent.style.position !== "relative") {
document.querySelector("main").style.maxWidth = "100%";
const mainContainer = document.querySelector("div.main-container");
mainContainer.className = [...mainContainer.classList].filter(c => !c.includes(":grid-cols-")).join(" ") // make wide
document.querySelector("div.subgrid-container").classList.remove("m:w-[1120px]") // make wide
document.getElementById("right-sidebar-container").style.display = "none" // hide sidebar
parent.style.position = "relative"
}
const cols = Math.floor(parent.offsetWidth / MIN_WIDTH);
columns = cols;
const WIDTH = Math.floor((100-columns)/columns);
const nodes = [...parent.querySelectorAll("article, shreddit-ad-post, faceplate-partial").values()]
for (const article of nodes) {
const key = article.ariaLabel
if (key === null) /* faceplate-partial */ {
} else if (key in postMap) {
const post = postMap[key]
if (post.height !== article.offsetHeight) {
post.height = article.offsetHeight
}
} else {
postMap.set(key, {height:article.offsetHeight, col:0, top:0})
}
}
let tops = Array(columns).fill(0);
for (const post of postMap.values()) {
post.col = indexOfSmallest(tops)
post.top = tops[post.col]
tops[post.col] += post.height
}
const height = Math.max(...tops)
if (height) {
parent.style.height = height + 500 + "px"
}
for (const article of nodes) {
const key = article.ariaLabel
const {col, top} = postMap.get(key) ?? {col:0, top:tops[0]}
article.setAttribute("style", cleanup ? "" : `position:absolute; width:${WIDTH}%; top:${top}px; left:${col*(WIDTH+1)}%`)
}
for (const batch of parent.querySelectorAll("faceplate-batch").values()) {
if (!batch.style.height) {
batch.style.height = [...batch.childNodes].reduce((height,c) => height + c.clientHeight, 0) + "px"
}
}
};
const setLayout = function(changes, observer) {
const c = shouldClean(cardIcon());
if (c !== cleanup) {
cleanup = c;
window.requestAnimationFrame(makeLayout)
}
};
const requestLayout = () => window.requestAnimationFrame(makeLayout)
const pageChange = new MutationObserver(requestLayout);
window.addEventListener('resize', requestLayout);
window.addEventListener('scrollend', requestLayout);
const layoutSwitch = new MutationObserver(setLayout);
const watch = function(changes, observer) {
postMap = new Map()
parent = document.querySelector("article + hr + faceplate-partial").parentNode
if (parent === null) return;
pageChange.observe(parent, {childList: true});
const timeout = setTimeout(() => {
const icon = cardIcon();
if (icon !== undefined) {
clearTimeout(timeout);
layoutSwitch.observe(icon, {attributes: true});
}
})
window.requestAnimationFrame(makeLayout);
};
const apply = new MutationObserver(watch);
const app = document.querySelector("shreddit-app")
apply.observe(app, {attributes: true});
watch();
})();
@Krokette
Copy link

it doesn't seem to work anymore. Is there a fix for it ?

@drhouse
Copy link

drhouse commented Apr 29, 2024

it doesn't seem to work anymore. Is there a fix for it ?

I started using this userscript Reddit 2023 Ui Revert to forward www.reddit.com to new.reddit.com, then add:
// @match https://new.reddit.com/*
to the top of Reddit Multi Column script and it will work again

@c6p
Copy link
Author

c6p commented May 29, 2024

@Krokette @drhouse I've updated it to work with the latest Reddit design. Hopefully, it works now.

Sorry for the late fix. Recently, I've been on a metered connection and have had trouble finding the time.

@drhouse
Copy link

drhouse commented May 30, 2024

@c6p good job on the update, I installed it from Greasyfork

@Krokette
Copy link

Krokette commented Jun 12, 2024

@c6p Awesome ! Thank you, the design is pretty neat ! And the performance seems to be better than before ♥

@lolDayus
Copy link

lolDayus commented Jul 2, 2024

Hey this might just be a "me" thing but this is so close to doing what I want BUT I'm having this issue where, as I scroll down my feed, each post will swap places around on the screen so that one second a post is in the right column and then the next it's in center (I have 3 columns). This gets confusing very quickly with how often they switch places, in that I'll see a post I want to click but by the time the page "settles" it'll be shifted to a different part of the page. any ideas?

@drhouse
Copy link

drhouse commented Jul 2, 2024

as I scroll down my feed, each post will swap places around on the screen so that one second a post is in the right column and then the next it's in center (I have 3 columns).

+1 having same issue

@c6p
Copy link
Author

c6p commented Jul 3, 2024

@lolDayus @drhouse noted. While threads are coming, it re-layouts. But since some thread images are not yet loaded, their height changes. So does their position.

When I have the time, I'm going to try to wait until a thread's content is loaded, to make the layout more stable. Or just keep their assigned rows and columns, even if it makes some columns longer than others.

@c6p
Copy link
Author

c6p commented Sep 11, 2024

v0.2.1released

  • Add new.reddit.com
  • Fix left sidebar scrolling
  • Fix article jumpiness

@c6p
Copy link
Author

c6p commented Sep 12, 2024

v0.2.2 released

  • Fix subreddits that use faceplate-batch elements to virtualize loaded articles

@c6p
Copy link
Author

c6p commented Sep 13, 2024

v0.2.3

  • Fix empty page due to reddit hiding too far away articles
    • Fixed: unbalanced columns

@Archer2011
Copy link

Doesn't work anymore

@thepick
Copy link

thepick commented Jan 12, 2025

Doesn't work anymore

Yeah, I think there was an update on Reddit's end. It doesn't work across all browsers now.

@c6p
Copy link
Author

c6p commented Jan 12, 2025

v0.2.4

  • Fix: update main element type

@DannL444
Copy link

DannL444 commented Feb 5, 2025

It stopped working

@thepick
Copy link

thepick commented Feb 6, 2025

It seems to be working well in Chrome-based browsers now, but not on Firefox-based browsers. Switching from Violentmonkey to Tampermonkey didn't help.

@c6p
Copy link
Author

c6p commented Apr 8, 2025

v0.2.5

  • Fix: filter-out :grid-col- classes from main-container to make it wide

@c6p
Copy link
Author

c6p commented Apr 8, 2025

v0.2.6

  • Fix: ads breaking column layout

@gameont
Copy link

gameont commented Jan 11, 2026

When in a feed and then pressing the back arrow next to the subreddit name to go back, the scroll position on the home page is lost. Using the Reddit app and website without this script, pressing the back button returns the user to the same scroll position. Is there a way to remember scroll position?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment