JSFiddle - React, Tailwind, and code Playground
by Palpatim
HTML
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css">
<div id="container"></div>
CSS
#container {
margin-left: 1rem;
margin-top: 1rem;
border: .1rem solid blue;
width:90%;
background-color: #aaaaaa;
}
.hdr {
position: absolute;
padding: 0 .25rem;
width: 100%;
height: 1.5rem;
font-family: monospace;
line-height: 1.5rem;
background-color: green;
color: #00FF00;
}
.body {
/* margin-top = .hdr box height */
margin: 1.5rem 1rem 0;
border: .1rem solid red;
padding: .5rem;
}
.max200 {
position: relative;
margin-left: 1rem;
border: .1rem solid yellow;
max-height: 25rem;
overflow-x: hidden;
overflow-y: scroll;
}
JavaScript
// Initialize structure
var maxSections = 8;
var numLines = 20;
function createSection(sectionNumber) {
var $max200 = $('<div class="max200" id="section-' + sectionNumber + '"/>');
var $header = $('<div class="hdr"/>');
$header.html('Section ' + sectionNumber + ' of ' + maxSections);
var $body = $('<div class="body" />');
for (var i = 0; i < numLines; i++) {
$body.append(i + '<br/>');
}
$max200.append($header);
$max200.append($body);
return $max200;
}
function appendSection($parent, current) {
var $s = createSection(current);
$parent.append($s);
current++;
if (current <= maxSections) {
appendSection($s, current);
}
}
appendSection($('#container'), 1);
/**
* Given an element, create an event listener that
* will pin the element's header once it passes a certain offset
*/
function createScrollListener($el) {
var $el = $(e.target);
}
/**
* Given a child element, pin the header of the
* child such that it is "stacked" under the parent's header.
* In the special case of the top-level section, fix the header
* so that it is abutted to the top of the #container div
*/
function pinHeader($child) {
var $childHeader, childHeaderBoundRect, $parentContainer, $parentHeader, parentHeaderBoundRect, top;
$childHeader = $child.find('> .hdr');
childHeaderBoundRect = $childHeader[0].getBoundingClientRect();
$parentContainer = $child.parent().closest('.max200');
if ($parentContainer.length) {
$parentHeader = $parentContainer.find('> .hdr');
parentHeaderBoundRect = $parentHeader[0].getBoundingClientRect();
top = parentHeaderBoundRect.top + parentHeaderBoundRect.height;
} else {
// First .max200 div does not have a parent container, so
// fix it to the top of the #container div
$parentContainer = $('#container');
parentHeaderBoundRect = $parentContainer[0].getBoundingClientRect();
top =...