Simple Way to Add Dropdowns to Blogger Menu

Give Blogger’s built-it menu gadget a little glow-up with dropdowns. No messy HTML, just simple tweaks that work

Girl with kanban, Generated with Gemini

Blogger’s built-in navigation is great for what it is — clean, simple, and easy to manage. It gets the job done without making you overthink. The only catch is, the built-in navigation doesn’t come with dropdown support.

For small blogs, that’s fine. But once you start grouping posts under categories, it feels like hitting a wall. Most people end up switching to a custom HTML menu for more control. But, not everyone wants to dig through code every time they need to add a new link.

So here’s the sweet spot! Stick with Blogger’s Pages gadget, but give it a little JavaScript boost. That way, you keep things simple while unlocking dropdown functionality that feels native.

Before we dive in, a few notes first:

  1. The JavaScript only handles the dropdown animation.
  2. We’ll add a bit of CSS to make it behave properly, but how it looks depends on your overall theme styling.
  3. To define submenus, we’ll use the symbol in your menu item — that’s how the script knows which items are children.

Alright, let’s get to it.

Step 1: Add the JavaScript

Add this script right before your closing </body> tag. It’s the brain of the dropdown system.

<script>
//<![CDATA[
document.addEventListener('DOMContentLoaded', () => {
  // Define the parent element
  const menu = document.querySelector('.widget.PageList > ul');
  if (!menu) return;

  const items = Array.from(menu.children);
  let lastParent = null;

  items.forEach(li => {
    const link = li.querySelector('a');
    if (!link) return;

    let text = link.textContent.trim();

    // Define the child
    if (/^↳\s*/.test(text)) {
      if (!lastParent) return;

      text = text.replace(/^↳\s*/, '').trim();
      link.textContent = text;

      let submenu = lastParent.querySelector('ul.submenu');
      if (!submenu) {
        submenu = document.createElement('ul');
        submenu.className = 'submenu';
        lastParent.classList.add('has-sub');
        lastParent.appendChild(submenu);

        // added toggle button for mobile
        const toggleBtn = document.createElement('button');
        toggleBtn.className = 'toggle';
        toggleBtn.type = 'button';
        toggleBtn.setAttribute('aria-label', 'Toggle submenu');
        lastParent.appendChild(toggleBtn);

        // Binding parent with the button
        const parent = lastParent;
        toggleBtn.addEventListener('click', e => {
          e.stopPropagation();
          parent.classList.toggle('open');
        });
      }

      submenu.appendChild(li);
    } else {
      lastParent = li;
    }
  });

  // Ensure hover behavior only active on mobile
  const mediaQuery = window.matchMedia('(min-width: 681px)');
  function updateHoverBehavior(e) {
    const isDesktop = e.matches;
    document.querySelectorAll('.has-sub').forEach(item => {
      item.removeEventListener('mouseenter', show);
      item.removeEventListener('mouseleave', hide);
      if (isDesktop) {
        item.addEventListener('mouseenter', show);
        item.addEventListener('mouseleave', hide);
      }
    });
  }

  function show() { this.classList.add('open'); }
  function hide() { this.classList.remove('open'); }

  mediaQuery.addEventListener('change', updateHoverBehavior);
  updateHoverBehavior(mediaQuery);
});
//]]>
</script>

What this script does:

  1. It finds the container that holds your navigation links.
  2. Detects the symbol, then adds a toggle icon and binds dropdown actions to the parent menu.
  3. Keeps hover effects active only on desktop, so mobile users don’t get weird tap behavior.

Step 2: Add a bit of CSS

This CSS is needed to animate the dropdown smoothly. It doesn’t style the navigation much but just controls how the dropdown slides open and closes.

.PageList .has-sub {
  position: relative;
  padding-right: 30px;
}
.PageList .has-sub .submenu {
  position: absolute;
  left: 50%;
  top: 35px;
  transform: translateX(-50%);
  width: 180px;
  background: white;
  padding: 15px;
  flex-direction: column;
  color: black;
  gap: 10px;
  opacity: 0;
  visibility: hidden;
  transition: all .3s;
  border: 1px solid rgba(0,0,0, 0.1);
  box-shadow: 5px 10px 10px rgba(0,0,0, 0.2);
}
.PageList .has-sub.open .submenu {
  visibility: visible;
  opacity: 1;
}
.PageList .has-sub .submenu a {
  color: black;
}
.PageList .has-sub .toggle {
  display: block;
  width: 24px;
  height: 24px;
  background: none;
  position: absolute;
  top: 0;
  right: 0;
  padding: 0;
  border: 0;
  display: none;
}
.PageList .has-sub .toggle::after {
  content: "▼";
  font-weight: normal;
  line-height: 150%;
  text-align: center;
  font-size: 1em;
  color: white;
  text-indent: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Also, here's the responsive tweaks, so everything runs properly on mobile screens too.

@media screen and (max-width: 480px) {
  .PageList .has-sub {
    padding-right: 0;
  }
  .PageList .has-sub .submenu a {
    font-size: 1rem;
    line-height: 150%;
    text-transform: unset;
    opacity: 0.7;
  }
  .PageList .has-sub .toggle {
    right: 0;
    display: block;
  }
  .PageList .has-sub .submenu {
    background: none;
    top: 15px;
    transition: none;
    width: 100%;
    left: 0;
    transform: none;
  }
  .PageList .has-sub.open .submenu {
    position: relative;
  }
}

Step 3: Add Child Menus in Blogger

Now for the fun part.

If you want to add a child menu item, simply add the symbol in front of the Page name field inside the Pages gadget. For example:

The script automatically recognizes it as a child item and tucks it neatly under its parent, which is the Gallery menu from the image above. Easy as that.

And that’s it! You’ve just upgraded your Blogger navigation without ditching the native Pages widget. 

Found a typo or error in this article? Let us know here and we’ll get it fixed ✅