fix(timeline): restore sticky month headers and jump-to-top button

Remove wrapper div around month headings so the h2 is a direct child
of the timeline container. position: sticky was broken because the
heading's containing block (the wrapper) was only as tall as the
heading itself, giving it no room to stick.

Also update MutationObserver to detect headings added as direct
children via node.matches() in addition to node.querySelector().
This commit is contained in:
Jon Seager 2026-02-03 13:29:46 +00:00
parent 145ddb4765
commit 16dd72b624
No known key found for this signature in database
2 changed files with 11 additions and 10 deletions

View file

@ -1,13 +1,11 @@
<div id="{{ month.anchor }}" class="scroll-mt-24" data-timeline-month> <h2 id="{{ month.anchor }}" class="timeline-heading scroll-mt-24 mb-6 text-2xl font-semibold text-amber-800" data-timeline-month>
<h2 class="timeline-heading mb-6 text-2xl font-semibold text-amber-800">
{{ month.heading }} {{ month.heading }}
<button type="button" class="timeline-top-btn" onclick="window.scrollTo({top: 0, behavior: 'smooth'})" aria-label="Back to top"> <button type="button" class="timeline-top-btn" onclick="window.scrollTo({top: 0, behavior: 'smooth'})" aria-label="Back to top">
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z" clip-rule="evenodd" /> <path fill-rule="evenodd" d="M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z" clip-rule="evenodd" />
</svg> </svg>
</button> </button>
</h2> </h2>
</div>
{% for event in month.events %} {% for event in month.events %}
<div class="timeline-item relative mb-8" data-timeline-event> <div class="timeline-item relative mb-8" data-timeline-event>
{# Timeline node/bullet #} {# Timeline node/bullet #}

View file

@ -201,6 +201,9 @@
mutations.forEach((mutation) => { mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => { mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) { if (node.nodeType === Node.ELEMENT_NODE) {
if (node.matches?.(".timeline-heading")) {
stickyObserver.observe(node)
}
const heading = node.querySelector?.(".timeline-heading") const heading = node.querySelector?.(".timeline-heading")
if (heading) { if (heading) {
stickyObserver.observe(heading) stickyObserver.observe(heading)