---
title: "Important: The main navigation in the header never wraps"
manual: "Frontend Theme for Extension Development"
version: "main"
source: "Changelog/2.0/Important-HeaderNavigationNeverWraps.rst"
rendered: "2026-09-28T12:50:34+00:00"
---

# Important: The main navigation in the header never wraps {#important-header-navigation-never-wraps}

## Description {#description}

The main navigation in the site header keeps its top level entries in **one
row**, or it is behind its menu toggle. When the header row gets tight, the
**site title gives way**: it wraps onto as many lines as it needs, down to its
longest word. Neither the title nor the navigation is capped at a share of the
row any more.

Where one row no longer fits beside the title, the header collapses the menu
behind its toggle — at a width of its own **per header arrangement**, because
each arrangement puts something else beside the menu:

| Arrangement | The menu is a row from | Sass variable |
| --- | --- | --- |
| `simple` | 74rem (1184 pixels) | `bp.$header-simple` |
| `centred` | 55rem (880 pixels) | `bp.$header-centred` |
| `actions` | 55rem (880 pixels) | `bp.$header-actions` |
| `two-tier` | 65rem (1040 pixels) | `bp.$header-two-tier` |

The widths are a budget of **seven top level entries** of the length of the
showcase's sections, beside its title and both header controls, with a margin
of 41 to 51 pixels for a wider system font. A main navigation outside the site
header still collapses at 48rem (768 pixels).

It used to be the other way round. From 1024 pixels up the title kept its
line, up to half the row, and the top level of the menu wrapped onto a second
row inside its frame; between 768 and 1024 pixels the menu was held to half
the row and wrapped inside that. The second level of the menu opens under its
own entry, so the second level of an entry in the first row opened over the
entries of the second. The half row cap also reached `centred`, `actions`
and `two-tier`, whose menu has a row of its own, and made it wrap between
768 and 1024 pixels as well.

## Impact {#impact}

On a screen narrower than the breakpoint of its arrangement, a site's main
navigation is now behind its toggle where it used to be shown, wrapped: with
the default arrangement that is every width below 1184 pixels. On a wider
screen a long site title takes more lines than before, beside a menu of one
row. A single word longer than the row is not broken.

The collapse needs the theme's script. **Without JavaScript** nothing
collapses: below the breakpoint the list is stacked in the flow, and it lists
the top level entries only, at every width down to a phone - every second level
is hidden. That is 511 to 566 pixels of header for the showcase from 768
pixels up and 577 to 632 at 375, where the whole menu would be about 1730 and
2520\. A
page that is the target of a top level entry therefore has to link the pages
below it, as the section pages of the showcase do with a menu of their
subpages; a site with a second level in its main navigation checks its own.
The pattern that defeats this is a top level page of the type "Shortcut" to
its first subpage: without JavaScript its entry leads to that subpage, and its
other subpages are reachable only if that one links them. The same holds for
a top level entry that is a spacer, which links nowhere. This concerns the
menu of the site header only: a main navigation rendered elsewhere keeps its
second levels without JavaScript.

**When the theme script fails** \- it is not found, or it throws before it has
bound the menu toggle, the display settings and the dialog openers - the page
falls back to that same layout: the inline head script sets `data-js`
before first paint as before, and takes it back once the document is parsed
unless `theme.js` confirmed with `data-js-bound`. The menu stays
reachable. A failure in a later part of the script - a carousel, a lightbox -
leaves the header as it is, and a script that runs late, loaded `async` for
example, brings the collapsed menu back when it confirms. `theme.js`
itself stays a module without `async`. A page whose script works is
unchanged and never shows the expanded menu. Under a Content Security Policy
the inline head script is allowed by a hash the extension ships - see
[Important: The no-flash script runs under a Content Security Policy](Important-NoFlashScriptContentSecurityPolicy.html#important-no-flash-script-content-security-policy); only a site that
overrides `page.headerData.10`, or whose policy does not inherit the
default frontend scope, has to act.

A site whose menu is longer or shorter than the budget compiles the stylesheet
with breakpoints of its own. They are Sass variables, because a media query
cannot read a custom property, and they are `!default`: a site package's own
entry point configures them before anything else loads the module, and is
compiled with `Resources/Private/Scss/` on the load path:

```scss
@use 'abstracts/breakpoints' with ($header-simple: 80rem);
@use 'theme';
```

Editing `Resources/Private/Scss/abstracts/_breakpoints.scss` in place is
lost with the next update of the extension.

A header carries **one** arrangement modifier. A site package that adds an
arrangement of its own with a modifier class of its own gets the breakpoint of
`simple`, the widest; a header with two of the shipped modifiers matches the
rules of both, and between their breakpoints the menu cannot be reached.

The Sass variable `bp.$lg` (64rem), which only the site header used, is
removed.
