Replacement for HTML tables on smaller devices

6 April 2023

In some cases classic table elemens that looks good on big screens could be implemented little different on mobile device resolutions - with little help of javascript and dynamic DOM manipulation

Sometimes it's hard show all content from HTML table on mobile devices in a way that it looks good an readable. There are already various methods for tables to look better on smaller screen but there is one that in some cases might work better in a way that it render data in non-table way. This method should work fine on tables that uses its first row as column names container.

In short, we'll implement DOM manipulation and create mobile specific HTML (new elements derived from existrng original table, tr and td elements) visible only at smaller width devices (vida media queries) and extracted from original table layout.


document.addEventListener('DOMContentLoaded', function () {
  generateMobileTables();
}, false);

function generateMobileTables() {
    var selector = "responsive";
    var allTables = document.getElementsByClassName(selector);

    if (allTables.length > 0) {

        var tableWrapper = document.createElement('div');
        tableWrapper.setAttribute("class", "table-wrapper");

        for (i = 0; i < allTables.length; ++i) {
            allTables[i].parentNode.insertBefore(tableWrapper, allTables[i]);
            tableWrapper.appendChild(allTables[i]);
        }

        for (i = 0; i < allTables.length; ++i) {
            var tbl = allTables[i];
            var columns = [];
            var first_row_cells = tbl.rows[0].cells;
            for (c = 0; c < first_row_cells.length; ++c) {
                columns.push(first_row_cells[c].innerHTML);
            }

            var mobileTable = document.createElement('div');
            mobileTable.setAttribute("class", "mobile-table");

            var rows = tbl.rows;
            if (rows.length <= 1) continue;

            for (r = 1; r < rows.length; ++r) {

                for (c = 0; c < rows[r].cells.length; ++c) {

                    var html = rows[r].cells[c].innerHTML;
                    if (html == "" || html == " ") html = "-";
                    var p = document.createElement('p');
                    p.innerHTML = columns[c];
                    mobileTable.append(p);

                    var div = document.createElement('div');
                    div.innerHTML = html;
                    mobileTable.append(div);

                }

                var hr = document.createElement('hr');
                mobileTable.append(hr);
            }

            tbl.parentElement.after(mobileTable);

        }
    }
}
.mobile-table {
    display: none;
    border: solid 1px #ddd;
    padding: 2rem;
}

.mobile-table > p {
    font-weight: bold;
    margin-bottom: 0;
}

.mobile-table > div {
    margin-bottom: 1rem;
}

.mobile-table hr:last-child {
    display: none;
}

@media only screen and (max-width: 640px){
    .table-wrapper {
        display: none;
    }

    .mobile-table {
        display: block;
    }
}