JSFiddle - React, Tailwind, and code Playground

by Thomas Upton

HTML

<div id="container"></div>

CSS

* {
    padding: 0;
    margin: 0;
}
body {
    background-color: #000;
    color: #ccc;
    font-family: Helvetica, Arial, Verdana, sans-serif;
}

#container {
    width: 850px;
    margin: 25px auto 0 auto;
    border: 1px solid #777;
}
#content {
    max-height: 709px;
    overflow-y: auto; /* scroll all rows */
}
.row {
    border-bottom: 1px solid gray;
    height: 70px; /* must be defined so row_data and columns can be 100% */
}
.row:nth-child(odd) {
    background-color: #222;
}
.row:hover {
    background-color: #444;   
}
.row:last-child {
    border: 0;   
}
.row a {
    color: #4AB7FF;
    text-decoration: none;
}
.row a:hover {
    text-decoration: underline;   
}
.row_data,
.row_header {
    float: left;
    width: 254px;
    height: 100%;
    border-right: 1px solid gray;
}
.row_contents {
    text-align: center;
    padding-top: 5px;
}
.row_nav {
    font-size: 85%;
    padding-top: 10px;   
}
.columns,
.column_header {
    float: left;
    width: 580px;
    height: 100%;
    overflow-y: hidden; /* scroll just the columns */
}
.columns:hover {
    overflow-y: auto;
}
.data {
    padding: 5px 0 0 5px;
}
.header {
    height: 20px;
    padding-bottom: 5px;
    border-bottom: 1px solid #ccc;
}
.row_header {
    border-right: none;
}

JavaScript

dojo.require("dojo.NodeList-traverse");

var header = [
    '<div class="header">',
        '<div class="row_header"><div class="data">Row Keys</div></div>',
        '<div class="column_header"><div class="data">Columns</div></div>',                    
    '</div>'].join('');

var rows = [];
for (var j = 1; j < 31; j++) {
    var row = [
        '<div class="row">',
            '<div class="row_data">',
                '<div class="row_contents">Row Key ' + j,
                    '<div class="row_nav"><a href="javascript:void(0);">View all columns &raquo;</a></div>',
                '</div>',
            '</div>',
        '<div class="columns">'].join('');
    for (var i = 1; i < 31; i++) {
        row += '<div class="data">Column ' + i + ': Value' + i + '</div>';
    }

    row += ['</div>',
        '</div>'].join('');

    rows.push(row);
}

var scrollHandler = function(e) {
    var columnParents = dojo.query(e.target).parents('.columns');
    if (columnParents.length >= 1) {
        var scroll = (e[(!dojo.isMozilla ? "wheelDelta" : "detail")] * (dojo.isMozilla ? 1 : -1)) > 0 ? 1 : -1;
        columnParents[0].scrollTop += (scroll * 23);
        dojo.stopEvent(e);
    }        
}

var content = document.createElement('div');
content.id = 'content';
content.innerHTML = rows.join('');
dojo.connect(content, (!dojo.isMozilla ? "onmousewheel" : "DOMMouseScroll"), scrollHandler);

var container = document.getElementById('container');
container.innerHTML = header;
container.appendChild(content);