Fix modal-open layout shift caused by position:fixed scroll lock
Replace the body position:fixed hack with overflow:hidden on html element, which works cleanly with scrollbar-gutter:stable to prevent layout shift. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -91,10 +91,8 @@ body {
|
|||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.modal-open {
|
html.modal-open {
|
||||||
position: fixed;
|
overflow: hidden; /* scrollbar-gutter: stable keeps the gutter reserved */
|
||||||
width: 100%;
|
|
||||||
overflow-y: scroll; /* keep scrollbar gutter to prevent layout shift */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Ambient animated background ── */
|
/* ── Ambient animated background ── */
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ export async function openCommandPalette() {
|
|||||||
const overlay = document.getElementById('command-palette')!;
|
const overlay = document.getElementById('command-palette')!;
|
||||||
const input = document.getElementById('cp-input') as HTMLInputElement;
|
const input = document.getElementById('cp-input') as HTMLInputElement;
|
||||||
overlay.style.display = '';
|
overlay.style.display = '';
|
||||||
document.body.classList.add('modal-open');
|
document.documentElement.classList.add('modal-open');
|
||||||
input.value = '';
|
input.value = '';
|
||||||
input.placeholder = t('search.placeholder');
|
input.placeholder = t('search.placeholder');
|
||||||
_loading = true;
|
_loading = true;
|
||||||
@@ -318,7 +318,7 @@ export function closeCommandPalette() {
|
|||||||
_isOpen = false;
|
_isOpen = false;
|
||||||
const overlay = document.getElementById('command-palette')!;
|
const overlay = document.getElementById('command-palette')!;
|
||||||
overlay.style.display = 'none';
|
overlay.style.display = 'none';
|
||||||
document.body.classList.remove('modal-open');
|
document.documentElement.classList.remove('modal-open');
|
||||||
_items = [];
|
_items = [];
|
||||||
_filtered = [];
|
_filtered = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,13 +67,10 @@ export function setupBackdropClose(modal: any, closeFn: () => void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _lockCount = 0;
|
let _lockCount = 0;
|
||||||
let _savedScrollY = 0;
|
|
||||||
|
|
||||||
export function lockBody() {
|
export function lockBody() {
|
||||||
if (_lockCount === 0) {
|
if (_lockCount === 0) {
|
||||||
_savedScrollY = window.scrollY;
|
document.documentElement.classList.add('modal-open');
|
||||||
document.body.style.top = `-${_savedScrollY}px`;
|
|
||||||
document.body.classList.add('modal-open');
|
|
||||||
}
|
}
|
||||||
_lockCount++;
|
_lockCount++;
|
||||||
}
|
}
|
||||||
@@ -82,9 +79,7 @@ export function unlockBody() {
|
|||||||
if (_lockCount <= 0) return;
|
if (_lockCount <= 0) return;
|
||||||
_lockCount--;
|
_lockCount--;
|
||||||
if (_lockCount === 0) {
|
if (_lockCount === 0) {
|
||||||
document.body.classList.remove('modal-open');
|
document.documentElement.classList.remove('modal-open');
|
||||||
document.body.style.top = '';
|
|
||||||
window.scrollTo({ top: _savedScrollY, behavior: 'instant' });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user