Dynamic ‘section navigation’ with the ‘Page list’ block and CSS

Written by Keith Devon on March 31, 2025


On our recent project building the Kimbolton School website, we were tasked with creating a navigation block that would be shown on most pages on the site.

This navigation would:

The final results

Before we start, I want to show you what we’re aiming for. The following images show the menu on the Kimbolton School website.

We won’t be copying the exact styling, just the functionality of showing the correct pages.

Current page: ‘About us‘ (top-level)

Current page: ‘Our people‘ (child of ‘About us’)

Current page: ‘Governors‘ (grandchild of ‘About us’)

Choosing the right block

After discussing a few different options, including building a custom block, we realised that we could use the ‘Page list’ block.

The ‘Page list’ block allows you to select the parent page, which will show all of the children, so we initially dismissed it.

However, we realised that we could output all of the pages in the website (by not selecting a parent page) and then use CSS to show only the pages that we wanted to. This post will show you how.

Creating the pattern

First we added a ‘Page list’ block to a page. Then we gave it a custom class of .in-this-section so that we specifically style this version. To make it even more user-friendly for our client, we then created a pattern called ‘Section nav’ so that they could drop this onto any page without having to manually add the class.

The first thing to do is to hide all of the list items in the ‘Page list’ block.

.in-this-section .wp-block-pages-list__item {
    display: none;
}

Now we can start to add the pages to our menu that we want to display. Let’s start with the current page.

Showing the current page

We want to show the current page and it’s ancestors.

To show the current page, you could do:

.in-this-section .current-menu-item {
    display: block;
}

That will work if you’re on a top-level page. But if you’re on a child page, it’ll be nested within another page, which will still be hidden. So we need to make sure that all ancestor pages are also displayed:

.in-this-section .current-menu-item,
.in-this-section .current-menu-ancestor {
    display: block;
}

That’s better. Now, if we’re on a child page, we can see the parent page and the current page. It even works as you move down the levels into grand child pages.

But we can’t see child pages yet. Let’s fix that.

Child pages

Sub menus (the nested lists) are given the .wp-block-navigation__submenu-container class. The first thing that we need to do is to hide these by default.

.in-this-section .wp-block-navigation__submenu-container {
    display: none;
}

Now, like before, we can target the ones that we want to display using the built-in class system.

First, let’s show the submenu containers for the current menu item:

.in-this-section .current-menu-item > .wp-block-navigation__submenu-container {
    display: block;
}

Now the container is being displayed, but all of the list items within it are still being hidden. Let’s show those too:

.in-this-section .current-menu-item .wp-block-pages-list__item {
  display: block;
}

This is working well if we’re on a top-level page, but once we’re further down the page tree, we’re only seeing the top level page displayed in the menu. That’s because we’re only displaying the submenu container of the current page, and not the ancestor pages. Let’s fix that now by adding to the rule above:

.in-this-section .current-menu-ancestor > .wp-block-navigation__submenu-container,
.in-this-section .current-menu-item .wp-block-pages-list__item {
  display: block;
}

Nice, we are now displaying the menu items that we want to display. i.e. The current page, and the current page’s children and ancestors.

Highlighting the current page

It’s good user experience to highlight the current page that we’re on, so let’s do that now.

.in-this-section  .current-menu-item > .wp-block-pages-list__item__link {
  font-weight: bold;
}

Of course, you can style this any way you like, it doesn’t have to be bold text.

The full CSS

And that’s it! A dynamic page menu system using only the ‘Page list’ block.

Here’s the CSS in full:

.in-this-section .wp-block-pages-list__item {
    display: none;
}

.in-this-section .current-menu-item,
.in-this-section .current-menu-ancestor,
.in-this-section .current-menu-ancestor .wp-block-pages-list__item {
    display: block;
}

.in-this-section .wp-block-navigation__submenu-container {
    display: none;
}

.in-this-section .current-menu-item > .wp-block-navigation__submenu-container {
    display: block;
}

.in-this-section .current-menu-ancestor > .wp-block-navigation__submenu-container,
.in-this-section .current-menu-item .wp-block-pages-list__item {
  display: block;
}

.in-this-section  .current-menu-item > .wp-block-pages-list__item__link {
  font-weight: bold;
}

I hope you found that useful! If you have any thoughts, criticisms, or improvements please let me know.