Tech 10. Mar. 2014

Pure CSS Sticky Navigation

So schöne Dinge man mit Javascript auch machen kann - man muss es nicht immer tun. Dazu habe ich schon verschiedene Male geschrieben. Heute zu einer reinen CSS-Lösung für eine Sticky-Navigation. Die Anforderung an eine Sticky-Navigation lautet i.d.R. in etwa so: Beim Scrollen soll am oberen Fensterrand das Menü stehen bleiben damit der User immer das Menü im Zugriff hat. Der (zumeist darüber liegende Header) kann dabei weggescrollt werden. zusätzlich hat das Menü auf Smartphone ggf. eine andere Darstellung und hat nicht das volle Menü am oberen Rand sondern bspw. nur einen Home-Button oder ein sogenanntes Burger-Menü. Die Idee ist einfach: Man nutz die Möglichkeit Layer per z-Index übereinander zu legen und deren Verhalten beim Scrollen per postion-Angabe zu definieren.

Beispiel HTML:

<nav id="top">
    <ul id="menu">
        <li class="totop"><a href="#anfang"> <span>zum Anfang</span></a></li>
        <li><a href="#mitmachen">Mach mit!</a></li>
        <li class="minor"><a href="#kontakt">Kontakt</a></li>
    </ul>
</nav>

<nav id="fixed">
    <ul id="menu">
        <li class="totop"><a href="#anfang"> <span>zum Anfang</span></a></li>
        <li><a href="#mitmachen">Mach mit!</a></li>
        <li class="minor"><a href="#kontakt">Kontakt</a></li>
    </ul>
</nav>

Und das passende CSS:

nav#top {    
}
nav#fixed {
     position: fixed;
     top: 0;
     left: 0;
     right: 0;
     z-index: 50;
}
header {
     background: #F4F4F4;
     z-index: 100;
     position: relative;
}

Die Vorteile liegen auf der Hand: Beim Scrollen auf Smartphone und Tabletts entstehen keine unnötigen Ruckler die bei den gängigen JavaScript Lösungen auftreten, weil das Rendering einfach nicht so fix abgearbeitet wird. Auf Desktop Browsern ist das natürlich auch der Fall, aber dort wäre der Javascript-Nachteil i.d.R. nicht spürbar.

Größtes Manko an dieser Lösung: Das Menü wird im Markup mehrmal benötigt. Hier muss man sich entscheiden, ob man das entweder in Kauf nimmt, da bspw. Barrierefreiheit eine untergeordnete Rolle spielt oder man setzt an dieser Stelle Javascript ein. Der „verschobene“ Javascript-Einsatz hat den Effekt, dass nach dem laden der Seite aber vor den User Aktionen (wie Scrollen) im Hintergrund das Menü dupliziert werden kann. Da das Sticky Menü hier noch nicht sichtbar ist, wird auch kein Javascript-Ruckeln verursacht. Beim Scrollen passiert dann alles per CSS.

Nun kann man noch einige Tricks ergänzen, um das Menü noch ein wenig flexibler auf die Geräte auszusteuern.

Man kann bspw. für Smartphones nur den Home Button stehen lassen:

@media ( max-width : 599px) {
     nav#fixed #menu li {
          display: none;
     }
     nav#fixed #menu li.totop {
          display: inline-block;
     }
}

Oder bei mittleren Auflösungen, wo das Menü zwar noch passt, aber der Platz schon recht eng wird, einige Punkte entfernen. Und das natürlich auch mehrstufig.

@media (max-width: 767px) {
     nav#top #menu li.totop {
          display: none;
     }
}
@media (max-width: 599px) {
     nav #menu li.minor {
          display: none;
     }
}