JSFiddle - React, Tailwind, and code Playground
HTML
<div id="outputarea">
</div>
CSS
.cube {
height: 50px;
width: 50px;
border: 2px solid #000;
margin-bottom: 10px;
display: inline-block;
vertical-align: top;
text-align: center;
}
.cube + .cube {
margin-left: 10px;
}
.row {
clear: both;
}
JavaScript
// массив вывода, в демонстрационных целях
var output = [];
// исходный массив
var array = ['1','2','3','4','5','6','7','8','9','10','11','12'];
// ширина матрицы, кол-во элементов в строку
var perRow = 3;
// остальные переменные
var itemsCount = array.length;
var height = Math.ceil(itemsCount / perRow); // высота матрицы
// модификаторы остатка для коррекции порядкового индекса в последнем столбце
var leaster = Math.floor(itemsCount / height);
var greater = Math.ceil(itemsCount / height);
// просто счетчик
var counter = 0;
// инкрементор, используется для коррекции индекса в столбцах
var incrementor;
// Цикл по строкам
for(var rows = 0; rows < height; rows++) {
incrementor = 0;
// Цикл по столбцам
for(var cols = 0; cols < perRow; cols++) {
// По умолчанию индекс - текущая строка + 1
// Актуально для первого столбца
var index = rows + 1;
// Для всех прочих столбцов вычисляем индекс со смещением
if(cols > 0) index = rows + 1 + incrementor;
// Проверка модификаторов остатка
// Если условие выполняется, значит, в каком-либо
// из столбцов меньше строк, чем в других
// Тогда нужно уменьшить index на единицу.
if(cols === perRow - 1 && greater > leaster) {
index--;
}
output.push('<div class="cube">' + index + '</div>');
// После каждого прохода, увеличиваем index на максимальную высота
// матрицы, чтобы в следующей итерации получить корректное значение
incrementor += height;
counter++;
// если счетчик достиг максимального количества элементов, выходим
if(counter >= itemsCount) {
break;
}
}
output.push('</div><div class="row">');
}
// output
var outputarea = document.getElementById('outputarea');
outputarea.innerHTML = output.join('');