Headline Theme Scroll To Top Button

Anyone looking to add a scroll to top button to the Headline Theme, here is the code I used to get it working.
Capture3

I injected the following code into the header

<style>
    /*Scroll to Top CSS*/
    .scroll-top {
		position: fixed;
 		z-index: 50;
		padding: 0;
		right: 30px;
		bottom: 100px;
		opacity: 0;
		visibility: hidden;
		transform: translateY(15px);    
		height: 46px;
		width: 46px;
		cursor: pointer;
		display: flex;
  		align-items: center;
  		justify-content: center;
		border-radius: 50%;
  	transition: all .4s ease;
  	border: none;
  	box-shadow: inset 0 0 0 2px #ccc;
  	color: #ccc;
  	background-color: #fff;
	}

	.scroll-top.is-active {
		opacity: 1;
  		visibility: visible;
  		transform: translateY(0);
	}

	.scroll-top .icon-tabler-arrow-up {
  		position: absolute;
  		stroke-width: 2px;
  		stroke: #333;
	}

	.scroll-top svg path { 
		fill: none; 
	}

	.scroll-top svg.progress-circle path {
		stroke: #333;
		stroke-width: 4;
  		transition: all .4s ease;
	}

	.scroll-top:hover {
  		color: var(--ghost-accent-color);
	}

	.scroll-top:hover .progress-circle path, .scroll-top:hover .icon-tabler-arrow-up {
  		stroke: var(--ghost-accent-color);
	}
          
</style>

<!--   Scroll Top Button  -->
    <button class="btn-toggle-round scroll-top js-scroll-top" type="button" title="Scroll to top">
      <svg class="progress-circle" width="100%" height="100%" viewBox="-1 -1 102 102">
        <path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98"/>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-up" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="cuurentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
        <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
        <line x1="12" y1="5" x2="12" y2="19" />
        <line x1="18" y1="11" x2="12" y2="5" />
        <line x1="6" y1="11" x2="12" y2="5" />
      </svg>
    </button>

I injected the following script into the footer

<script>
    /*Scroll to Top*/
const scrollTopBtn = document.querySelector('.js-scroll-top');
if (scrollTopBtn) {
  scrollTopBtn.onclick = () => {
    window.scrollTo({top: 0, behavior: 'smooth'});
  }
  
  const progressPath = document.querySelector('.scroll-top path');
  const pathLength = progressPath.getTotalLength();
  progressPath.style.transition = progressPath.style.WebkitTransition = 'none';
  progressPath.style.strokeDasharray = `${pathLength} ${pathLength}`;
  progressPath.style.strokeDashoffset = pathLength;
  progressPath.getBoundingClientRect();
  progressPath.style.transition = progressPath.style.WebkitTransition = 'stroke-dashoffset 10ms linear';		
  const updateProgress = function() {
    const scroll = window.scrollY || window.scrollTopBtn || document.documentElement.scrollTopBtn;

    const docHeight = Math.max(
      document.body.scrollHeight, document.documentElement.scrollHeight,
      document.body.offsetHeight, document.documentElement.offsetHeight,
      document.body.clientHeight, document.documentElement.clientHeight
    );

    const windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

    const height = docHeight - windowHeight;
    var progress = pathLength - (scroll * pathLength / height);
    progressPath.style.strokeDashoffset = progress;
  }

  updateProgress();
  const offset = 100;

  window.addEventListener('scroll', function(event) {
    updateProgress();

    //Scroll back to top
    const scrollPos = window.scrollY || window.scrollTopBtn || document.getElementsByTagName('html')[0].scrollTopBtn;
    scrollPos > offset ? scrollTopBtn.classList.add('is-active') : scrollTopBtn.classList.remove('is-active');

  }, false);
}
</script>

Original source can be found here. I just modified it to work with the headline theme.

3 Likes

I had no expectation that this would work. I just copy-pasted the code into the header and footer, just like you said, and it worked great! Thank you!

It works perfectly. Thanks a lot!

This works like a charm on the Headline theme.

What code would I add to only enable this on posts? So it doesn’t appear on section pages, homepage, etc.?

I’m new to Ghost (and CSS, etc.) so any quick/easy tweak would be appreciated.

Many thanks!

You can add the following in the <style> tag:

body:not(.post-template) .scroll-top { display: none; }

I’ll extend the original blog post to include that:

1 Like