Scrolling text ticker using only pure CSS and JS

December 4, 2025

This tiny snippet injects a scrolling text ticker along the bottom of your site. It’s perfect for quick announcements, promos, or “what’s new” messages. It:

  • Auto-creates a bottom bar with your message
  • Scrolls text smoothly from right to left
  • Pauses the animation when the user hovers it
  • Respects prefers-reduced-motion so accessibility stays solid
  • Uses no frameworks and no external CSS
<style>
  /* Bottom-of-page scrolling ticker
     - Auto-injected via JS
     - Fixed to bottom, full-width
     - Pauses on hover
   */

  .vibe-ticker-bar {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 9999;
    overflow: hidden;
    background: #111;
    color: #fff;
    font: 13px/1.5 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  }

  .vibe-ticker-inner {
    display: inline-flex;
    white-space: nowrap;
    will-change: transform;
    animation: vibe-ticker-scroll var(--vibe-ticker-speed, 24s) linear infinite;
  }

  .vibe-ticker-bar:hover .vibe-ticker-inner {
    animation-play-state: paused;
  }

  .vibe-ticker-item {
    padding: 6px 18px;
    border-inline-end: 1px solid rgba(255, 255, 255, 0.25);
  }

  .vibe-ticker-label {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 11px;
    margin-right: 10px;
    opacity: 0.8;
  }

  .vibe-ticker-text {
    font-weight: 400;
  }

  @keyframes vibe-ticker-scroll {
    0% {
      transform: translateX(0);
    }
    100% {
      transform: translateX(-50%);
    }
  }

  /* Respect users who prefer less motion */
  @media (prefers-reduced-motion: reduce) {
    .vibe-ticker-inner {
      animation: none;
      transform: none !important;
    }
  }
</style>

<script>
  // Tiny bottom-of-page scrolling ticker
  // Drop this near the end of your <body> on pages where you want it.

  (function () {
    // If you already added one on the page, don't add another
    if (document.querySelector(".vibe-ticker-bar")) return;

    // Customize this array with your own messages
    var messages = [
      "New: lightweight stats & referrer tracking scripts.",
      "Highlight your latest script, tool, or launch here.",
      "Copy-paste tools for real-world webmasters, not SaaS dashboards.",
      "Keep your pages fast, simple, and under your control."
    ];

    // Speed in seconds for one full loop
    var speedSeconds = 26;

    // Create main bar
    var bar = document.createElement("div");
    bar.className = "vibe-ticker-bar";
    bar.setAttribute("role", "status");
    bar.setAttribute("aria-label", "Site updates ticker");

    // Inner scrolling container
    var inner = document.createElement("div");
    inner.className = "vibe-ticker-inner";
    inner.style.setProperty("--vibe-ticker-speed", speedSeconds + "s");

    // Helper to build one "run" of all messages
    function buildRun() {
      var frag = document.createDocumentFragment();

      messages.forEach(function (msg) {
        var item = document.createElement("div");
        item.className = "vibe-ticker-item";

        var label = document.createElement("span");
        label.className = "vibe-ticker-label";
        label.textContent = "Update";

        var text = document.createElement("span");
        text.className = "vibe-ticker-text";
        text.textContent = " " + msg;

        item.appendChild(label);
        item.appendChild(text);

        frag.appendChild(item);
      });

      return frag;
    }

    // We duplicate the run so the animation can loop seamlessly
    inner.appendChild(buildRun());
    inner.appendChild(buildRun());

    bar.appendChild(inner);

    // Wait until DOM is ready enough to attach
    function attach() {
      if (!document.body) {
        setTimeout(attach, 50);
        return;
      }
      document.body.appendChild(bar);
    }

    attach();
  })();
</script>

How to use it

Paste the whole snippet (the <style> and <script> block) near the end of your <body> on any page where you want the ticker to appear. You don’t need to add any HTML manually – the JavaScript injects the ticker bar for you.

Customizing the messages

Edit the messages array inside the script:

  • Add or remove strings as needed
  • Include emojis like 🔥, 📈, 🎯 to match your niche
  • Update the copy to announce new posts, features, or promos

Adjusting speed and behavior

The speedSeconds variable controls how fast a full scroll loop takes. A higher number is slower; a lower number is faster. You can also:

  • Change background and text colors in the CSS for dark or light sites
  • Increase the font-size if you want a louder banner
  • Remove the :hover pause rule if you want it to always scroll

Because it’s a single self-contained snippet with no dependencies, it’s easy to drop into landing pages, tools, or blogs whenever you want a little extra motion and a simple way to broadcast updates across your site.

Comments (0)

No comments yet — be the first.

← Back to all scripts