JSFiddle - React, Tailwind, and code Playground
by Drath
HTML
<div>
<ul data-columns="4" data-selector="li" data-class="auto-column" data-column-element="ul" data-balance="true">
<li>Test #1</li>
<li>Test #2</li>
<li>Test #3
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
</ul>
</li>
<li>Test #4
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Really Long Sub Test Really Long Sub Test Really Long Sub Test</li>
</ul>
</li>
<li>Test #5
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
</ul>
</li>
<li>Test #6
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
</ul>
</li>
<li>Really Long Test Really Long Test Really Long Test #7
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
</ul>
</li>
<li>Test #8
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
</ul>
</li>
<li>Test #9</li>
<li>Test #10</li>
<li>Test #11
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
</ul>
</li>
<li>Really Long Test Really Long Test Really Long Test #12
<ul>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
<li>Sub Test</li>
...
CSS
.auto-column {
float: left;
width: 25%;
box-sizing: border-box;
}
JavaScript
var columnContainer = $('[data-columns]');
columnContainer.each(function () {
var columns = parseInt($(this).data('columns'), 10);
var selector = $(this).data('selector');
var className = $(this).data('class');
var columnElement = $(this).data('column-element');
var balance = $(this).data('balance');
var columnItems = $(this).children(selector)
var container = $(this).parent();
for (var i = 0; i < columns; i++) {
container.append('<' + columnElement + ' class="' + className + '"></ul>');
}
var columnCount = 0;
columnItems.each(function () {
var newHTML = $($(this)[0].outerHTML);
container.find('.' + className + ':eq(' + columnCount + ')').append(newHTML);
columnCount++;
if (columnCount >= columns) {
columnCount = 0;
}
});
var getAndSortHeights = function () {
var columnHeights = [];
for (var i = 0; i < columns; i++) {
columnHeights[i] = {
eq: i,
height: container.find('.' + className + ':eq(' + i + ')').outerHeight()
};
}
// Sort the columns from smallest to biggest
columnHeights.sort(function (a, b) {
return a.height - b.height;
});
return columnHeights;
}
// Are we trying to balance the height of the columns?
if (balance) {
var columnHeights = getAndSortHeights();
// Attempt to balance
for (var tries = columnHeights.length - 1; tries > 0; tries--) {
var newBiggestColumn = container.find('.' + className + ':eq(' + (columnHeights[columns - tries].eq) + ')');
newBiggestColumn.children(selector).each(function () {
var newSmallestColumn = container.find('.' + className + ':eq(' + columnHeights[0].eq + ')');
$(this).detach().appendTo(newSmallestColumn);
if (newSmallestColumn.outerHeight() >=...