Ein Leser schickte mir ein GIF, das einen coolen Effekt zeigte, den er auf Google auf Mobilgeräten gesehen hatte. (Vermutlich die Homepage, die man sieht, wenn man Chrome auf Android startet?) Es gibt ein Suchfeld in der Mitte der Seite, das mit der Seite scrollt, aber kurz bevor es von der Seite verschwindet, wird es am Header fixiert. Lass uns das behandeln, denn, wissen Sie...
OH: Ich bin ein mobiler Webentwickler, also bekomme ich im Grunde den ganzen Tag Anfragen, damit Inhalte nach etwas Scrollen oben haften.
— Daniel Wilson (@dancwilson) 16. September 2014
Es ist ein cooler Effekt, besonders wenn er dazu dient, die Benutzerfreundlichkeit zu verbessern und nicht, um eine dumme, aufdringliche Werbung zu fixieren. Hier ist das GIF, auf dem ich die Idee basierte. Ein wenig ruckelig, aber die Idee ist da.

Zwei Zustände
Wie die meisten guten Tricks steckt nicht viel dahinter. Alles, was wir tun, ist, uns die zwei verschiedenen möglichen Zustände vorzustellen (und dafür zu gestalten).
- Suchleiste in ihrer scrollbaren Position
- Suchleiste in ihrer fixierten Header-Position
Wir wechseln zwischen ihnen, indem wir einfach einen Klassennamen ändern. Es gibt keine Trickserei mit zwei Suchformularen, die sich in verschiedenen Szenarien offenbaren. Das ist gut, denn wir wollen nicht mit dem Synchronisieren herumfummeln. Viel einfacher, nur eines zu bewegen.
Zustand Eins

(Ich werde hier SCSS verwenden, da die Verschachtelung für die Verwaltung von Zuständen schön ist.)
.top-header {
position: fixed;
top: 0;
left: 0;
width: 320px;
height: 60px;
}
.search { /* Container just in case we want more than just the search input to come along */
position: absolute;
top: 155px;
left: 20px;
right: 20px;
input {
width: 265px;
transition: width 0.2s;
-webkit-appearance: none; /* Autoprefixer doesn't catch this */
}
}
.top {
height: 250px; /* Space in here for search */
padding-top: 40px;
position: relative;
}
Zustand Zwei

Angenommen, wir haben eine Klasse namens „fix-search“ auf ein Elternelement angewendet.
.top-header {
...
.fix-search & {
background: #eee;
}
}
.search { /* Container just in case we want more than just the search input to come along */
...
.fix-search & {
position: fixed;
top: 10px;
input {
width: 250px;
}
}
}
Zustände wechseln
Der Trick hierbei ist, diese Klasse genau im richtigen Moment anzuwenden. In unserer kleinen Demo können wir testen, wann dieser perfekte Moment wäre, und ihn hartkodiert in ein JavaScript einbauen, das auf das Scrollen achtet. Im jQuery-Stil.
var wrap = $("#wrap");
wrap.on("scroll", function(e) {
if (this.scrollTop > 147) {
wrap.addClass("fix-search");
} else {
wrap.removeClass("fix-search");
}
});
Das ist alles, was nötig ist, um zwischen den beiden eingerichteten Zuständen zu wechseln. Wenn die Seite 147 Pixel oder mehr nach unten gescrollt wurde, erhält sie diese Klasse. Wenn nicht, dann nicht. Selbst wenn Sie nach unten gehen und wieder nach oben kommen, verschwindet die Klasse (da diese kleine Funktion bei jedem Scroll-Ereignis aufgerufen wird).
Demo
Siehe den Pen Suchfeld im Inhalt bewegt sich zum fixierten Header von Chris Coyier (@chriscoyier) auf CodePen.
Debouncing
In der großen Tradition, beim Binden eines Events an ein Scroll-Event über Scroll-Debouncing zu sprechen: Sie sollten das Debouncing in Betracht ziehen, wenn Sie Funktionen an Scroll-Events binden, denn wenn Sie es nicht tun, wird es tausendmal aufgerufen und könnte langsam sein.
CSS
Das ist die Art von Sache, die man in reinem CSS machen könnte. Es gibt noch keine guten Lösungen, aber ich bin immer wieder erstaunt über die verrückten Dinge, die Leute mit CSS machen, also werde ich es aktualisieren, wenn etwas Neues kommt.
Vielleicht werden wir eines Tages Scroll-Positions-Media-Queries haben können?
Unterstützung für feste Positionen
Beachten Sie, dass diese Demo auf fester Positionierung basiert, die eine fragwürdige Geschichte auf Mobilgeräten hat. Obwohl ich versucht bin zu sagen, dass sie heutzutage "ziemlich gute" Unterstützung hat, sollten Sie sich selbst ein Urteil bilden. Einige Lektüren.
- Kann ich verwenden… zur festen Positionierung
- Feste Positionierung in mobilen Browsern von Brad Frost
- Probleme mit position: fixed & Scrolling auf iOS von Remy Sharp
Dies ist nur ein (nicht besonders wiederverwendbares) Beispiel
Es gibt viele magische Zahlen in dieser Demo. Immer wenn Sie Höhen einstellen, sollten Warnsignale in Ihrem Gehirn aufleuchten. Das bedeutet nicht, dass Sie es nie tun sollten, es bedeutet nur, dass Sie gewarnt sein sollten. In dieser Demo, wenn das zentrierte Bild im Header seine Höhe ändern würde, würde es ziemlich egal was passieren würde, komisch aussehen. Dies ist keine flexible und fehlerverzeihende Layout-Variante. Selbst wenn Sie den Header so fixieren, dass er nach einer Änderung gut aussieht, hat das JavaScript entsprechende magische Zahlen, wann der Zustand geändert werden soll.
Vielleicht könnte eine Version, die waypoints (oder deren Konzept) verwendet, ein kugelsicheres System schaffen.
na ja... ich fühle mich nicht auf dem neuesten Stand.
Lösen/auslösen JavaScript-Ereignisse (ich weiß nicht, wie Sie es nennen, aber Sie verstehen, was ich meine) nur, wenn das Scrollen auf Mobilgeräten beendet ist?
Unter iOS 7 und älter ja, das Ereignis wird nur am Ende des Scrollens ausgelöst. Nicht unter Chrome für Android und nicht unter iOS 8 (muss ich für letzteres testen).
Nicht mitbekommen :/. Auf jeden Fall sehr cool, das zu lernen.
Dennoch funktioniert sein Codepen einwandfrei auf einem iOS7, das gestern installiert wurde.
Remy hat ein paar gute Funktionen für Debouncing und Throttling, letzteres ist nützlich für z.B. Größenänderungen.
Hier ist der Link
position: sticky wird das hoffentlich leisten, aber die Unterstützung ist noch nicht gut: http://caniuse.com/#feat=css-sticky
Ich war gezwungen,
position:sticky;bei einem Projekt zu verwenden, weil das Scroll-Ereignis ausgelöst wurde, sobald das Scrollen beendet war (https://developer.apple.com/library/safari/documentation/appleapplications/reference/SafariWebContent/HandlingEvents/HandlingEvents.html).Funktionierte sehr gut auf iOS7, aber nicht auf iOS6.
Sieht gut aus. Hier ist eine Abspaltung, die die Größenänderung der Eingabebreite und die festen Positionsteile trennt, so dass die Eingabe ein wenig besser am Menüknopf "ausweicht".
Drei-Zustands-Version
Ich mag es. Habe es für Sie abgewandelt: gleiche Idee, aber mit einer Zwischenposition
top, damit ich den Übergang zu seiner fixierten Position erleichtern konnte. Ebenso mit der Hintergrundfarbe der oberen Leiste.Toller Beitrag, Chris. Eine Variation, die ich im Android Chrome Browser bemerkt habe, war, dass die Suchleiste ausblendet und dann nach oben springt, sobald das Fenster auch nur ein wenig nach oben gescrollt ist. Ich werde vielleicht ein wenig mit Ihrem Code spielen, um diesen Effekt nachzubilden. Liebe die Seite!
Um den Code kompakter zu halten, könnten Sie ersetzen
mit
/Olaf
Chris sagt
Ich würde mich definitiv über eine CSS-Lösung freuen. Es gibt viele Websites, die JavaScript zur Erkennung von Scrollvorgängen für rein dekorative Effekte verwenden, die in CSS sein sollten, oder für Leistungsziele wie Lazy Loading.
Ein Ansatz mit Media-Queries müsste warten, bis Element-Level-Media-Queries verfügbar sind. Meine Präferenz wäre eine Pseudoklasse
:onscreen. Wenn das Element im Ansichtsfenster ist, hat es diese Pseudoklasse und Stile werden ausgelöst. Bevor es auf dem Bildschirm erscheint, bevor die Seite als Ganzes auf dem Bildschirm ist (z. B. für eine Webseite, die in einem ausgeblendeten Tab geöffnet ist) oder wenn das Element aus dem Blickfeld scrollt, werden diese Stile übersprungen.Für Ihre Sticky-Suchleiste möchten Sie die Pseudoklasse an den aus dem Blickfeld scrollenden Header-Bereich anhängen.
Für das Lazy Loading von Hintergrundbildern könnten Sie ebenfalls einen vorherigen Geschwisterteilnehmer verwenden, der in Sicht kommt, obwohl Sie das Bild beibehalten möchten, wann immer er in Sicht ist.
Für einen Animationseffekt, wenn etwas in Sicht kommt, würden Sie einfach die Pseudoklasse auf dieses Element anwenden.
(Vielleicht könnte die Pseudoklasse einen Parameter haben, ähnlich wie nth-of-type-Parameter, so dass Sie einschränken könnten, ob der Effekt jedes Mal auftritt, wenn das Element in Sicht kommt, oder nur die ersten paar Male?)
Und während wir träumen, wie wäre es mit einer
scroll-Option für CSS-Übergänge, damit Sie kein kompliziertes JavaScript benötigen, um Links auf derselben Seite schön scrollen zu lassen?Designer wollen diese Effekte. Designer erstellen diese Effekte mit JavaScript. Eine deklarative Möglichkeit, diese Effekte in CSS zu definieren, würde es Browsern ermöglichen, sie zu optimieren.
Nun, ich habe etwas versucht, um magische Zahlen zu entfernen, aber das ist nicht so einfach.
http://codepen.io/Sirop/pen/qhsbA
Könnten Sie nicht die magische Zahl eliminieren, indem Sie
offset().topverwenden...Außerdem... ist das nicht dieselbe Technik, die wir bei Sticky Navs gesehen haben, die sich am oberen Bildschirmrand fixieren, sobald der Benutzer ein Stück nach unten gescrollt hat? Ich verstehe nicht ganz, wie das eine große Neuigkeit ist... aber ich schätze den Beitrag... sehr informativ...
Ich gehe davon aus, dass nichts auf dieser Seite eine "große Neuigkeit" ist.
Dies ist eine gute Übersicht über die Implementierung eines einfachen Sticky-Effekts. Wenn Sie den Code nicht selbst schreiben möchten, gibt es zahlreiche Plugins dafür. Ich hatte guten Erfolg mit den bereits erwähnten Waypoints (die als Teil der Erstellung Ihres eigenen Codes verwendet werden können, aber auch ein Add-on haben, um dies für Sie zu tun), sowie mit der Sticky-Klasse in ZURB Foundation und dem Sticky jQuery-Plugin, aber eine schnelle Google-Suche wird zweifellos Alternativen in allen Ihren Lieblingsgeschmacksrichtungen hervorbringen.
Herumfummeln ist, wie einige der besten Designinnovationen entstanden sind. Ich hoffe, dieser Verweis geht niemals verloren.
Leider ist
position: stickynoch keine Sache.Dieser Übergang ist Teil von Googles neuer Designspezifikation namens "Material Design". Chrome ist eine der ersten Android-Apps, die dies unterstützt. Es gibt einige coole Übergänge und Animationen. Es ist auch für Webkomponenten auf polymer-project.org verfügbar.
Für diejenigen, die über
position: sticky;gesprochen haben, hier ist meine Abspaltung von Chris' Pen, die nur CSS verwendet. Beachten Sie, dass sie nur in Firefox 32 funktioniert, der derzeit die stabile Version ist.Ich bevorzuge definitiv eine Version ohne magische Zahlen. Vor einiger Zeit habe ich ein Muster für diesen Effekt erstellt, das ich jetzt ein paar Mal verwendet habe. Die Dinge, die ich gelöst habe, waren: keine magischen Zahlen, das ursprüngliche Element sollte im Dokumentfluss bleiben können, der Seiteninhalt sollte nicht springen, wenn dieses ursprüngliche Element zu einem fest positionierten Element gemacht wird, und was auch immer die Sprünge verhindert, sollte lokalisiert sein. Wenn man an einem großen Projekt arbeitet, gilt: Je lokalisierter die Stiländerungen, desto besser.
Ich mache das, indem ich das endgültige Sticky-Element mit einem "Anker"-Element im Markup paare. Wenn das Sticky-Element "klebt", lese ich die Höhe dieses Elements und gebe sie dem Anker, um den Sprung des Inhalts zu verhindern. Beim Ablösen geht die Ankerhöhe zurück auf 0 (oder auto, da sie leer sein sollte).
Hier ist ein Beispiel:
http://codepen.io/anon/pen/chDbg
Ich habe es bisher nur für das Fixieren von Dingen am oberen Bildschirmrand gemacht, aber es scheint, dass es ziemlich trivial wäre, es anzupassen, um es am unteren, linken oder rechten Rand zu fixieren.
Gute Idee, Chris, aber hast du es in allen wichtigen Browsern getestet, auch bei verschiedenen Bildschirmauflösungen?
Dies scheint etwas zu sein, das nicht richtig funktioniert, wenn der native Momentum-Scroll greift. (Ich könnte falsch liegen. Habe es nicht getestet.)
Wenn also mein "touchend" (Ende des Scrollens) unterhalb der magischen 147 Pixel (oder was auch immer Ihre Zahl ist) liegt, aber der Momentum-Scroll das Fenster ganz nach oben bewegt, wird die Klasse "fix-search" nicht entfernt.
Liege ich damit richtig? Und wenn ja, hat jemand eine Lösung dafür?
Interessanter Beitrag, wurde er in allen Browsern getestet?
So habe ich das Problem mit dem Entfernen von magischen Zahlen angepackt. Anstatt eine vordefinierte Höhe im JQuery-Snippet zu verwenden, habe ich
window.innerHeightzusammen mit einem Intro-Div mit dem Stilheight: 100vh;verwendet. Ich habe das Beispiel auf CodePen hochgeladen.Siehe den Pen On Scroll Fix Content von David Schroeder (@simpleminded) auf CodePen.
Ein Problem damit ist jedoch, dass ich es nicht vollständig auf Responsivität getestet habe. Das Problem bei der Verwendung von VH-Einheiten ist, dass, wenn Sie es auch 100% breit machen, es mit dem Problem schrumpft, wodurch diese Box ebenfalls schrumpft. Zu diesem Zeitpunkt müssten Sie vordefinierte Zahlen verwenden, um sicherzustellen, dass Ihr Inhalt wieder in diese Box passt.
Super Beitrag! Ich habe das schon auf Websites gesehen und wollte es zu der Zeit nicht ausprobieren, weil es mir zu kompliziert erschien. Ich denke, jetzt ist die Zeit, es zu versuchen!