Widget:ScrollToTopSidebar: Difference between revisions

From Bodhicitta
(Scroll-to-top button deepens its background with reading progress through the content column)
(Scroll-to-top button: darker band fills left to right with reading progress (hard edge))
Line 1: Line 1:
<style>
<style>
/* Background deepens with reading progress through the content column (--stt-a, set below). */
/* A darker band fills the button from the left as you read down the content column (--stt-p, set below). */
#scrollToTop {
#scrollToTop {
background: rgba(186, 27, 29, var(--stt-a, .08));
background: linear-gradient(to right, rgba(186, 27, 29, .3) var(--stt-p, 0%), rgba(186, 27, 29, .1) var(--stt-p, 0%));
transition: background-color .15s linear;
}
}
#scrollToTop:hover {
#scrollToTop:hover {
background: rgba(186, 27, 29, calc(var(--stt-a, .08) + .15));
background: linear-gradient(to right, rgba(186, 27, 29, .5) var(--stt-p, 0%), rgba(186, 27, 29, .3) var(--stt-p, 0%));
}
}
</style>
</style>
Line 35: Line 34:
const sttRow = container.closest('.row');
const sttRow = container.closest('.row');
const sttContent = (sttRow && sttRow.querySelector(':scope > .col-md-9')) || document.documentElement;
const sttContent = (sttRow && sttRow.querySelector(':scope > .col-md-9')) || document.documentElement;
const STT_MIN = 0.08, STT_MAX = 0.55;


function sttProgress() {
function sttProgress() {
Line 44: Line 42:
}
}


// Show/hide the button and deepen its background with scroll position
// Show/hide the button and advance its fill with scroll position
let sttTicking = false;
let sttTicking = false;
function sttUpdate() {
function sttUpdate() {
Line 50: Line 48:
if (window.pageYOffset > 300) {
if (window.pageYOffset > 300) {
scrollToTopButtonSb.style.display = 'block';
scrollToTopButtonSb.style.display = 'block';
scrollToTopButtonSb.style.setProperty('--stt-a', (STT_MIN + (STT_MAX - STT_MIN) * sttProgress()).toFixed(3));
scrollToTopButtonSb.style.setProperty('--stt-p', (sttProgress() * 100).toFixed(2) + '%');
} else {
} else {
scrollToTopButtonSb.style.display = 'none';
scrollToTopButtonSb.style.display = 'none';

Revision as of 18:18, 30 September 2026

<style> /* A darker band fills the button from the left as you read down the content column (--stt-p, set below). */

  1. scrollToTop {

background: linear-gradient(to right, rgba(186, 27, 29, .3) var(--stt-p, 0%), rgba(186, 27, 29, .1) var(--stt-p, 0%)); }

  1. scrollToTop:hover {

background: linear-gradient(to right, rgba(186, 27, 29, .5) var(--stt-p, 0%), rgba(186, 27, 29, .3) var(--stt-p, 0%)); } </style> <script> // Create the scroll to top button const scrollToTopButtonSb = document.createElement('button'); scrollToTopButtonSb.innerHTML = 'to top '; scrollToTopButtonSb.setAttribute('id', 'scrollToTop');

// Add the button to the document body const container = document.getElementById('scrollToTopContainer'); container.appendChild(scrollToTopButtonSb);

// Handle initial hash navigation window.addEventListener('load', () => { if (window.location.hash) { setTimeout(() => { const element = document.querySelector(window.location.hash); if (element) { element.scrollIntoView({ behavior: 'smooth' }); } }, 100); } });

// Progress is measured through the main content column beside the sidebar // (the .col-md-9 sibling), falling back to the whole page. const sttRow = container.closest('.row'); const sttContent = (sttRow && sttRow.querySelector(':scope > .col-md-9')) || document.documentElement;

function sttProgress() { const rect = sttContent.getBoundingClientRect(); const range = rect.height - window.innerHeight; if (range <= 0) return 1; return Math.min(1, Math.max(0, -rect.top / range)); }

// Show/hide the button and advance its fill with scroll position let sttTicking = false; function sttUpdate() { sttTicking = false; if (window.pageYOffset > 300) { scrollToTopButtonSb.style.display = 'block'; scrollToTopButtonSb.style.setProperty('--stt-p', (sttProgress() * 100).toFixed(2) + '%'); } else { scrollToTopButtonSb.style.display = 'none'; } } window.addEventListener('scroll', () => { if (!sttTicking) { sttTicking = true; window.requestAnimationFrame(sttUpdate); } }, { passive: true });

// Scroll to top when the button is clicked scrollToTopButtonSb.addEventListener('click', () => { window.scrollTo({ top: 0, behavior: 'smooth' }); }); </script>