JSFiddle - React, Tailwind, and code Playground
by Rolf
HTML
<p>
<label>Enable Rebreak <input type="checkbox" id="rebreak"></label>
</p>
<figure id="ov1" class="overview">
<ol>
<li>
<p>Thema 1</p>
<ul>
<li>Punkt 1-1</li>
<li>Punkt 1-2</li>
<li>Punkt 1-3</li>
<li>Punkt 1-4</li>
<li>Punkt 1-5</li>
</ul>
</li>
<li>
<p>Thema 2</p>
<ul>
<li>Punkt 2-1<br>
<li>Punkt 2-2<br>
</ul>
</li>
<li>
<p>Thema 3</p>
<ul>
<li>Punkt 3-1</li>
<li>Punkt 3-2</li>
<li>Punkt 3-3</li>
<li>Punkt 3-4</li>
<li>Punkt 3-5</li>
<li>Punkt 3-6</li>
<li>Punkt 3-7</li>
<li>Punkt 3-8</li>
<li>Punkt 3-9</li>
<li>Punkt 3-10</li>
<li>Punkt 3-11</li>
<li>Punkt 3-12</li>
<li>Punkt 3-13</li>
</ul>
</li>
<li>
<p>Thema 4</p>
<ul>
<li>Punkt 4-1</li>
<li>Punkt 4-2</li>
</ul>
</li>
<li>
<p>Thema 5</p>
<ul>
<li>Punkt 5-1</li>
<li>Punkt 5-2</li>
<li>Punkt 5-3</li>
</ul>
<br>
</li>
</ol>
</figure>
CSS
.overview {
column-width: 18em;
border: 1px solid green;
padding: 2px;
margin-bottom: 3em;
}
.overview ol {
margin: 0;
padding-left: 1.5em;
}
.overview > ol > li {
padding: 0 10px 0 0;
}
.overview .keepTogether {
break-inside: avoid;
}
.overview > ol > li::marker {
font-weight: bold;
}
.overview > ol > li > p {
margin: 0;
padding: 0;
}
.overview .break {
background: linear-gradient(to bottom, yellow 10px, white 10px);
break-before: column;
}
.overview > ol > li.breaking {
padding: 0 0 0 10px;
background: linear-gradient(to bottom, red 10px, white 10px);
}
JavaScript
window.addEventListener("resize", runRebreak);
let cbRebreak = document.getElementById("rebreak");
let reflowTimer = -1;
let allowRebreak = rebreak.checked;
cbRebreak.addEventListener("change", function(event) {
allowRebreak = event.target.checked;
if (!allowRebreak)
removeManualBreaks(document.querySelector(".overview"));
else
runRebreak();
});
allowRebreak && runRebreak();
function removeManualBreaks(container) {
let breaks = container.querySelectorAll(".break, .breaking");
for (let i=0; i<breaks.length; i++) {
breaks[i].classList.remove("break");
breaks[i].classList.remove("breaking");
}
}
function setKeepTogethers(container) {
let sections = container.querySelectorAll("ol > li");
for (let i=0; i<sections.length; i++) {
if (sections[i].querySelectorAll("li").length < 3)
sections[i].classList.add("keepTogether");
}
}
function runRebreak() {
if (!allowRebreak) return;
//console.clear();
//console.log(`REBREAK`);
let ov = document.getElementById("ov1");
removeManualBreaks(ov);
setKeepTogethers(ov);
if (reflowTimer)
clearTimeout(reflowTimer);
reflowTimer = setTimeout(runReflow, 100, ov, 0);
}
function runReflow(container, startWith) {
//console.log(`Reflow from ${startWith}`);
let sections = container.querySelectorAll("ol > li");
for (let i=startWith; i<sections.length; i++) {
let sect = sections[i];
let li1 = sect.querySelector("ul > li:nth-of-type(1)");
let li2 = sect.querySelector("ul > li:nth-of-type(2)");
//console.log(`Section ${i} top=${sect.offsetTop}, l1.top=${li1.offsetTop}, l2.top=${li2.offsetTop}`);
let breaker;
let nextSect = i+1;
if (sect.classList.contains("break"))
{
//console.log("already breaking");
}
else if (li1.offsetTop < sect.offsetTop) {
breaker = sect;
//console.log(`add break for sect ${i}`);
}
else if (li2.offsetTop <...