ng-scroll-nav
Introduction
ng-scroll-nav is a standalone, reusable and customizable component for Angular 18, 19 and 20.
It is designed to work with signals and Angular zoneless, providing a lightweight, flexible, and accessible scrollable nav. It is also fully compatible with SSR, CSR and prerender.
Installation
If you want to install the latest version (currently 20):
npm install ng-scroll-nav
Angular 19:
npm install ng-scroll-nav@v19-lts
Angular 18:
npm install ng-scroll-nav@v18-lts
Overview
The main feature of ng-scoll-nav is its scrolling functionality: if all the elements you add fit within the component, you'll have a normal navigation bar. Otherwise, the component becomes scrollable.
This component works especially well with our ng-link-button component
Using ng-scroll-nav is easy:
- Provide the links you need as children of the component.
- Configure its style, behavior, and accessibility using inputs.
- Style it with customizable CSS variables to match your design needs.
Here’s a basic usage example:
import { NgScrollNav } from 'ng-scroll-nav';
import { NgLinkButton } from 'ng-link-button';
@Component({
selector: 'app-root',
standalone: true,
imports: [NgScrollNav, NgLinkButton],
template: `
<ng-scroll-nav>
<ng-link-button [square]="true">
Link 1
</ng-link-button>
<ng-link-button [square]="true">
This is Link 2
</ng-link-button>
<ng-link-button [square]="true">
Another Link 3
</ng-link-button>
<ng-link-button [square]="true">
Link 4
</ng-link-button>
</ng-scroll-nav>
`,
})
Functionality
As shown in the example below, you just have to add link elements as children of ng-scroll-nav. Yo can use our ng-link-button or an < a > tag if you prefer.
You can control the scrolling behavior using the [scrollStep] and scrollBehavior inputs (see Inputs and Outputs) section below.
<ng-scroll-nav [scrollStep]="200" scrollBehavior="auto">
<ng-link-button>
Link 1
</ng-link-button>
<ng-link-button>
This is Link 2
</ng-link-button>
</ng-scroll-nav>
Inputs and Outputs
Here is a list of all input/ouput:
Scroll inputs
| Input | Description | Default |
|---|---|---|
| scrollStep | Pixels that the scroll moves when you press an arrow | 150 |
| scrollBehavior | Scroll behavior (auto or smooth). | 'smooth' |
Accessibility Inputs
| Input | Description | Default |
|---|---|---|
| lang | Select the language for accessibility | 'en' |
| customAria | Set up your own custom aria attributes (more info below) | null |
Styling
You can easily customize the component’s appearance using the CSS variables listed below.
ng-scroll-nav{
--scroll-nav-justify-content: center;
--scroll-nav-arrow-size: 1rem;
}
| Variable | Description | Default |
|---|---|---|
| --scroll-nav-bg | Background color of the scrollable navigation (host and arrow icons). | inherit |
| --scroll-nav-color | Main text and icon color of the scrollable navigation. | host: inherit / arrows: currentColor |
| --scroll-nav-arrow-size | Width and height of the navigation arrow icons. | 1.4rem |
| --scroll-nav-justify-content | Defines the justify-content alignment for the scrollable container. | start |
| --scroll-nav-gap | Spacing (gap) between items inside the scrollable content area. | 0 |
Accessibility
There are two ways of setting the aria-label attributes: by lang attribute or by customAria attribute (See Accessibility Inputs at Inputs and Outputs section)
If needed, you can import ScrollNavLangs and ScrollNavCustomAria types like this:
import { ScrollNavLangs, ScrollNavCustomAria } from 'ng-scoll-nav';
'lang' attribute:
The component includes five predefined languages for accessibility labels that you can set easily with the lang attribute:
Laguages can be: english (en), spanish (es), italian (it), french (fr) or deutch (de)
*** We recommend using the lang attribute if you don't need any other languages than the ones provided by default. It's simple and compliant with WAI-ARIA standards. ***
<ng-scroll-nav lang="es" />
💡 If no value is provided in lang, the default language is English (en).
💡 If your application supports multiple languages, you can bind the lang attribute to a signal and link it with a select, for example.
'customAria' attribute:
In addition to the predefined languages available through the lang attribute, you can fully customize the ARIA labels for your menu button by using the customAria input.
This option gives you full control over the text announced by screen readers when the menu is opened or closed — perfect for custom translations, accessibility improvements, or when you want to use a language that is not included in the predefined set.
Here is the exact declaration of the ScrollNavCustomAria type:
export interface ScrollNavCustomAria {
navAriaLabel?: string;
prevBtnAriaLabel?: string;
nextBtnAriaLabel?: string;
linksGroupAriaLabel?: string;
};
| Property | Description |
|---|---|
| globalAriaLabel | aria-label for the global container. Useful to indicate that the user has entered a carousel component. |
| globalRoleDescription | Describes the role of the carousel region (e.g., “carousel” or “image gallery”) to assistive technologies. |
| prevBtnAriaLabel | Label for the “previous” navigation button. Communicates its purpose to screen readers. |
| nextBtnAriaLabel | Label for the “next” navigation button. Communicates its purpose to screen readers. |
| trackRoleDescription | Describes the carousel track region that contains the sliding items (e.g., “list of items”). |
| trackAriaLabel | Label for the carousel track. Can be used to describe what the list contains (e.g., “featured products”). |
| rangeMessage | Function that returns a message indicating the current visible item range in relation to the total (e.g., “Showing items 1–3 of 10”). Useful for providing dynamic feedback to screen readers. |
Example of usage:
import { NgScrollNav, ScrollNavCustomAria } from 'ng-scroll-nav';
@Component({
imports: [NgScrollNav],
template: `
<ng-scroll-nav lang="en" [customAria]="accOpts()">
<ng-link-button [square]="true">
Link 1
</ng-link-button>
<ng-link-button [square]="true">
This is Link 2
</ng-link-button>
</ng-scroll-nav>
`
})
class App {
accOpts = signal<ScrollNavCustomAria>({
navAriaLabel: 'EDITED navAriaLabel',
prevBtnAriaLabel: 'EDITED prevBtnAriaLabel',
nextBtnAriaLabel: 'EDITED nextBtnAriaLabel',
linksGroupAriaLabel: 'EDITED linksGroupAriaLabel',
});
}
💡 Remember that what is indicated in the customAria attribute replaces the default language set in lang.
💡 If you only set one of the properties, the other will use the label from the current lang.