Our npm namespace has changed. Developers should update their projects to continue accessing our components.

In-page navigation

Help users quickly understand and navigate the contents of a page.

  • Content:
    @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/spacing.variables' as spacing;
    @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/typography.variables' as typography;
    @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/font-weights.variables' as fontWeights;
    @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/font-sizes.variables' as fontSizes;
    @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/2-tools/functions/global.functions' as globalFunctions;
    @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/colours.variables' as colours;
    @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/breakpoints.variables' as breakpoints;
    
    .ontario-page-navigation {
    	border-top: 3px solid colours.$ontario-colour-black;
    	border-bottom: 3px solid colours.$ontario-greyscale-20;
    	padding: spacing.$spacing-0;
    	max-width: 46rem;
    }
    
    .ontario-page-navigation--no-top-border {
    	border-top: none;
    }
    
    .ontario-page-navigation--full {
    	border-top: 3px solid colours.$ontario-colour-black;
    	max-width: 100%;
    }
    
    .ontario-page-navigation-content {
    	padding: spacing.$spacing-7 spacing.$spacing-0;
    	max-width: 46rem;
    }
    
    .ontario-page-navigation-content--full {
    	padding-top: spacing.$spacing-7;
    	max-width: 100%;
    }
    
    .ontario-page-navigation-header {
    	@extend %h3-styles;
    	margin-bottom: spacing.$spacing-0;
    }
    
    .ontario-page-navigation-list {
    	padding: spacing.$spacing-0;
    	padding-left: spacing.$spacing-4 + globalFunctions.px-to-rem(4);
    	margin: spacing.$spacing-0;
    	margin-top: spacing.$spacing-4;
    	list-style-type: disc;
    }
    
    .ontario-page-navigation-list__item {
    	padding-bottom: spacing.$spacing-4 + globalFunctions.px-to-rem(4);
    	padding-left: spacing.$spacing-0;
    
    	& > a.ontario-page-navigation-item__link {
    		font-family: typography.$ontario-font-open-sans;
    		font-size: globalFunctions.px-to-rem(18);
    		line-height: globalFunctions.px-to-rem(25.6);
    		font-weight: fontWeights.$ontario-font-weights-semi-bold;
    		font-style: normal;
    		margin-left: spacing.$spacing-0;
    		text-decoration: none;
    
    		&:hover {
    			text-decoration: underline;
    		}
    	}
    }
    
    // Two Column Layout
    .ontario-page-navigation-columns {
    	display: flex;
    	flex-direction: row;
    
    	@media screen and (max-width: breakpoints.$small-breakpoint) {
    		flex-direction: column;
    	}
    }
    
    .ontario-page-navigation-col {
    	flex: 1;
    }
    
  • URL: /components/raw/in-page-navigation/in-page-navigation.scss
  • Filesystem Path: fractal/components/components/navigation/in-page-navigation/in-page-navigation.scss
  • Size: 2.4 KB
  • Content:
    .ontario-page-navigation-header{font-style:normal;font-weight:700;text-rendering:optimizeLegibility;margin-bottom:1rem;font-feature-settings:normal;font-family:"Raleway","Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif}.ontario-page-navigation-header{font-size:1.4375rem;letter-spacing:.02rem;line-height:1.39;margin:0 0 .75rem 0;max-width:48rem}@media screen and (min-width: 40em){.ontario-page-navigation-header{font-size:1.75rem;letter-spacing:.02rem;line-height:1.43}}.ontario-page-navigation{border-top:3px solid #1a1a1a;border-bottom:3px solid #ccc;padding:0;max-width:46rem}.ontario-page-navigation--no-top-border{border-top:none}.ontario-page-navigation--full{border-top:3px solid #1a1a1a;max-width:100%}.ontario-page-navigation-content{padding:2.5rem 0;max-width:46rem}.ontario-page-navigation-content--full{padding-top:2.5rem;max-width:100%}.ontario-page-navigation-header{margin-bottom:0}.ontario-page-navigation-list{padding:0;padding-left:1.25rem;margin:0;margin-top:1rem;list-style-type:disc}.ontario-page-navigation-list__item{padding-bottom:1.25rem;padding-left:0}.ontario-page-navigation-list__item>a.ontario-page-navigation-item__link{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:1.125rem;line-height:1.6rem;font-weight:600;font-style:normal;margin-left:0;text-decoration:none}.ontario-page-navigation-list__item>a.ontario-page-navigation-item__link:hover{text-decoration:underline}.ontario-page-navigation-columns{display:flex;flex-direction:row}@media screen and (max-width: 40em){.ontario-page-navigation-columns{flex-direction:column}}.ontario-page-navigation-col{flex:1}
  • URL: /components/raw/in-page-navigation/in-page-navigation.css
  • Filesystem Path: fractal/components/components/navigation/in-page-navigation/in-page-navigation.css
  • Size: 1.6 KB

Guiding principle: Be consistent.


About in-page navigation

This component (also known as a table of contents) consists of a list of topics that link to different topic sections on the same page.

It helps a user understand the page and navigate directly to the topic that interests them.

This guidance refers specifically to in-page contents on standard government web pages. It is not meant for a multi-page table of contents, such as those used for laws, reports or books to link to content across multiple pages.


When to use this component

There is no set recommendation for how long a page needs to be before you consider using in-page navigation.

We recommend using this component to help users:

  • quickly understand the contents of a single page
  • jump directly to the section they want to read
  • share a link to a specific section of the page

A page with multiple short sections may not need in-page navigation because a user can quickly scan the headings of the page. This component may still be useful for providing a direct link to specific sections.

Test with your users to find out if this component helps them get to the information they need.


How the navigation works

Users are most commonly confused or uncertain about whether links in this component will take them to a new page or to content on the current page they are on.

To ensure users understand that this navigation stays within the same page, set and maintain their expectations:

  • Use the heading “On this page” to differentiate this component from other link lists that take users to new pages.
  • Match the link text to the heading text so users are taken exactly where they expect to go.
  • Use smooth-scrolling to navigate to the section rather than an abrupt jump, unless your website or application cannot accommodate this interaction.
  • Show some preceding text or white space at the top of the screen so that it doesn’t look or feel like a new page.

Combine with “back to top” button

Use the in-page navigation component in combination with a Back to Top button.

The button should appear once the in-page navigation is out of view.

The button should smooth-scroll back to the top of the page, where the user can find the in-page navigation links again.

Example


Illustration of in page navigation component on mobile and the linked to content on another part of the page with the back top button that appears when the navigation is out of view.

Back button behaviour

After using in-page navigation, the browser’s back button should act as a form of “undo” and take the user to their previous location on the same page.

After using the Back to Top button, the browser’s back button should take users to the previous page in the browser history. Regular HTML anchors on web pages work this way by default.

Test this behaviour on single-page apps to ensure it behaves the same.


Best practices

Do:

  • Organize the content into sections with concise headings.
  • Place this component at the start of the page — after the lead and before the main content of the page.
  • Maintain 40px between the in-page navigation and any components above and below it.
  • Keep the text area to 8 columns within the 12-column grid.
  • Use standard design system link colours
  • Limit the list to one column. Multiple columns are not always read in the intended order.

Don’t:

  • Underline the links. The heading explains where this navigation will go and underlining can impact readability, especially on text-heavy linked lists.
  • Place in-page navigation links in an area normally used for other types of navigation (for example, the header).
  • Link to content outside of the current page.
  • Hide parts of in-page navigation.
  • List out the page links horizontally.
  • Number the list, unless you need to signify a specific order or count.

Numbered headings

If you must number your H2 headings, include the number in the heading and use a numbered list for the in-page navigation.

Otherwise, use a bulleted list for in-page navigation links.

Numbered lists may convey that something must be done in a certain order (such as steps in a process) or be used when keeping count.

Do not number the list of in-page navigation links if:

  • the H2 headings are not numbered
  • the order of the headings is irrelevant
  • the final count is irrelevant

Long Pages

When implementing in-page navigation, be mindful of the length of your page content.

A long page may be an indication that you need to break up your content across several pages instead of keeping it all on one page.

Two-column design

Upon request, we can provide a version of the in-page navigation component that displays as two columns on desktop and stacks in a single column on mobile.

This is designed for pages with 15 or more in-page navigation links.

Preferred approach

Because the two-column design does not work in a mobile layout, the preferred approach is to:

  • keep the number of in-page navigation links under 15
  • use the standard single-column design

This helps to provide a consistent experience across desktop and mobile screen sizes.


Technical specifications

Black horizontal rule

The default component includes a black horizontal rule above the “On this page” heading.

On ontario.ca pages, the built-in horizontal rule is not necessary when the in-page navigation appears immediately below:

  • a hero banner image, or
  • a title and lead that already have a horizontal rule under them

To remove the horizontal rule, add a class ontario-page-navigation--no-top-border to the in-page navigation container:

<div class="ontario-page-navigation ontario-page-navigation--no-top-border"></div>

The href attribute of an in-page navigation item should match the associated section id attribute.

Example:

In-page navigation item

<li class="ontario-page-navigation-list__item">
    <a class="ontario-page-navigation-item__link" href="#section1">  </a>
</li>

Associated section

<div id="section1">
    <h2>Section 1</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore</p>
</div>

Smooth scrolling

The smooth-scrolling animation helps users understand where they are and what they need to do to go back to where they were before.

Example JavaScript code for the smooth-scrolling behavior:

(function () {
    const links = document.querySelectorAll('.ontario-page-navigation-item__link');

    for (const link of links) {
        link.addEventListener('click', clickHandler);
    }

    function clickHandler(e) {
        e.preventDefault();

        const href = this.getAttribute('href');
        const element = document.querySelector(href);

        if (element) {
            element.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
    }
})();

The script is in scripts/toc-smooth-scroll.js.


Accessibility

Use the <nav> tag

Put the in-page navigation inside a <nav> tag to mark it as part of the page’s navigation.

This is picked up by many screen readers and can help the user navigate the page without having to go through the links one by one within the context of the page.

<main>
    <nav>
        <div class="ontario-row">
            <div class="ontario-columns ontario-small-12" style="padding: 0rem;">
                <div class="ontario-page-navigation--full">
                    <div class="ontario-page-navigation-content--full">
                        <h2 class="ontario-page-navigation-header">On this page</h2>
                        <a class="ontario-show-on-focus" href="#skip-to-main"> Skip this page navigation </a>
                        <ol class="ontario-page-navigation-list" role="navigation">
                            <li class="ontario-page-navigation-list__item">
                                <a class="ontario-page-navigation-item__link" href="#general-guidelines">General guidelines </a>
                            </li>
                            <li class="ontario-page-navigation-list__item">
                                <a class="ontario-page-navigation-item__link" href="#technical-specifications"> Technical specifications </a>
                            </li>
                            <li class="ontario-page-navigation-list__item">
                                <a class="ontario-page-navigation-item__link" href="#accessibility"> Accessibility </a>
                            </li>
                        </ol>
                    </div>
                </div>
            </div>
        </div>
    </nav>
    <div id="skip-to-main"></div>
</main>

Skip navigation

Include a visually hidden “Skip this page navigation” just after the header.

This enables screen reader and keyboard users to choose to explore this navigation or move ahead to something else.

Place the hidden “Skip this page navigation” link after the header.

<a class="ontario-show-on-focus" href="#skip-to-main">Skip this page navigation</a>

Set the id of a <div> at the end of your On this page section html to skip-to-main to help with easy navigation:

<div id="skip-to-main"></div>

If you have any questions or feedback, please get in touch.