---
area: "Learn"
parent: "Links chapter"
url: "https://unpoly.com/learn/navigation-bars"
---
<nav aria-label="Unpoly docs">[All docs](https://unpoly.com/index.md) · [Links chapter](https://unpoly.com/learn/links.md)</nav>

# Navigation bars

Unpoly marks links in navigation bars with an [`.up-current`](https://unpoly.com/api/up-current.md) class when they point to the current location.

Style that class with your CSS to highlight the current section in a menu.

<nav aria-label="Contents">

#### Contents

- [Marking links as current](#marking-links-as-current)
- [Defining navigational containers](#navigational-containers)
- [Styling current links](#styling)
- [Matching the current location](#matching-urls)
- [Accessibility considerations](#accessibility-considerations)
- [Updating `.up-current` classes](#updating-up-current-classes)

</nav>

## Marking links as current {#marking-links-as-current}

Let's look at a simple menu with two links:

```html
<nav>
  <a href="/foo">Foo</a>
  <a href="/bar">Bar</a>
</nav>
```

When the browser location changes to `/foo`, the first link is automatically marked as [`.up-current`](https://unpoly.com/api/up-current.md):

```html
<nav>
  <a href="/foo" class="up-current">Foo</a>
  <a href="/bar">Bar</a>
</nav>
```

Unpoly doesn't style [`.up-current`](https://unpoly.com/api/up-current.md) links by default, but we can [style highlighted links](https://unpoly.com/learn/navigation-bars.md#styling) using CSS.

When the browser location changes to `/bar`, the first link loses its [`.up-current`](https://unpoly.com/api/up-current.md) class.
Now the second link is automatically marked as [`.up-current`](https://unpoly.com/api/up-current.md):

```html
<nav>
  <a href="/foo">Foo</a>
  <a href="/bar" class="up-current">Bar</a>
</nav>
```

## Defining navigational containers {#navigational-containers}

The [`.up-current`](https://unpoly.com/api/up-current.md) class is applied to all links within a _navigational container_.

Standard [`<nav>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav) elements are always considered navigational containers:

```html
<nav>
  <a href="/foo">Foo</a>
  <a href="/bar">Bar</a>
</nav>
```

If you cannot use a `<nav>` element, you can also set the [`[up-nav]`](https://unpoly.com/api/up-nav.md) attribute on an arbitrary tag instead:

```html
<div up-nav>
  <a href="/foo">Foo</a>
  <a href="/bar">Bar</a>
</div>
```

You may also assign [`[up-nav]`](https://unpoly.com/api/up-nav.md) to an individual link instead of a navigational container:

```html
<a href="/foo" up-nav>Foo</a>
```

Matching containers can opt _out_ of [`.up-current`](https://unpoly.com/api/up-current.md) assignment by setting an `[up-nav=false]` attribute:

```html
<nav up-nav="false">
  <a href="/foo">Foo</a>
  <a href="/bar">Bar</a>
</nav>
```

To automatically match your existing navigation components, configure additional selectors in [`up.status.config.navSelectors`](https://unpoly.com/api/up.status.config.md#config.navSelectors):

```js
up.status.config.navSelectors.push('.navbar')
```

## Styling current links {#styling}

Unpoly applies no default styling to [`.up-current`](https://unpoly.com/api/up-current.md) links. Use your own CSS instead:

```css
.up-current {
  font-weight: bold;
  background-color: yellow;
}
```

If you already have a CSS class for current links that you want to reuse, you can tell Unpoly about it:

```js
up.status.config.currentClasses.push('my-current')
```

Unpoly will set all configured classes on a current link:

```html
<nav>
  <a href="/foo" class="up-current my-current">Foo</a>
  <a href="/bar">Bar</a>
</nav>
```

## Matching the current location {#matching-urls}

The URL shown in the browser's [address bar](https://en.wikipedia.org/wiki/Address_bar) is generally considered the "current" location ([except with overlays](#layers)).

A link is marked as [`.up-current`](https://unpoly.com/api/up-current.md) when the current location matches either:

- the link's `[href]` attribute
- the link's [`[up-href]`](https://unpoly.com/api/up-href.md) attribute on a [faux hyperlink](https://unpoly.com/learn/faux-interactive-elements.md#acting-like-a-hyperlink)
- one of the link's [alias URLs](#aliases)

Any `#hash` fragments will be ignored in both link attributes and in the current location.

### Matching multiple URLs {#aliases}

You often want to highlight a link for multiple URLs. For example, a link to a _Users_ section might open a list of users, but should also be "current" for the new user form.

To build this, set an [`[up-alias]`](https://unpoly.com/api/up-alias.md) attribute to any URL that should also be highlighted as [`.up-current`](https://unpoly.com/api/up-current.md). The link below will be highlighted at both `/users` and `/users/new` locations:

```html
<nav>
  <a href="/users" up-alias="/users/new">Users</a>
</nav>
```

To pass more than one alternative URL, set comma-separated values:

```html
<nav>
  <a href="/users" up-alias="/users/new, /users/online">Users</a>
</nav>
```

You can also use a [URL pattern](https://unpoly.com/api/url-patterns.md):

```html
<nav>
  <a href="/users" up-alias="/users/*">Users</a>
</nav>
```

### Matching the location of other layers {#layers}

Each [layer](https://unpoly.com/api/up.layer.md) has a separate location that it considers "current". Even when an overlay has [no visible history](https://unpoly.com/learn/history-in-overlays.md#configuring-visibility), it still tracks the location of the fragment it contains.

Links are marked as current when they point to the location _of their own layer_. To highlight links that point to the location of _another_ layer, set an [`[up-layer]`](https://unpoly.com/api/up-nav.md#up-layer) attribute on their [navigational container](#navigational-containers). The attribute value can be any [layer option](https://unpoly.com/learn/targeting-other-layers.md).

Below you can see a "hamburger menu" that is shown in an overlay. It contains links to the root layer, so their [`.up-current`](https://unpoly.com/api/up-current.md) classes reflect the root layer's location:

```html
<!-- Navigation bar in an overlay -->
<nav up-layer="root">
  <a href="/users" up-layer="root">Users</a>
  <a href="/posts" up-layer="root">Posts</a>
</nav>
```

You can also match multiple layers this way. This is useful when links within a single navigation bar target various layers.

In this example links are marked as "current" if their URL matches the location of _any_ layer:

```html
<nav up-layer="any">
  <a href="/users" up-layer="root">Users</a>
  <a href="/posts" up-layer="root">Posts</a>
  <a href="/sitemap" up-layer="current">Full sitemap</a>
</nav>
```

## Accessibility considerations {#accessibility-considerations}

When a link is marked as [`.up-current`](https://unpoly.com/api/up-current.md), Unpoly also assigns an [`[aria-current]`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current) attribute to convey the emphasis to assistive technologies:

```html
<nav>
  <a href="/foo" class="up-current" aria-current="page">Foo</a>
  <a href="/bar">Bar</a>
</nav>
```

When using a non-`<nav>` element with [`[up-nav]`](https://unpoly.com/api/up-nav.md), we recommend also setting a `[role=navigation]` attribute to define a navigation landmark:

```html
<div up-nav role="navigation">
  <a href="/foo">Foo</a>
  <a href="/bar">Bar</a>
</div>
```

## Updating `.up-current` classes {#updating-up-current-classes}

The [`.up-current`](https://unpoly.com/api/up-current.md) class is toggled automatically within all content that Unpoly renders. For example, when Unpoly [follows a link](https://unpoly.com/api/up-follow.md), [submits a form](https://unpoly.com/learn/submitting-forms.md) or [renders from a script](https://unpoly.com/api/up.render.md), any newly inserted hyperlinks will get [`.up-current`](https://unpoly.com/api/up-current.md) if they point to the current URL. When the browser location [changes](https://unpoly.com/api/up:location:changed.md), existing links will be updated to reflect the new location.

To toggle [`.up-current`](https://unpoly.com/api/up-current.md) on content that you manually inserted without Unpoly, use [`up.hello()`](https://unpoly.com/api/up.hello.md).

<nav aria-label="Reading order">

- [Previous: Preloading links](https://unpoly.com/learn/preloading.md)
- [Next: Elements that act like links or buttons](https://unpoly.com/learn/faux-interactive-elements.md)

</nav>

