CSS, HTML und Javascript mit {stil}

Javascript statt CSS position sticky

JS stickyfy – CSS position: sticky mit Javascript

CSS position: sticky ist ein Sonderfall von position: fixed. Ein Block wandert nach oben, wenn der Benutzer die Seite nach unten scrollt, aber bleibt fest stehen, wenn er eine bestimmte Position erreicht.

In CSS gibt es die Eigenschaften position: fixed und position: sticky. position: fixed setzt einen Block von vornherein auf einer bestimmten Position fest, so dass er nicht mitscrollt, wenn der Benutzer durch die Seite scrollt.

position: sticky funktioniert ähnlich, aber der Block scrollt zunächst mit und wird erst ab einer bestimmten Position im Browserfenster fixiert.

CSS position: fixed wird von allen aktuellen Browsern unterstützt, position: sticky hingegen nicht von IE11 und Microsoft Edge. Die könnten wir nun einfach laufen lassen – oder wir greifen auf Javascript zurück.

Javascript für CSS position: sticky

Sticky Navigation

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet est vitae elit sollicitudin bibendum fringilla at dui. Aliquam tempus pretium tempor. Quisque diam massa, gravida ut sem non, laoreet venenatis lorem. Proin vel posuere justo, ut fermentum eros. Proin id ultricies mi. Nulla facilisis venenatis nisi at laoreet. Suspendisse potenti. In justo elit, ultricies sit amet facilisis a, consectetur ut sem.

CSS für sticky
   @media (min-width: 680px) {
   .jsSticky {
      position: relative;
      width: 100%;
      height: 40px;
      background: hsl(350,50%,50%);
   }

   .jsSticky.clone {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      transform: translateY(-100%);
      transition: 0.2s transform ease-in;
   }

   body.down .jsSticky.clone {
      transform: translateY(0);
   }
}

Javascript sticky ahmt das Verhalten von CSS sticky durch die Animation von position: fixed nach.

stickystart legt stellt fest, wie weit der Benutzer scrollen kann, bevor der Block fixiert wird. In diesem Beispiel wird der Block oben im Browserfenster fixiert und die Scrolldistanz ist der Abstand des Sticky-Blocks vom oberen Browserrand.

Javascript für position: sticky
var stickystart = document.querySelector(".jsSticky").offsetTop;
var sticky = document.getElementsByClassName("jsSticky")[0];
var sticky = {
  sticky_after: stickystart,
  init: function() {
    this.header = document.querySelector(".jsSticky");
    this.before = document.querySelector(".jsSticky").previousElementSibling.nextChild;
    this.clone = this.header.cloneNode(true);
    this.clone.classList.add("clone");
    this.header.insertBefore(this.clone, this.before);
    this.scroll();
    this.events();
  },

  scroll: function() {
    if(window.pageYOffset > this.sticky_after) {
      document.body.classList.add("down");
    }
    else {
      document.body.classList.remove("down");
    }
  },

  events: function() {
    window.addEventListener("scroll", this.scroll.bind(this));
  }
};

document.addEventListener("DOMContentLoaded", sticky.init.bind(sticky));

position: sticky für moderne Browser

Das sind nur wenige Zeile Vanilla Javascript, aber ein Event Listener auf dem scroll-Event ist eine schwere Last, die man Browsern, die position:sticky unterstützen, nicht auferlegen sollte. Scrollen gehört zu den den meistgenutzten Aktionen.

Eine Abfrage, ob der Browser position: sticky von Haus aus unterstützt, ist dank der CSS @supports-Regel einfach.

Nach dem CSS für den sticky-Fake kommt das CSS für die Browser, die sticky unterstützen.

@supports (position: sticky) or (position: -webkit-sticky) {
   @media (min-width: 680px) {
      .jsSticky {
         position: -webkit-sticky;
         position: sticky;
         top: 0;
      }
   }
}

window.getComputedStyle klärt, ob sticky unterstützt wird.

var positionSticky = window.getComputedStyle(sticky).getPropertyValue("position");
if (positionSticky === "relative") {

   // stickyfy

}

In der @supports-Regel steckt noch eine weitere Bedingung: Geräten mit einem kleinen Viewport soll der sichtbare Bereich der Seite nicht verkleinert werden.