Poskakování stránky kvůli posuvníku
Jak zabránit, aby obsah stránky poskakoval v závislosti na posuvníku.
Pokud je obsah stránky centrovaný a některé stránky jsou krátké, takže se neobjeví svislý posuvník (zpravidla na pravé straně), způsobí přechod mezi dlouhou stránkou (s posuvníkem) a krátkou (bez posuvníku) nepěkné poskočení.
U webových aplikací k podobné situaci často dochází, když se obsah stahuje asynchronně a během načítání se tak výška stránky změní.
Existují dvě bezpracné možnosti jako vytvářet stránky delší (vyšší) nebo:
Neřešit.
CLS
CLS je zkratka Cumulative Layout Shift pro metriku označující neočekávané poskakování layoutu.
Tuto nepříjemnou věc může způsobovat řada věcí – posuvník může být jedna z nich.
Jde o to, že zobrazivší se posuvník během načítání zmenší dostupnou šířku. Tím dost často dojde k potřebě stávající obsah překreslit.
Tento problém se týká hlavně webových aplikací / SPA a průběžného načítání.
U klasického webu generovaného čistě na serveru má zpravidla prohlížeč obsah dostupný rovnou, takže dokáže rovnou rozhodnout, jestli (ne)bude posuvník potřeba.
- Web.dev: Cumulative Layout Shift
Minimální výška
Vlastností min-height
lze zadat minimální výšku obsahu na hodnotu, která posuvník vytvoří. Může to být ale matoucí/nepříjemné pro uživatele, protože mohou kvůli tomu zbytečně rolovat.
Přidání posuvníku
Jednoduchou konstrukcí jde přidat posuvník i v případech, že není potřeba – bude neaktivní (zašedlý).
Má to trochu nevýhodu, že je potom na stránce posuvník vždy a může ji to trochu hyzdit.
html {
overflow-y: scroll;
}
CSS vlastnost scrollbar-gutter
Poměrně nová CSS vlastnost scrollbar-gutter
(nepodporuje ji Safari) dokáže upravit přístup prohlížeče k posuvníku.
Zvlášť užitečná je hodnota stable
:
html {
scrollbar-gutter: stable;
}
Tím se zajistí, že prohlížeč pro daný element vždy vyhradí místo pro posuvník.
Trochu problém u ní je, že v případě aplikování přímo pro <html>
logicky vyhrazuje místo u ní.
Chová se to dost podobně, jako by se přidalo vnitřní odsazení přes padding
.
Pokud se tedy pozadí stránky nastavuje až v nějakém vnořeném elementu, výsledek může být visuálně dost podobný jako neaktivní posuvník.
- MDN: scrollbar-gutter
Vlastní posuvník
Jedno z možných řešení je si posuvník zajišťovat po svém — prostým vhodně ostylovaným <div>
em, který bude absolutně posicovaný, takže nebude ovlivňovat vykreslení obsahu.
- Vlastní vzhled scrollbaru: Posuvník v JavaScriptu
Nestandardní scrollbar ale nemusí být pro návštěvníky úplně ideální.
I kdyby měla náhrada vyřešené rolování kolečkem, klávesnicí i dotykem (se zachováním setrvačnosti) a autoscroll, nikdy nebude respektovat uživatelské nastavení, jako je třeba velikost a plynulost posunu. Dojem, že na stránce je cosi divného, je pak silnější, než kdyby obsahový blok cukal o pár pixelů do strany.
Odečtení šířky
S využitím jednotky vw
(viewport — rozměry okna) a počítání calc
je možné dopočítat šířku posuvníku a nastavit ji jako levý margin
čistě v CSS. Řešení je funkční od IE 9.
html {
margin-left: calc(100vw - 100%);
}
Bude to fungovat tak, že v případě krátké stránky bude levý margin nulový (šířka viewportu se bude rovnat šířce elementu <html>
).
V případě dlouhé stránky bude viewport šírší o šířku posuvníku. O tuto šířku se potom dlouhá stránka odšťouchne zleva.
Změření šířky posuvníku
Je-li potřeba dynamicky reagovat na šířku posuvníku, docela elegantní řešení je změřit šířku JavaScriptem a nastavit ji do CSS proměnné.
Posuvník totiž dokáže být v různých prohlížečích a systémech různě široký.
V macOS navíc ještě mění svou šířku na základě toho, jestli je či není připojena myš.
function setScrollbarWidthVariable() {
let div = document.createElement('div');
div.style.overflowY = 'scroll';
document.body.appendChild(div);
let scrollbarWidth = div.offsetWidth - div.clientWidth;
document.body.removeChild(div);
document.documentElement.style.setProperty('--scrollbar-width', scrollbarWidth + 'px');
}
setScrollbarWidthVariable()
Tento kód nastaví proměnnou scrollbar-width
, která bude kdekoliv dostupná k použití:
.cokoliv {
width: var(--scrollbar-width);
}
Poskakování obsahu za modálem
Při zobrazování obsahu v modálu se typicky pro celou stránku vypíná scrollování, protože modál bude mít scrollbar vlastní.
.is-modal-open {
overflow: hidden;
}
Zde je opět vhodné odšťouchnout obsah, aby neposkaoval. Třeba průhledným border
em:
.is-modal-open {
overflow: hidden;
border-right: var(--scrollbar-width) solid transparent;
}
Komentáře