App Header
The fixed header bar of the LabXpert app. It is a layout component with three zones — it positions its zones and brings nothing else; everything inside is composed from existing components.
Why three zones
.l-container is a fixed 970px wide and centered, which leaves a margin on both sides. The two outer zones are pulled into that margin, so the navigation keeps the full container width:
┌── margin ──┬────────── .l-container (970px) ──────────┬── margin ──┐
│ __start │ __nav │ __end │
│ (absolute) │ (in flow) │ (absolute) │
└────────────┴──────────────────────────────────────────┴────────────┘
↑ right: 100% left: 100% ↑Once the viewport is too narrow for those margins, both zones move into the normal flow and the bar becomes an ordinary three-column flex row.
| Viewport | __start / __end |
|---|---|
>= 1380px | position: absolute, in the page margin |
< 1380px | in the normal flow (the default) |
The rules are written mobile-first: the flow case is the default and needs no reset values, the absolute positioning is added in a min-width query.
The breakpoint is derived, not picked: $container-width (970px) + 2 × $app-header-zone-width (205px) = 1380px. Both live in _variables.scss.
Structure
div.l-app-header ← fixed bar, background, blur
└── div.l-container.-invisible.l-app-header__bar
├── div.l-app-header__start ← app switcher + product logo
├── div.l-app-header__nav ← LabXpert Navigation
└── div.l-app-header__end ← app actions + user account| Class | Purpose |
|---|---|
.l-app-header | The fixed bar: height, background, blur, shadow, z-index |
.l-app-header__bar | Goes on the .l-container, provides the positioning context |
.l-app-header__start | Pulled into the left margin |
.l-app-header__nav | Takes the remaining space (flex: 1 1 100%) |
.l-app-header__end | Pulled into the right margin, content aligned right |
.l-app-header-offset | Add to the first container below the header — clears the fixed bar |
WARNING
__bar must sit on the container itself, not on a wrapper inside it. It supplies the position: relative that the two outer zones are positioned against.
Clearing the fixed bar
The header is position: fixed, so the content below needs to clear it. Add .l-app-header-offset to the first container:
<div class="l-container -invisible l-app-header-offset">
...
</div>The offset is calculated from $app-header-height + $app-header-content-gap, so it stays in sync when the bar height changes.
Example
The demo below fakes a narrow container so both outer zones stay visible in the docs, and pins the bar in place instead of fixing it to the viewport.
Show Code
<!-- The demo wrapper fakes the page margin next to .l-container that the outer
zones are pulled into, and keeps the fixed bar inside the docs page. -->
<div style="position: relative; height: 120px; overflow: hidden;">
<div class="l-app-header" style="position: absolute;">
<div class="l-container -invisible p-x-l l-app-header__bar" style="width: 600px; min-width: 0;">
<div class="l-app-header__start">
<div class="h-pos-relative">
<button type="button" class="c-btn -icon-btn -small -link h-bg-white" data-target="#app-header-apps" aria-label="Bereich wechseln">
<i class="fas fa-grid-round h-color-black" aria-hidden="true"></i>
</button>
<div class="c-panel -close-backdrop -is-dropdown -is-extra-small" id="app-header-apps" role="menu" aria-haspopup="true" style="width: 300px">
<div class="c-panel__inner">
<p class="h-type-uppercase h-type-bold h-type-small p-t-xs">Bereich wechseln</p>
<ul class="c-list -linklist -fullwidth -small">
<li class="c-list__item p-y-xs">
<a class="c-link -secondary -tiny" href="#">LaborPlus</a>
</li>
<li class="c-list__item p-y-xs">
<a class="c-link -secondary -tiny" href="#">MediCheck</a>
</li>
</ul>
</div>
</div>
</div>
<a href="#" class="h-flex">
<img src="/resources/images/logos/logo-labxpert.svg" width="130" alt="LabXpert" class="m-x-s"/>
</a>
</div>
<div class="l-app-header__nav">
<ul class="c-nav-labxpert">
<li class="c-nav-labxpert__item">
<a class="c-nav-labxpert__link c-link" href="#">Start</a>
</li>
<li class="c-nav-labxpert__item -is-current">
<a class="c-nav-labxpert__link c-link" href="#">Protokolle</a>
</li>
</ul>
</div>
<div class="l-app-header__end">
<a href="#" class="c-btn -icon-btn -small -link h-bg-white m-r-s" title="Updates">
<i class="far fa-bell h-color-black" aria-hidden="true"></i>
</a>
<a href="#" class="c-btn -icon-btn -small -link h-bg-white m-r-s" title="Einstellungen">
<i class="far fa-gear h-color-black" aria-hidden="true"></i>
</a>
<button type="button" class="c-btn -icon-btn -small -link h-bg-white" aria-label="Benutzerkonto">
<i class="fa-solid fa-user h-color-black" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>Notes
- The zone content is composition only: Button, Panel, List, Logo and the LabXpert Navigation.
z-indexcomes from theapp-headerkey of the central z-index map (core/abstracts/_functions.scss), so it is not a loose number in the markup.