Be KreaTief

Sticky Navigation (oder Header) ohne Jump ✤✤(✤)

Ich wurde letztens gefragt, wie ich denn meine Navigation sticky gemacht habe und habe versprochen, dass ich dazu einen Post schreibe.
Eigentlich wollte ich euch das Script präsentieren, das ich für mein Menu geschrieben habe. Da ich dieses in letzter Zeit für mehrer Projekte verwendet habe, ist mir aber aufgefallen, dass es ein bisschen Probleme macht. Das ist nicht das Problem meines sticky scripts, es ist das Problem von vielen Scripten. Nach Recherche und viel Trial und Error, habe ich nun ein Script zusammengestellt, dass das Problem nicht aufweist.


Das Problem vieler dieser Scripte ist, dass es einen Sprung gibt, sobald man runterscrollt und die Navigation oben fixiert bleibt. Das äussert sich ausserdem darin, dass der Content, der unterhalb der Navigation platziert ist durch das Ändern der Positionierung plötzlich von der Navigation verdeckt wird. Hat man nur eine dünne Navigation, fällt das kaum auf, doch wenn ihr bei folgendem Beispiel ganz langsam scrollt, werdet ihr sehen, dass sobald das Menu die Oberkante erreicht, der Titel darunter verdeckt wird. Das ist der Sprung von dem ich gesprochen habe und das ist das, was wir vermeiden wollen.

See the Pen HvtgD by Myri (@bekreatief) on CodePen.



Bei einem klassischen Script, braucht ihr nur einen Container, hier brauchen wir etwas mehr Markup.
Die Idee ist, einen Platzhalter hinter dem Menu zu platzieren, mit der gleichen Höhe, Dieser Platzhalter wird nicht aus dem Kontext geworfen, sondern scrollt einfach weiter. Das heisst kein Sprung, weil das Element, das wir entfernen, über einem anderen Element liegt, das wir nicht entfernen.
Dieser Container braucht die gleiche Höhe wie unser Menu. Da man meist keine Höhe definiert, lassen wir das jQuery machen.

Nehmen wir ein Beispiel.

Unser Markup sieht wie folgt aus:

<div class="fix_wrap">
  <div class="fix_hold"></div>
  <nav class="fix_nav">
    <a href="#">Link 1</a>
    <a href="#">Link 2</a>
    <a href="#">Link 3</a>
    <a href="#">Link 4</a>
    <a href="#">Link 5</a>
  </nav>
</div>

Unser Style dazu ist ganz simpel:

.fix_wrap {
  position: relative;
  left: 0;
  top: 0;
}
.fix_wrap .fix_nav {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  text-align: center;
  background: #8c4698;
  padding: 10px 0px;
}

Jetzt müssen wir nur noch etwas jQuery schreiben, dass die Höhe der Navigation liest und diese Höhe dem Platzhalter zuweist. Und dann ändern wir die Position des Menus von absolute zu fixed, sobald das Menu die Oberkante des Fensters erreicht hat.

$(function(){
  var gluetube = $('.fix_wrap');
  var glue = $('.fix_nav');        
  var grease = $('.fix_hold');        
  var h = (glue).height();        
  var offset = glue.offset();        
  var glueTop = offset.top;        
  var windowTop = $(window).scrollTop();        
  
  function sticky(){            
    grease.css({'height':h});            
    windowTop = $(window).scrollTop();            
    return glue.css({position: windowTop>glueTop ? "fixed": "absolute" });        
  }        
  
  $(window).on("load resize scroll",function(e){            
    sticky();        
  });    
});

Das ganze würden wir dann in einem Gadget oder direkt im Code des Menus platzieren. Vergesst dabei nicht jQuery zu integrieren, am beste direkt vor dem schliessenden body-tag und drunter dieses Script.
Wollt ihr es in ein Gadget kopieren, würde das so aussehen:

<div class="fix_wrap">
  <div class="fix_hold"></div>
  <nav class="fix_nav">
    <a href="#">Link 1</a>
    <a href="#">Link 2</a>
    <a href="#">Link 3</a>
    <a href="#">Link 4</a>
    <a href="#">Link 5</a>
  </nav>
</div>

<style>
.fix_wrap {
  position: relative;
  left: 0;
  top: 0;
}
.fix_wrap .fix_nav {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  text-align: center;
  background: #8c4698;
  padding: 10px 0px;
}
</style>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script>
$(function(){
  var gluetube = $('.fix_wrap');
  var glue = $('.fix_nav');        
  var grease = $('.fix_hold');        
  var h = (glue).height();        
  var offset = glue.offset();        
  var glueTop = offset.top;        
  var windowTop = $(window).scrollTop();        
  
  function sticky(){            
    grease.css({'height':h});            
    windowTop = $(window).scrollTop();            
    return glue.css({position: windowTop>glueTop ? "fixed": "absolute" });        
  }        
  
  $(window).on("load resize scroll",function(e){            
    sticky();        
  });    
});
</script>

Zum Vergleich habe ich euch das gleiche Demo wie vorhin noch mit dem neuen Script geschrieben, damit ihr sehen könnt, wie smooth der sticky Effekt verläuft.


See the Pen gHomL by Myri (@bekreatief) on CodePen.

edit

2 comments:

  1. Hey :) ich bin mir nicht ganz sicher ob das so ein tutorial ist deshalb schreib ich es mal hierhin :)
    wenn es das nicht ist könntest du vielleicht mal ein tutorial dazu machen wie man den Header so fixiert bekommt beim runterscrollen? :)
    das wäre super!

    PS: tolle arbeit! Ich meine deinen ganzen blog :) du steckst so viel arbeit darein und erklärsst so viel und das hilft einfach so vielen Mädels und vielleicht auch Jungs die keine richtige ahnnung vom coden haben ihren blog schöner zu machen :)

    ReplyDelete
  2. sorry ich glaube ich hab den link ganz vergessen :D
    http://brina-bellina.de/

    ReplyDelete

Fragen, Feedback oder anderes, was du loswerden willst?
Kommentiere über das alte Kommentarsystem (check wieder vorbei um zu sehen, ob ich geantwortet habe) oder G+

Questiosn, Feedback or something else you want to tell me?
Comment using the old system or G+ and make sure to check back to see if I answered