Q1. Why Can a Non-Scrollable List Block Mobile Page Scrolling?
A touch gesture is routed through a scroll chain. The browser starts with the element under the finger and then considers its scrollable ancestors. An element can interrupt that chain even when its own content is too short to scroll.
In this case, swiping over the backlink list did not move the list or the page. Swiping immediately outside the list moved the page normally. The problem was therefore attached to the nested overflow structure, not to page scrolling in general.
Q2. Which CSS Properties Created the Scroll Trap?
The backlink list inherited a generic scroll-list rule:
ul.overflow {
overflow-y: auto;
}The backlink plugin added containment:
.backlinks > ul.overflow {
overscroll-behavior: contain;
}A generic parent rule also affected the backlink wrapper:
div:has(> .overflow) {
overflow-y: hidden;
}On mobile, the backlink component was no longer height-limited. Its list therefore had no reason to scroll, but it still participated in a nested overflow chain. overscroll-behavior: contain prevented the list from handing boundary scrolling to an ancestor, while the wrapper’s overflow-y: hidden formed another interruption before the page.
Q3. How Was It Confirmed That the List Was Not Actually Scrollable?
At a 390 by 844 mobile viewport, the backlink list had matching dimensions:
clientHeight = 34
scrollHeight = 34A scroll container needs scrollHeight to exceed clientHeight before it has vertical content to consume. The equal values proved that the list had no internal scroll range.
Before the fix, a gesture over the list left both values unchanged:
list.scrollTop = 0
page.scrollY = 2600The same gesture outside the backlink area moved the page from 2600 to 2900.
Q4. Why Was Changing Only overscroll-behavior Insufficient?
Changing the list from overscroll-behavior: contain to auto restored permission to continue along the scroll chain, but the next ancestor still had overflow-y: hidden. The gesture remained trapped at that wrapper.
This is why nested scrolling bugs must be diagnosed across the full ancestor chain. Inspecting only the element under the finger can reveal one blocker while missing the next one.
Q5. What CSS Restored Normal Mobile Scrolling?
The mobile layout does not constrain the backlink height, so it does not need an internal scroll container. The fix returned both the wrapper and the list to normal visible overflow:
@media all and (max-width: 800px) {
// Backlinks are not height-limited on mobile, so they do not need nested
// scrolling. Keep both wrappers in normal flow so swipes scroll the page.
.page > #quartz-body .backlinks {
overflow-y: visible;
}
.page > #quartz-body .backlinks > ul.overflow {
max-height: none;
overflow-y: visible;
overscroll-behavior: auto;
}
}After the fix, a gesture beginning over the backlink list moved the page to its next scroll position while list.scrollTop remained 0. The page, rather than the list, correctly owned the gesture.
Q6. Why Use a Project CSS Override Instead of Editing the Plugin?
The installed plugin directory is generated dependency state. A plugin reinstall or update can replace local edits inside it.
The durable customization belongs in the project’s authored stylesheet. A project override survives plugin installation and keeps the exception visible near the rest of the site’s mobile layout rules. The selector must be specific enough to beat the plugin rule if plugin styles are emitted later in the final stylesheet.
Q7. What Is the General Diagnostic Rule?
When scrolling fails only over one region, inspect the computed overflow-y, overscroll-behavior, and touch-action values for the target and every ancestor up to the page. Also compare scrollHeight with clientHeight to determine which element can actually scroll.
A declared scroll container and an element with real scroll range are not the same thing. A container with no scrollable content can still change gesture routing and block the page.