test(home): outline every fixed/sticky element to find the white bar

User reports: TEST #3 marker sits at the true bottom of the home
page's main content, but when scrolled the test text "goes behind"
an opaque white bar — confirming the bar is fixed/sticky (overlays
scrolling content). Our CSS only declares ONE fixed element near
the bottom (``#datatools-sticky-footer``), which the user already
ruled out. So something else — Streamlit native chrome, a third-
party widget, or a fixed element we haven't enumerated — is
overlaying the content.

Inject a small diagnostic iframe whose JS, running against the
parent document, walks every element on the page and outlines each
``position: fixed`` or ``position: sticky`` node with a distinct
color + a top-left label showing ``tagName#id[data-testid] pos=…
h=…px bg=…``. Re-runs after initial paint, on a couple of delays
(for late-mounting components), and on every scroll.

This is read-only — no DOM mutations beyond outline styles and
labels — so it's safe to ship even if I miss removing it.
The user can now visually identify which colored box is the
offending white bar and report its label.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-18 22:15:19 +00:00
parent e282f061dc
commit 4c8e1199a4

View File

@@ -289,16 +289,87 @@ def _home_page() -> None:
key_namespace=name,
)
# TEMP: visible marker at the very end of the home page's main
# content. Used to locate the "white bar" the user wants removed.
# If this red banner lines up with the offending white strip when
# scrolled to the bottom, the strip is something rendered right
# here at the tail of ``stAppViewBlockContainer``.
# TEMP: end-of-content marker — confirmed at the true bottom of
# the home page's main content. The user reports content scrolls
# *behind* the offending white bar, so the bar is fixed-positioned.
# Only ``#datatools-sticky-footer`` is fixed at the bottom per
# our CSS, but the user already confirmed the sticky footer is
# NOT the offending bar. So there's a fixed element we haven't
# accounted for. The JS below outlines EVERY fixed/sticky element
# in the parent document with a labelled colored border so we can
# see exactly what's overlaying scrolled content.
st.markdown(
'<div style="background:#ffe0e0;border:2px dashed #b00020;'
'color:#b00020;font-weight:700;font-size:13px;text-align:center;'
'padding:8px 12px;margin:4px 0;font-family:system-ui,sans-serif;">'
'◀ CLAUDE TEST #3 — END OF MAIN CONTENT — IS THIS THE WHITE BAR?'
'◀ CLAUDE TEST #3 — END OF MAIN CONTENT ▶'
'</div>',
unsafe_allow_html=True,
)
st.iframe(
"""
<script>
(function () {
function outlineFixed() {
var doc = window.parent.document;
if (!doc) return;
// Clear previous outlines + labels so reruns don't stack.
doc.querySelectorAll('[data-claude-outline-label]').forEach(function (n) {
n.remove();
});
doc.querySelectorAll('[data-claude-outlined]').forEach(function (el) {
el.style.outline = '';
el.style.outlineOffset = '';
el.removeAttribute('data-claude-outlined');
});
var palette = ['#e6194b', '#3cb44b', '#4363d8', '#f58231', '#911eb4',
'#46f0f0', '#f032e6', '#bcf60c', '#fabebe', '#008080'];
var idx = 0;
doc.querySelectorAll('*').forEach(function (el) {
var cs = window.parent.getComputedStyle(el);
if (cs.position !== 'fixed' && cs.position !== 'sticky') return;
var rect = el.getBoundingClientRect();
// Skip zero-size and off-screen-only items.
if (rect.width < 2 || rect.height < 2) return;
var color = palette[idx % palette.length];
idx += 1;
el.style.outline = '3px solid ' + color;
el.style.outlineOffset = '-3px';
el.setAttribute('data-claude-outlined', '1');
// Label pinned to the element's top-left.
var label = doc.createElement('div');
label.setAttribute('data-claude-outline-label', '1');
var name = el.tagName.toLowerCase()
+ (el.id ? '#' + el.id : '')
+ (el.getAttribute('data-testid')
? '[' + el.getAttribute('data-testid') + ']' : '')
+ ' pos=' + cs.position
+ ' h=' + Math.round(rect.height) + 'px'
+ ' bg=' + cs.backgroundColor;
label.textContent = name;
label.style.cssText =
'position:fixed;left:' + Math.max(0, rect.left) + 'px;'
+ 'top:' + Math.max(0, rect.top - 18) + 'px;'
+ 'background:' + color + ';color:#fff;'
+ 'font:11px/1.2 ui-monospace,monospace;'
+ 'padding:2px 5px;border-radius:3px;'
+ 'z-index:2147483647;pointer-events:none;'
+ 'white-space:nowrap;max-width:90vw;overflow:hidden;'
+ 'text-overflow:ellipsis;';
doc.body.appendChild(label);
});
}
// Run after initial paint and again after Streamlit's component
// iframes settle.
setTimeout(outlineFixed, 400);
setTimeout(outlineFixed, 1500);
setTimeout(outlineFixed, 3500);
// Re-run on scroll so labels track the current viewport state.
window.parent.addEventListener('scroll', function () {
setTimeout(outlineFixed, 50);
}, true);
})();
</script>
""",
height=1,
)