Navigation beim Runterscrollen verstecken, beim Hochscrollen anzeigen
Eine Navigation, die beim Runterscrollen versteckt und beim Hochscrollen anzeigt wird, ist sehr beliebt. Mit JavaScript (jQuery) kann die Scrollrichtung abgefragt und je nach Richtung eine CSS-Klasse ergänzt werden.
Fixierte Navigationsleisten, die sich horizontal über die volle Breite der Website erstrecken sind keine Seltenheit. Um den Blick des Anwenders auf den Inhalt zu lenken und gleichzeitig den wertvollen Platz auf dem Display bestmöglich ausnutzen zu können, wird die Navigation auch häufig beim runterscrollen versteckt und beim hochscrollen wieder angezeigt. Insbesondere sog. Onepager und Landingpages nutzen vermehrt den Effekt. Im Folgenden archivieren wir eine CSS/jQuery-Lösung um das Verhalten herzustellen.
HTML-Grundaufbau
Die HTML-Struktur besteht in unserem Beispiel lediglich aus einem leeren <nav>
-Element.
<nav></nav>
Scroll-Richtung mit jQuery abfragen
Zunächst prüfen wir mit Hilfe von jQuery in welche Richtung der Anwender scrolled. Wenn er nach unten scrolled, wird dem <body>
die Klasse down
hinzugefügt. Wenn es nach oben geht wird die Klasse entfernt.
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
if (!$('body').hasClass('down')) {
$('body').addClass('down');
}
} else {
$('body').removeClass('down');
}
lastScrollTop = st;
if ($(this).scrollTop() <= 0) {
$('body').removeClass('down');
};
});
Verstecken der Navigation mit CSS
Der CSS-Code ist ebenfalls recht übersichtlich. Die Navigation wird eingefärbt, oben im Browserfenster fixiert und über die volle Breite ausgedehnt. Zusätzlich erhält sie eine feste Höhe und eine Transition, damit sie später animiert aus dem Viewport fährt, sobald per JavaScript die Klasse hinzugefügt wird.
Sobald die Klasse down
vorhanden ist, wird mit der CSS-Eigenschaft transform
die Navigation um Ihre Höhe nach oben aus dem Viewport geschoben.
nav {
height:100px;
background:lime;
position: fixed;
top:0;
right:0;
left:0;
transition: transform .25s .1s ease-in-out;
}
.down nav {
transform: translate3d(0, -100px, 0); // um 100px nach oben verschieben
}
Moin, moin!
Etwas mehr Barrierefreiheit:
Damit Elemente beim Fokussieren im so ausgeblendeten Kopfbereich angezeigt werden, sollte das `transform` bei `:focus-within` unterbunden werden.
Also in diesem Fall:
„`CSS
.down nav:focus-within{
transform: none;
}
„`
Beste Grüße!
Hallo Michael, vielen Dank für die sehr hilfreiche Ergänzung!
Hallo,
ich habe für die Mobile-Nav einen ClickEvent erstellt, welches die Subnav ein- bzw. ausblendet. Beim Scrollen funktioniert auch alles, wie im oberen Beispiel dargestellt.
Bis auf zwei Detail 1) die Subnav soll beim Scrollen automatisch schließen 2) sowie beim Ändern der Darstellung in die Desktop Version. Bei 2) könnte ich mir gut vorstellen, dass mittels Media Queries zu realisieren?!
Hat jemand einen Input für mich?
Besten Dank.
Tanza
An sich eine prima Lösung. Aber was kann ich tun, wenn die Menüleiste gleichzeitig aufklappbar sein soll? Ich habe das Aufklappmenü mit Bootstrap realisiert, und da vergrößert sich beim Aufklappen jedes Mal der -Bereichs, was offenbar ein scroll-Event auslöst, so dass sich das ganze Menü nach oben verschiebt. Hat jemand eine Idee, wie man das umgehen/verhindern kann?
Kann mir da jemand bitte helfen für Elementor die richtigen Markups und Klassen schreiben, und wo ich was einbinden soll?
Hallo
Ich finde diese Möglichkeit grossartig
Kann ich diese irgendwie in Elementor einbinden?
Grundsätzlich ja – vorausgesetzt, du kannst eigenes JavaScript im WordPress-Theme einschleusen (z.B. über ein Child-Theme o.ä.). Das Markup und die Klassen etc. weichen dann natürlich vom Beispiel ab und müssen angepasst werden.
besten dank
gibt es eine js-plugin evtl?
was würdest du verlangen mir dies kur zu machen, wenns geht aber ohne child-theme.
so ein plugin habe ich schon gefunden und installiert, aber jetz sollte ich die klassen richtig einschleusen.
kannst du mir bitte helfen?
Hey,
ich habe die ersten 3 Google Seiten nach einer Sticky Navbar Lösung durchsucht, aber nichts gefunden was funktioniert.
Ich arbeite mit einem Baukasten (Siquando ProWeb3) und habe nur einige HTML,PHP Codes eingefügt, da ich nicht so der Programmierer bin.
Kann mir evt. jemand einen Tipp geben, wie ich das auf der Homepage http://www.ahaf.de umsetzen kann?
Danke für jede Hilfe!
Beste Grüße
Henning Famulla
Hallo Henning, das Snippet hier im Blog ist standardkonform und sollte funktionieren. Möglicherweise beinhaltet deine Umsetzung auf Grundlage einer Vorlage aber Code, der Inkompatibilitäten verursacht. Das lässt sich allerdings nur mit entsprechender Recherche in Erfahrung bringen.
Hallo,
ich wollet mich erstmal bedanken für die tollen Tipps!
Ich habe folgende Frage, im header Bereich habe ich ein Logo (relativ groß), das über den Slider hervorsteht (im Vordergrund), wenn ich die Seite nach unten scrolle, geht das Element/Logo mit, allerdings soll in Hintergrund bzw. rücken. Im Content ist schon der Test und das Logo soll hinter dem Text sein. Wäre es möglich? Ich habe schon dem Logo z-index:1 vergeben aber, wenn ich den anderen Elementen auch 1 oder 2 vergebe ändert sich nichts.
Hast du die Positionierung der Elemente mit CSS richtig definiert, sodass z-Index auch greift?
Hallo, gibt es die Möglichkeit zu sagen das die leiste erst wieder erscheinen soll wenn man ganz nach oben gescrollt hat? Danke
Wenn die Navigation beim runterscrollen verschwinden soll und dann beim hochscrollen erst ganz oben sichtbar sein soll, musst du doch gar nichts machen. Das ist ja der Standard … oder?
Hallo,
gibt es da keine Lösung um komplett auf Javascript zu verzichten? Denn wenn Javascript deaktiviert ist, würde dein Code nicht funktioniert. Bitte um Antwort. Vielen Dank
Nein, eine Lösung ohne JavaScript gibt es nicht. Was allerdings auch nicht tragisch ist, wenn die Website sauber nach dem Progressive Enhancement-Konzept aufgebaut ist.
Super, ich würde das Ganze aber mit debouncing schreiben, dann ist das nicht so ressourcenhungrig.
Tolles Skript! Absolut!
Gibt es eine Möglichkeit, dass erst wieder ab zB Scrollwert 250 angezeigt wird, also nicht bei jedem upscroll?
Danke für einen Tipp!
Hallo,
gutes Tutorial.
Was muß wo hinzugefügt / abgeändert werden, wenn das Verstecken der Navigation erst einsetzen soll, wenn schon etwas gescrollt wurde, z.B. nach 200px scrollen die Navigation ausgeblendet werden soll?
Ändere die Variable lastScrollTop = 0 z.B. zu lastScrollTop = 200px;
Damit sollte es funktionieren
[…] Quelle: Navigation beim Runterscrollen verstecken, beim Hochscrollen anzeigen | kulturbanause® blog […]
Hallo,
vielen Dank für das kleine Tutorial.
Mir ist bloß etwas aufgefallen: Im IE (nicht Edge) funktioniert das Script leider nicht wie gewünscht. Der IE (alle Versionen) berechnet den Wert für scrollTop() zu langsam. Das führt dazu, dass beim scrollen der letzte Wert mehrfach berechnet wird. Somit geht er bei if(st > lastScrollTop) immer in das else und beim runterscrollen wird die Navigation niemals „sticky“!
Ein Workaround für mich war, dass ich über BrowserDetect den InternetExplorer abgefragt habe und diese Alternative eingebaut habe:
if(BrowserDetect.browser === ‚IExplorer‘) {
$(this).bind(‚mousewheel‘, function(e){
if(e.originalEvent.wheelDelta < 0) {
//scroll down
if (!$('.header').hasClass('sticky')) {
$('.header').addClass('sticky');
} else {
//scroll up
$('header').removeClass('sticky');
}
});
}
Hallo
Kann mir jemand sagen wo man diesen Code einfügen muss damit es auch im Internet Explorer funktioniert?
Ich habe schon viele verschiedene Codes ausprobiert und keiner funktioniert im IE11. Mit diesem Post hatte ich wieder Hoffnung eine Lösung gefunden zu haben, aber wenn ich den im script einfüge geht nichts mehr.
Ah, ok, das macht Sinn. Trotzdem ist die zweite Abfrage überflüssig, da der scrollTop-Wert ja bereits in der Variable gespeichert ist. Auch die hasClass-Abfrage kann man weglassen, da jQuery das intern eh überprüft.
Ich hab das nochmal entsprechend umgestellt, jetzt klappt’s auch in Safari:
https://jsfiddle.net/cre06a09/2/
Hallo,
ist die zweite scrollTop-Abfrage (<=0) nicht überflüssig? Der scrollTop-Wert von window wird eh nie negativ sein und wenn er 0 ist, ist er auf jeden Fall kleiner als lastScrollTop und das wird schon vom vorherigen conditional behandelt.
Demo:
https://jsfiddle.net/cre06a09/1/
Oder überseh ich da irgendetwas?
Hallo Timo, die zweite Abfrage haben wir eingebaut, da man u.a. im Safari über die obere Kante des Browsers hinweg scrollen kann. Damit ist der Wert kleiner Null und die Navigation verschwindet. Ich habe es gerade noch einmal ausprobiert und bei der von dir gekürzten Fassung kann ich somit einen Fehler provozieren, den ich mit unserer Variante nicht ausgelöst bekomme.
Sehr interessant! Kann man sicherlich mal gebrauchen.
Könnte mir bitte jemand erklären, was das folgende bedeutet?
script
src=“https://code.jquery.com/jquery-1.12.4.min.js“
integrity=“sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=“
crossorigin=“anonymous“>
script
Hallo Franz, hier wird jQuery über ein CDN geladen. Die Attribute erklärt die jQuery-Doku wie folgt: »The integrity and crossorigin attributes are used for Subresource Integrity (SRI) checking. This allows browsers to ensure that resources hosted on third-party servers have not been tampered with.«
Hallo Jonas, danke für deine Antwort! Schönen Tag noch!
Wirklich sehr cool und schön.
Ich frage mich nur…
Wie könnte man diese Sache umschreiben, wenn der Inhalt von „nav“ unbekannt ist.
Also wenn man keine fixe Höhe angeben möchte, sondern diese sich u.U. durch den Inhalt ändern könnte?
Jemand eine Idee?
LG
Markus
Hi Markus,
dazu entfernst du aus die height Eigenschaft und änderst bei transform die „-100px“ in „-100%“. Also: transform: translate3d(0, -100%, 0);
Demo: https://jsfiddle.net/cre06a09/
Danke.
Bin ich gestern auch noch draufgekommen ;-))
Sehr cooler Shorttip danke. Hab ich direkt Verwendung dafür :-)
VG
Frank