ObsiViewer/src/styles/_overlay-scrollbar.css

229 lines
7.2 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ===============================
Overlay Scrollbar — Cross-browser (Edge/Firefox/Chrome/Safari)
Fichier : _overlay-scrollbar.css
=============================== */
/* ---------- Thèmes & variables ---------- */
:root {
/* Couleurs (clair) — alignées sur les tokens de thème */
/* Track très discret */
--ovsb-track-bg: color-mix(in oklab, var(--border, rgba(15,23,42,0.25)) 16%, transparent);
/* Pouce (thumb) subtil basé sur --scrollbar-thumb, avec légère teinte brand */
--ovsb-thumb-bg: color-mix(
in oklab,
var(--scrollbar-thumb, rgba(100,116,139,0.55)) 80%,
color-mix(in oklab, var(--brand, #64748b) 18%, transparent) 20%
);
--ovsb-thumb-bg-active: color-mix(
in oklab,
var(--scrollbar-thumb, rgba(100,116,139,0.55)) 65%,
color-mix(in oklab, var(--brand-700, var(--brand, #64748b)) 40%, transparent) 35%
);
/* Géométrie & transitions */
--ovsb-trans: 240ms ease;
--ovsb-right: 2px; /* Décalage à droite de loverlay */
--ovsb-thumb-height: 24px; /* Hauteur mini du thumb */
/* Épaisseurs / états
Astuce : on anime lépaisseur via scaleX pour éviter les changements de hit-area.
Le track garde une largeur de hit-test stable. */
--ovsb-active-width: 10px; /* largeur visuelle en état "active" */
--ovsb-mini-width: 2px; /* largeur visuelle en état "mini" */
/* Ratio (mini vs active) → sert à scaleX. Si vous modifiez les largeurs, adaptez ce ratio. */
--ovsb-mini-scale: 0.2; /* 2 / 10 = 0.2 */
}
.dark,
[data-theme="dark"] {
/* Légèrement plus visible sur fond sombre mais toujours discret */
--ovsb-track-bg: color-mix(in oklab, var(--border, rgba(148,163,184,0.35)) 22%, transparent);
--ovsb-thumb-bg: color-mix(
in oklab,
var(--scrollbar-thumb, rgba(226,232,240,0.62)) 85%,
color-mix(in oklab, var(--brand-700, var(--brand, #94a3b8)) 24%, transparent) 15%
);
--ovsb-thumb-bg-active: color-mix(
in oklab,
var(--scrollbar-thumb, rgba(226,232,240,0.72)) 70%,
color-mix(in oklab, var(--brand-700, var(--brand, #94a3b8)) 45%, transparent) 30%
);
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
.ovsb,
.ovsb__root,
.ovsb__track,
.ovsb__thumb {
transition: none !important;
}
}
/* ========================================
1) Conteneur scrollable (hôte de loverlay)
======================================== */
/* IMPORTANT : appliquer .ovsb-host sur lélément QUI SCROLLE réellement */
.ovsb-host {
position: relative; /* nécessaire pour positionner loverlay en absolute */
overflow: auto; /* cest bien LUI qui scrolle */
/* Masquer la scrollbar native (Firefox + Edge/Chrome/Safari) */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Edge/IE legacy */
}
.ovsb-host::-webkit-scrollbar {
width: 0 !important; /* Chrome/Edge/Safari */
height: 0 !important;
background: transparent !important;
}
.ovsb-host::-webkit-scrollbar-thumb,
.ovsb-host::-webkit-scrollbar-track,
.ovsb-host::-webkit-scrollbar-corner {
background: transparent !important;
border: none !important;
}
/* Cas où le DOCUMENT scrolle (évitez si possible). Décommentez si nécessaire. */
/*
html, body {
scrollbar-width: none;
-ms-overflow-style: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
}
*/
/* Si vous décidez de garder la native (non recommandé ici), stabilisez le gutter : */
/*
@supports (scrollbar-gutter: stable) {
.ovsb-host-native {
scrollbar-gutter: stable both-edges;
}
}
*/
/* ========================================
2) Overlay (track + thumb)
======================================== */
/* Racine overlay : ne capture pas les events hors track/thumb */
.ovsb {
position: absolute;
top: 0;
right: var(--ovsb-right);
bottom: 0;
width: 12px; /* largeur de HIT-TEST stable (garde la zone de survol constante) */
pointer-events: none; /* la racine ne capte pas, on laisse le contenu défiler naturellement */
z-index: 10;
contain: layout paint; /* isolation pour perf */
}
/* Nœud interne (utile si vous voulez des wrappers) */
.ovsb__root {
position: absolute;
inset: 0;
}
/* Piste (track) — zone cliquable/drag */
.ovsb__track {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 12px; /* hit-area stable */
border-radius: 9999px;
background: var(--ovsb-track-bg);
opacity: 0; /* géré par états */
pointer-events: auto; /* le track doit capter pour hover/drag */
transition: opacity var(--ovsb-trans);
will-change: opacity;
}
/* Thumb (manette) — épaisseur animée via scaleX (pas de shift) */
.ovsb__thumb {
position: absolute;
top: 0; /* la position Y est appliquée via transform translateY */
right: 1px; /* léger décalage pour équilibre visuel */
width: var(--ovsb-active-width);
height: var(--ovsb-thumb-height);
border-radius: 9999px;
background: var(--ovsb-thumb-bg);
/* Position & épaisseur animées :
translateY: mis à jour dynamiquement (via style inline ou CSS var)
scaleX: mini/active
*/
transform: translateY(var(--ovsb-thumb-y, 0px)) scaleX(var(--ovsb-mini-scale));
transform-origin: right center;
transition: transform var(--ovsb-trans), background-color var(--ovsb-trans), opacity var(--ovsb-trans);
opacity: 0; /* masqué par défaut */
pointer-events: auto; /* doit capter pour le drag */
will-change: transform, opacity, background-color;
cursor: grab;
}
.ovsb__thumb:active {
cursor: grabbing;
}
/* ========================================
3) États (Hidden / Mini / Active)
======================================== */
/* HIDDEN : invisible, aucune interactivité */
.ovsb--hidden .ovsb__track,
.ovsb--hidden .ovsb__thumb {
opacity: 0;
pointer-events: none; /* rien ne capte, laisse le contenu réagir librement */
}
/* MINI : visible, thumb mince (scaleX mini), track discret */
.ovsb--mini .ovsb__track {
opacity: 1;
}
.ovsb--mini .ovsb__thumb {
opacity: 1;
background: var(--ovsb-thumb-bg);
transform: translateY(var(--ovsb-thumb-y, 0px)) scaleX(var(--ovsb-mini-scale));
}
/* ACTIVE : au survol de la zone scrollbar → thumb plus épais + couleur active */
.ovsb--active .ovsb__track {
opacity: 1;
}
.ovsb--active .ovsb__thumb {
opacity: 1;
background: var(--ovsb-thumb-bg-active);
transform: translateY(var(--ovsb-thumb-y, 0px)) scaleX(1);
}
/* Hover direct sur la zone track → active visuelle (utile en desktop) */
.ovsb__track:hover ~ .ovsb__thumb,
.ovsb__thumb:hover {
background: var(--ovsb-thumb-bg-active);
}
/* ========================================
4) Divers (compat & accessibilité visuelle)
======================================== */
/* Améliore la réactivité GPU (Edge/Chrome) */
.ovsb__track,
.ovsb__thumb {
backface-visibility: hidden;
}
/* Quand overlay affiché, éviter le scroll chaining vers parent si souhaité */
.ovsb-host {
overscroll-behavior: contain;
}
/* Cas tactile : permettre drag propre sans scroll involontaire horizontal */
.ovsb__thumb,
.ovsb__track {
touch-action: none;
}