Fix tooltip flash and misposition on mobile (#20)
Some checks failed
Build / build (push) Has been cancelled

- Temporarily expand tooltip for accurate size measurement before positioning
- Use @media (hover: hover) to prevent CSS :hover triggering on touch tap
- Await position calculation before showing tooltip
This commit is contained in:
Christian Semmler 2026-02-02 17:28:04 -08:00 committed by GitHub
parent 006ba8472c
commit 2c12d5ad5e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 4 deletions

View File

@ -20,6 +20,12 @@
const tooltip = trigger.querySelector('.tooltip-content');
if (!tooltip) return;
// Temporarily expand tooltip for measurement (keep invisible)
tooltip.style.maxHeight = 'none';
tooltip.style.padding = '10px';
tooltip.style.visibility = 'hidden';
tooltip.style.opacity = '0';
const { x, y } = await computePosition(trigger, tooltip, {
placement: 'top',
middleware: [
@ -31,7 +37,12 @@
Object.assign(tooltip.style, {
left: `${x}px`,
top: `${y}px`
top: `${y}px`,
// Clear temporary styles - CSS will handle final visibility
maxHeight: '',
padding: '',
visibility: '',
opacity: ''
});
}
@ -39,7 +50,7 @@
const isTouchDevice = window.matchMedia('(any-pointer: coarse)').matches;
// Touch devices: position and show on click
document.addEventListener('click', (e) => {
document.addEventListener('click', async (e) => {
const trigger = e.target.closest('.tooltip-trigger');
if (trigger) {
e.preventDefault();
@ -47,7 +58,7 @@
const wasActive = trigger.classList.contains('active');
document.querySelectorAll('.tooltip-trigger.active').forEach(t => t.classList.remove('active'));
if (!wasActive) {
positionTooltip(trigger);
await positionTooltip(trigger);
trigger.classList.add('active');
}
} else {

View File

@ -807,7 +807,18 @@ body {
max-height: 0;
}
.tooltip-trigger:hover>.tooltip-content,
/* Only use hover on devices with real hover support (not touch) */
@media (hover: hover) {
.tooltip-trigger:hover>.tooltip-content {
opacity: 1;
visibility: visible;
padding: 10px;
max-height: none;
overflow: visible;
}
}
/* Active state for touch devices (controlled by JS) */
.tooltip-trigger.active>.tooltip-content {
opacity: 1;
visibility: visible;