JSFiddle - React, Tailwind, and code Playground

HTML

<div id="listHolder"></div>

CSS

html, body {
    width:100%;
    height:100%;
    padding:0;
    margin:0
}
.listItem {
    border:1px solid gray;
    padding:0 5px;
    width: margin : 1px 0px;
}
#listHolder {
    height:100%;
    width:100%;
    background-color:#CCC;
    box-sizing:border-box;
    overflow:hidden
}

JavaScript

(function () {
    var list = (function () {
        var temp = [];
        for (var i = 0, l = 30; i < l; i++) {
            temp.push("item-" + (i));
        }
        return temp;
    }());

    function listItem(text, id) {
        var _div = document.createElement('div');
        _div.innerHTML = text;
        _div.className = "listItem";
        _div.id = id;
        return _div;
    }
    var listHold = document.getElementById('listHolder'),
        ht = listHold.clientHeight,
        wt = listHold.clientWidth,
        ele = listItem(list[0], 'item0'),
        frag = document.createDocumentFragment();
    listHold.appendChild(ele);
    var ht_ele = ele.clientHeight,
        filled = ht_ele,
        filledIn = [0];
    for (var i = 1, l = list.length; i < l; i++) {
        if (filled + ht_ele < ht - (ht_ele * 3)) {
            filled += ht_ele;
            ele = listItem(list[i], 'item' + i);
            frag.appendChild(ele);
        } else {
            filledIn.push(i - 1);
            break;
        }
    }

    listHold.appendChild(frag.cloneNode(true));

    var elements = document.querySelectorAll('#listHolder .listItem');

    function render(from, to) {
        var counter = 0;
        for (var i = from; i <= to; i++) {
            elements[counter].innerHTML = list[i];
            counter++;
        }
    }

    function MouseWheelHandler(e) {
        var e = window.event || e;
        var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
        if (delta == -1) {
            var start = filledIn[0],
                end = filledIn[1];
            start = start + 1;
            if (end == list.length - 1) {
                return;
            }
            end = end + 1;

            if (end - start == elements.length - 1) {
                render(start, end);
                filledIn = [start, end];
            } else {
                var shift = elements.length + (end - start);
                start = start - shift;
              ...