Skip to content

Instantly share code, notes, and snippets.

@NateScarlet
Last active July 6, 2022 04:09
Show Gist options
  • Save NateScarlet/74080c11386edb98fc8130a152a7a9a8 to your computer and use it in GitHub Desktop.
Save NateScarlet/74080c11386edb98fc8130a152a7a9a8 to your computer and use it in GitHub Desktop.
export default function doWaterfallLayout({
container,
columnWidth,
selector = ':scope > *',
}: {
container: HTMLElement;
selector?: string;
columnWidth: number;
}): void {
const columnCount = Math.max(
1,
Math.floor(
(container.parentElement ?? document.body).clientWidth / columnWidth
)
);
const columns = Array(columnCount)
.fill(undefined)
.map((_, index) => {
return {
index,
bottom: 0,
};
});
const shortestColumn = () => {
let ret = columns[0]!;
columns.forEach((i) => {
if (i.bottom < ret.bottom) {
ret = i;
}
});
return ret;
};
container.querySelectorAll(selector).forEach((el) => {
if (!(el instanceof HTMLElement)) {
return;
}
const col = shortestColumn();
const { clientHeight } = el;
el.style.position = 'absolute';
el.style.left = `${columnWidth * col.index}px`;
el.style.top = `${col.bottom}px`;
el.style.width = `${columnWidth}px`;
col.bottom += clientHeight;
});
container.style.position = 'relative';
container.style.width = `${columnCount * columnWidth}px`;
container.style.height = `${Math.max(...columns.map((i) => i.bottom))}px`;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment