Enhance Your Ghost Blog with Smooth Scrolling Navigation

Enhance Your Ghost Blog with Smooth Scrolling Navigation

Introduction

If you're looking to improve the user experience on your blog, adding smooth scrolling navigation can help your readers quickly jump to the top or bottom of the page—or even scroll up or down by one viewport at a time. In this guide, I'll show you how to integrate four helpful buttons into your Ghost blog:

  • Scroll-to-Top: Quickly scroll to the top of the page.
  • Page-Up: Scroll up by one viewport height.
  • Page-Down: Scroll down by one viewport height.
  • Scroll-to-Bottom: Quickly scroll to the bottom of the page.

These buttons are designed to appear only when needed, keeping your interface clean and unobtrusive.

How to Integrate the Buttons in Ghost

Ghost offers two main approaches to adding custom functionality without too much hassle:

1. Using Ghost's Code Injection

This is the quickest way to add the functionality. With Code Injection, you can add custom code site‑wide without editing your theme files. To do this:

  1. Log in to your Ghost Admin.
  2. Navigate to Settings → Code Injection.
  3. Paste the entire code snippet (shown below) into the Site Footer field.
  4. Save your changes and refresh your blog. The buttons should now appear and work as described.

2. Modifying Your Theme Files

If you prefer a more permanent solution or want greater control over placement, you can directly add the code to your theme files. This method requires you to:

  1. Download your active theme.
  2. Edit the footer partial (for example, default.hbs or footer.hbs), and paste the code snippet just before the closing </body> tag.
  3. Zip and re-upload your theme via Ghost Admin → Design.
  4. Activate the updated theme.

The Code Explained

Below is the complete code snippet—CSS and JavaScript—along with detailed comments. This code creates the buttons dynamically, defines the scrolling functions, and toggles their visibility based on the scroll position.

<!-- 
  Paste this entire block into Ghost Admin → Settings → Code Injection (Site Footer) 
  OR insert it into your theme's footer file before </body>.
-->

<style>
  /* Scroll-to-top button (top group)
     Positioned at the top-right corner; shows an upward arrow.
  */
  #scrollToTopBtn {
    position: fixed;
    top: 20px;
    right: 20px;
    width: 50px;
    height: 50px;
    background-color: #000;
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 24px;
    cursor: pointer;
    display: none; /* Initially hidden */
    justify-content: center;
    align-items: center;
    transition: opacity 0.3s ease-in-out;
  }
  #scrollToTopBtn:hover {
    background-color: #444;
  }
  #scrollToTopBtn.show {
    display: flex;
    opacity: 1;
  }

  /* Page-up button (top group)
     Positioned just below the scroll-to-top button.
  */
  #pageUpBtn {
    position: fixed;
    top: 80px; /* 60px below the scroll-to-top button */
    right: 20px;
    width: 50px;
    height: 50px;
    background-color: #000;
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 20px;
    cursor: pointer;
    display: none;
    justify-content: center;
    align-items: center;
    transition: opacity 0.3s ease-in-out;
  }
  #pageUpBtn:hover {
    background-color: #444;
  }
  #pageUpBtn.show {
    display: flex;
    opacity: 1;
  }

  /* Page-down button (bottom group)
     Positioned above the scroll-to-bottom button.
  */
  #pageDownBtn {
    position: fixed;
    bottom: 80px; /* 60px above the scroll-to-bottom button */
    right: 20px;
    width: 50px;
    height: 50px;
    background-color: #000;
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 20px;
    cursor: pointer;
    display: none;
    justify-content: center;
    align-items: center;
    transition: opacity 0.3s ease-in-out;
  }
  #pageDownBtn:hover {
    background-color: #444;
  }
  #pageDownBtn.show {
    display: flex;
    opacity: 1;
  }

  /* Scroll-to-bottom button (bottom group)
     Positioned at the bottom-right corner; shows a downward arrow.
  */
  #scrollToBottomBtn {
    position: fixed;
    bottom: 20px;
    right: 20px;
    width: 50px;
    height: 50px;
    background-color: #000;
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 24px;
    cursor: pointer;
    display: none;
    justify-content: center;
    align-items: center;
    transition: opacity 0.3s ease-in-out;
  }
  #scrollToBottomBtn:hover {
    background-color: #444;
  }
  #scrollToBottomBtn.show {
    display: flex;
    opacity: 1;
  }
</style>

<script>
document.addEventListener("DOMContentLoaded", function() {
  // Create the scroll-to-top button (top group)
  let scrollToTopBtn = document.createElement("button");
  scrollToTopBtn.id = "scrollToTopBtn";
  scrollToTopBtn.innerHTML = "&#8679;"; // Up arrow icon
  scrollToTopBtn.onclick = scrollToTop;
  document.body.appendChild(scrollToTopBtn);

  // Create the page-up button (top group)
  let pageUpBtn = document.createElement("button");
  pageUpBtn.id = "pageUpBtn";
  pageUpBtn.innerHTML = "PgUp"; // Label for page up
  pageUpBtn.onclick = pageUp;
  document.body.appendChild(pageUpBtn);

  // Create the page-down button (bottom group)
  let pageDownBtn = document.createElement("button");
  pageDownBtn.id = "pageDownBtn";
  pageDownBtn.innerHTML = "PgDn"; // Label for page down
  pageDownBtn.onclick = pageDown;
  document.body.appendChild(pageDownBtn);

  // Create the scroll-to-bottom button (bottom group)
  let scrollToBottomBtn = document.createElement("button");
  scrollToBottomBtn.id = "scrollToBottomBtn";
  scrollToBottomBtn.innerHTML = "&#8681;"; // Down arrow icon
  scrollToBottomBtn.onclick = scrollToBottom;
  document.body.appendChild(scrollToBottomBtn);

  // Function to smoothly scroll to the top of the page
  function scrollToTop() {
    window.scrollTo({ top: 0, behavior: "smooth" });
  }
  // Function to smoothly scroll to the bottom of the page
  function scrollToBottom() {
    window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" });
  }
  // Function to scroll up by one viewport height
  function pageUp() {
    window.scrollBy({ top: -window.innerHeight * 0.80, behavior: "smooth" });
  }
  // Function to scroll down by one viewport height
  function pageDown() {
    window.scrollBy({ top: window.innerHeightt * 0.80, behavior: "smooth" });
  }

  // Toggle button visibility based on scroll position
  window.onscroll = function() {
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    let scrollBottom = window.innerHeight + scrollTop;
    let totalHeight = document.body.scrollHeight;

    // Top group: show when scrolled more than 300px from the top
    if (scrollTop > 300) {
      scrollToTopBtn.classList.add("show");
      pageUpBtn.classList.add("show");
    } else {
      scrollToTopBtn.classList.remove("show");
      pageUpBtn.classList.remove("show");
    }
    // Bottom group: show when not within 300px of the bottom
    if (scrollBottom < totalHeight - 300) {
      pageDownBtn.classList.add("show");
      scrollToBottomBtn.classList.add("show");
    } else {
      pageDownBtn.classList.remove("show");
      scrollToBottomBtn.classList.remove("show");
    }
  };
});
</script>

Why This Approach Works

  • Easy Integration: Using Ghost's Code Injection, you can add this functionality across your entire site without modifying your theme files. Paste the code into the Site Footer, which will load on every page.
  • Modular Code: The CSS is fully commented, so you understand how each button is styled and positioned. The JavaScript is divided into precise functions that handle scrolling actions and toggle the visibility of the buttons. This makes the code easy to adjust and maintain.
  • Improved User Experience: The scroll buttons help readers quickly navigate long posts. The page‑up and page‑down functions let users move by one viewport height, while the scroll‑to‑top and scroll‑to‑bottom buttons provide instant navigation to the top or bottom of the page.
  • Conditional Visibility: The buttons appear only when needed (for example, when you've scrolled more than 300px from the top or are not near the bottom), ensuring that your interface remains clean and unobtrusive.
  • Two Integration Methods: Code Injection: Ideal for a quick setup that applies site‑wide without altering your theme files.
  • Editing Your Theme Files: A more permanent solution that gives you greater control over placement and design, though it requires re-uploading your theme.

Conclusion

Integrating smooth scrolling navigation on your Ghost blog improves the overall user experience and makes your site feel more interactive and modern. Whether you use Ghost's Code Injection for a quick solution or modify your theme for a more permanent integration, the provided code snippet is easy to implement and customise.

Feel free to better adjust the CSS or JavaScript to suit your blog's design and readers' needs. Happy coding and happy blogging!

You can now publish this article on your Ghost blog and share your enhanced navigation solution with your audience. Enjoy the improved user experience!