Add custom scrollbar and scroll behavior to sidebar

The changes add a custom scrollbar and enhanced scroll functionality to
the sidebar, with cross-browser support, accessibility features, and
device-specific optimizations.
This commit is contained in:
2025-06-01 12:53:29 -04:00
parent e71d2f9cb7
commit b422984fa2
2 changed files with 306 additions and 0 deletions
+235
View File
@@ -120,6 +120,241 @@ div {
visibility: visible !important;
}
/* Custom scrollbar for sidebar */
.sidebar::-webkit-scrollbar {
width: 8px;
}
.sidebar::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
margin: 0.5rem 0;
}
.sidebar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.3);
border-radius: 4px;
transition: background-color 0.2s ease;
}
.sidebar::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.5);
}
.sidebar::-webkit-scrollbar-thumb:active {
background: rgba(255, 255, 255, 0.6);
}
/* Firefox scrollbar styling */
.sidebar {
scrollbar-width: thin;
scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.1);
scroll-behavior: smooth;
}
/* Enhanced scrollbar for better UX */
.sidebar::-webkit-scrollbar-corner {
background: transparent;
}
/* Scrollbar styles for different states */
.sidebar:hover::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.4);
}
.sidebar:focus-within::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.45);
}
/* Theme-aware scrollbar styling */
@media (prefers-color-scheme: dark) {
.sidebar::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.2);
}
.sidebar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.4);
}
.sidebar::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.6);
}
}
/* High contrast mode support */
@media (prefers-contrast: high) {
.sidebar::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.3);
border: 1px solid rgba(255, 255, 255, 0.5);
}
.sidebar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(255, 255, 255, 0.9);
}
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
.sidebar {
scroll-behavior: auto;
}
.sidebar::-webkit-scrollbar-thumb {
transition: none;
}
}
/* Mobile and touch device enhancements */
@media (max-width: 768px) {
.sidebar::-webkit-scrollbar {
width: 6px;
}
.sidebar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.4);
border-radius: 3px;
}
}
/* Touch scrolling improvements */
.sidebar {
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
}
/* iPad-specific scrollbar styling */
@media (min-width: 768px) and (max-width: 1366px) {
.sidebar::-webkit-scrollbar {
width: 10px;
}
.sidebar::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.08);
border-radius: 5px;
margin: 0.75rem 0;
}
.sidebar::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0.25) 100%);
border-radius: 5px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.sidebar::-webkit-scrollbar-thumb:hover {
background: linear-gradient(180deg, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0.45) 100%);
}
}
/* Auto-hide scrollbar when not scrolling */
.sidebar {
overflow-y: auto;
overflow-x: hidden;
}
.sidebar:not(:hover):not(:focus-within) {
scrollbar-width: none;
}
.sidebar:not(:hover):not(:focus-within)::-webkit-scrollbar {
width: 0px;
background: transparent;
}
/* Show scrollbar on hover/focus */
.sidebar:hover::-webkit-scrollbar,
.sidebar:focus-within::-webkit-scrollbar {
width: 8px;
transition: width 0.2s ease;
}
@media (min-width: 768px) and (max-width: 1366px) {
.sidebar:hover::-webkit-scrollbar,
.sidebar:focus-within::-webkit-scrollbar {
width: 10px;
}
}
/* Active scrolling visual feedback */
.sidebar::-webkit-scrollbar-thumb:active {
background: rgba(255, 255, 255, 0.7);
transform: scale(1.1);
transition: all 0.1s ease;
}
/* Smooth scroll enhancements */
.sidebar {
scroll-padding-top: 1rem;
scroll-padding-bottom: 1rem;
}
/* Focus-visible scrollbar enhancement */
.sidebar:focus-visible::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.6);
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
}
/* Scrollbar animation on keyboard navigation */
.keyboard-navigation .sidebar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.5);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Better scrollbar visibility during navigation */
.sidebar-nav a:focus {
scroll-margin-top: 2rem;
scroll-margin-bottom: 2rem;
}
/* Initial scrollbar reveal animation */
@keyframes scrollbarReveal {
0% {
opacity: 0;
transform: translateX(10px);
}
50% {
opacity: 1;
transform: translateX(0);
}
100% {
opacity: 0.6;
transform: translateX(0);
}
}
.sidebar::-webkit-scrollbar-thumb {
animation: scrollbarReveal 3s ease-out;
}
/* Scrollbar accessibility improvements */
.sidebar[aria-label] {
scrollbar-gutter: stable;
}
/* Better contrast for users with vision difficulties */
@media (prefers-contrast: more) {
.sidebar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(255, 255, 255, 1);
}
.sidebar::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.4);
border: 1px solid rgba(255, 255, 255, 0.7);
}
}
/* Scrollbar size adjustment for different zoom levels */
@media (min-resolution: 192dpi) {
.sidebar::-webkit-scrollbar {
width: 12px;
}
.sidebar::-webkit-scrollbar-thumb {
border-radius: 6px;
}
}
.sidebar-header {
padding: 0 1rem 1.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
+71
View File
@@ -1116,9 +1116,80 @@
setupKeyboardNavigation();
}
// Enhanced scrollbar functionality
function enhanceScrollbarExperience() {
const sidebar = document.getElementById("sidebar");
if (!sidebar) return;
// Add smooth scrolling to sidebar navigation links
const navLinks = sidebar.querySelectorAll('.sidebar-nav a');
navLinks.forEach(link => {
link.addEventListener('click', (e) => {
// Smooth scroll the link into view within sidebar
setTimeout(() => {
link.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
});
}, 100);
});
});
// Enhanced keyboard navigation with scrollbar awareness
sidebar.addEventListener('keydown', (e) => {
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
setTimeout(() => {
const focusedElement = document.activeElement;
if (focusedElement && sidebar.contains(focusedElement)) {
focusedElement.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
});
}
}, 50);
}
});
// Add scroll position memory
let scrollPosition = 0;
sidebar.addEventListener('scroll', () => {
scrollPosition = sidebar.scrollTop;
});
// Restore scroll position on page reload
const savedScrollPosition = sessionStorage.getItem('sidebar-scroll-position');
if (savedScrollPosition) {
sidebar.scrollTop = parseInt(savedScrollPosition);
sessionStorage.removeItem('sidebar-scroll-position');
}
// Save scroll position before page unload
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('sidebar-scroll-position', sidebar.scrollTop.toString());
});
// Add accessibility enhancements
sidebar.setAttribute('aria-label', 'Main navigation sidebar');
sidebar.setAttribute('role', 'navigation');
// Show scrollbar briefly on focus to indicate scrollability
sidebar.addEventListener('focus', () => {
sidebar.style.scrollbarWidth = 'thin';
setTimeout(() => {
if (!sidebar.matches(':hover')) {
sidebar.style.scrollbarWidth = 'none';
}
}, 2000);
});
}
// Initialize on page load and handle layout changes
document.addEventListener('DOMContentLoaded', () => {
initializeIPadSupport();
enhanceScrollbarExperience();
// Force sidebar to be visible immediately
const sidebar = document.getElementById("sidebar");
if (sidebar && window.innerWidth > 767) {