fix(settings): stop clipping help tooltips in the settings pane

Help tooltips were CSS pseudo-elements on the info icon, so they were
descendants of the scrollable settings pane (.settings-content uses
overflow-y: auto) and got clipped at its top edge. The Active Library
deprecation notice made this obvious: the text grew to ~10 lines while
only ~5 fit above the icon, so the tooltip started mid-sentence at
"page. Deprecated:".

Render the tooltip once into <body> with position: fixed instead, so no
overflow ancestor can clip it, and position it from JS: above the trigger
when it fits, below otherwise, clamped to the viewport. It follows the
trigger on scroll/resize and hides on mouseout, Escape or touch. The
delegated listeners also cover help icons rendered later by the settings
manager, and the box may now use 320px instead of 220px, which keeps long
help texts to fewer lines.
This commit is contained in:
Will Miao
2026-10-11 11:34:52 +08:00
parent 79db86666d
commit d5139500f9
6 changed files with 398 additions and 49 deletions
+3 -49
View File
@@ -1565,55 +1565,9 @@ input:checked + .toggle-slider:before {
opacity: 1;
}
/* Tooltip using data-tooltip attribute */
.info-icon[data-tooltip] {
position: relative;
}
.info-icon[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 8px);
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 8px 12px;
border-radius: 6px;
font-size: 14px;
font-weight: normal;
font-family: var(--font-body);
white-space: normal;
max-width: 220px;
width: max-content;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s ease, visibility 0.2s ease;
pointer-events: none;
z-index: 10000;
line-height: 1.4;
box-shadow: var(--shadow-elevated);
text-transform: none;
}
.info-icon[data-tooltip]:hover::after {
opacity: 1;
visibility: visible;
}
/* Fix tooltip overflow on left edge - when icon is near left side of modal */
.settings-subsection-header .info-icon[data-tooltip]::after {
left: 0;
transform: translateX(0);
}
.settings-subsection-header .info-icon[data-tooltip]::before {
left: 12px;
}
/* Dark theme adjustments for tooltip - Fully opaque */
[data-theme="dark"] .info-icon[data-tooltip]::after {
background: rgba(40, 40, 40, 0.95);
box-shadow: var(--shadow-dark-lg);
}
/* Help tooltips are rendered by static/js/utils/tooltip.js into <body> instead
of a pseudo-element, so the scrollable settings pane cannot clip them - see
static/css/components/tooltip.css. */
/* Extra Folder Paths - Single input layout */
.extra-folder-path-row {
+41
View File
@@ -0,0 +1,41 @@
/* Floating tooltip for [data-tooltip] triggers.
Rendered into <body> by static/js/utils/tooltip.js and positioned with
`position: fixed`, so scrollable ancestors (e.g. .settings-content) cannot
clip it. */
.lm-tooltip {
position: fixed;
top: 0;
left: 0;
z-index: var(--z-tooltip);
box-sizing: border-box;
width: max-content;
max-width: min(320px, calc(100vw - 16px));
padding: 8px 12px;
border-radius: 6px;
background: rgba(0, 0, 0, 0.9);
color: white;
font-family: var(--font-body);
font-size: 14px;
font-weight: normal;
line-height: 1.4;
text-align: left;
text-transform: none;
white-space: normal;
overflow-wrap: break-word;
box-shadow: var(--shadow-elevated);
opacity: 0;
visibility: hidden;
transition: opacity 0.2s ease, visibility 0.2s ease;
pointer-events: none;
}
.lm-tooltip.visible {
opacity: 1;
visibility: visible;
}
/* Dark theme adjustments for tooltip - Fully opaque */
[data-theme="dark"] .lm-tooltip {
background: rgba(40, 40, 40, 0.95);
box-shadow: var(--shadow-dark-lg);
}