Eines der vielen super schönen Designmerkmale der Yahoo! Weather App für iOS ist der Übergang zwischen den Stadtbildschirmen. Das Hintergrundbild bewegt sich nicht einfach weg, wenn der Bildschirm von einem zum nächsten wechselt, sondern das Hintergrundbild gleitet selbst. Es scheint, als würde es einen Teil des "alten" Bildschirms verdecken und mehr vom "neuen" Bildschirm enthüllen, je näher es zur vollständigen Ansicht ist.
Versuchen wir, das im Web nachzubilden.
Das HTML
Wie jeder Slider besteht er aus drei Hauptkomponenten
- Der Container, der alles in Form hält
- Ein gleitender Container, der so breit ist wie alle Slides nebeneinander
- Jeder einzelne Slide-Container
Wir werden uns nicht allzu sehr um den Inhalt innerhalb des Slides kümmern. Ich füge nur die Temperatur hinzu, um zu zeigen, dass jeder Slide tatsächlich Inhalt darüber aufnehmen kann.
<div class="slider" id="slider">
<div class="holder">
<div class="slide" id="slide-0"><span class="temp">74°</span></div>
<div class="slide" id="slide-1"><span class="temp">64°</span></div>
<div class="slide" id="slide-2"><span class="temp">82°</span></div>
</div>
</div>
Der Container könnte ein <section> sein, die Slides könnten <article> sein. Das hängt wirklich davon ab. Ich überlasse Ihnen die semantischen Entscheidungen für Ihre eigenen Bedürfnisse.
Der Layoutplan sieht so aus

Das CSS
Der "Slider" (visueller Container) und die Slides müssen explizit die gleiche Größe haben. Wir verwenden hier Pixel, aber Sie könnten es mit jeder Einheit umsetzen.
.slider {
width: 300px;
height: 500px;
overflow-x: scroll;
}
.slide {
float: left;
width: 300px;
height: 500px;
}
Das Floaten dieser Slides nach links wird sie nicht nebeneinander aufreihen, da das Elternelement der Slides nicht breit genug ist, um dies zuzulassen. Das ist einer der Gründe, warum wir das Holder-Element benötigen. Es wird 300% breit sein (Anzahl der Slides × 100%), was genau drei Slides fasst.
.holder {
width: 300%;
}
Jeder unserer Slides hat eine eindeutige ID. Das ist nützlich, denn wenn wir wollen, können wir Ankerlinks erstellen, die auf diese IDs verweisen und der Slider wird zu diesen Slides "springen". Wir werden JavaScript hinzufügen, um das eigentliche "Gleiten" durchzuführen, aber unser Slider wird auch ohne das funktionieren. IDs machen das möglich, also verwenden wir sie hier, um einige schöne Hintergrundbilder einzufügen.
#slide-0 {
background-image: url(http://farm8.staticflickr.com/7347/8731666710_34d07e709e_z.jpg);
}
#slide-1 {
background-image: url(http://farm8.staticflickr.com/7384/8730654121_05bca33388_z.jpg);
}
#slide-2 {
background-image: url(http://farm8.staticflickr.com/7382/8732044638_9337082fc6_z.jpg);
}
Mit all dem an Ort und Stelle nimmt unser Layout Gestalt an

Das CSS (schwarzes Ausblenden)
Als kleines Detail kann die in Weiß gesetzte Temperatur Gefahr laufen, je nach Foto dahinter nicht sichtbar zu sein. Um sicherzustellen, dass sie sichtbar ist, können wir das Foto zum unteren Rand hin subtil schwarz überblenden lassen. Ein Pseudo-Element eignet sich dafür gut.
.slide:before {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40%;
background: linear-gradient(transparent, black);
}
Eine Erklärung mit Bildern ist hier angebracht

Das JavaScript (gleitende Hintergründe)
Wir werden hier jQuery verwenden, weil wir das Leben lieben. Unser Ziel ist es, die `background-position` der Slides beim Scrollen anzupassen. Wir können `background-position` in Prozent in CSS einstellen, aber das allein bewirkt nicht den coolen Versteck/Mehr-Enthüll-Effekt, den wir suchen. Basierend auf der gescrollten Menge (die wir in JavaScript messen können), passen wir die `background-position` an. Allein würde das ungefähr so aussehen
$("#slider").on("scroll", function() {
$(".slides").css({
"background-position": $(this).scrollLeft()/6-100+ "px 0"
});
});
Die "6" und "-100" sind magische Zahlen. Nicht magische CSS-Zahlen, die anfällig für Fehler sind, sondern traditionelle magische Zahlen. Nur ein paar Zahlen, die zufällig den Effekt bewirken. Ein Nachteil vielleicht, aber keine große Sache. Design-Sachen sind manchmal so. Vielleicht ist es am besten, einen Kommentar im Code dazu zu hinterlassen. Diese speziellen Zahlen basieren auf den von mir verwendeten Bildern, ihrer Größe und dem, was gut aussah.
Der Effekt, den wir hier erzielen wollen, ist das Verschieben des Hintergrunds

Das JavaScript (Strukturvermittlung)
Dieser kleine JavaScript-Schnipsel sieht ohne eine Struktur dahinter einsam aus. Ein Slider ist ein guter Anlass, sich eine einfache Möglichkeit zur Strukturierung von JavaScript anzusehen.
Wir können alles Slider-bezogene in ein Objekt packen.
var slider = {
};
Dann gruppieren wir die zusammengehörigen Elemente in einem Bereich, binden unsere Ereignisse zusammen und schreiben kleine Funktionen, die sehr spezifische Dinge tun.
var slider = {
el: {
slider: $("#slider"),
allSlides: $(".slide")
},
init: function() {
// manual scrolling
this.el.slider.on("scroll", function(event) {
slider.moveSlidePosition(event);
});
},
moveSlidePosition: function(event) {
// Magic Numbers
this.el.allSlides.css({
"background-position": $(event.target).scrollLeft()/6-100+ "px 0"
});
}
};
slider.init();
Das HTML (Hinzufügen von Navigation)
Das Hinzufügen von Swipe-Funktionen wäre super (super) süß (Hinweis). Aber vorerst fügen wir kleine klickbare Links hinzu, um Slides zu wechseln, anstatt uns auf die Scrollleiste zu verlassen. Sie könnten die Scrollleiste im echten Leben sogar entfernen (einfach `overflow: hidden;` auf dem Container). Was wir brauchen, sind Ankerlinks, die auf die IDs der einzelnen Slides verweisen.
<nav class="slider-nav">
<a href="#slide-0" class="active">Slide 0</a>
<a href="#slide-1">Slide 1</a>
<a href="#slide-2">Slide 2</a>
</nav>
Gestalten Sie diese, wie Sie möchten. Für die Demo mache ich sie zu kleinen grauen Kreisen mit verstecktem Text.
Das JavaScript (Hinzufügen von Navigation)
Unsere Struktur ist jetzt nützlicher. Wir fügen einfach ein paar Elemente hinzu, mit denen wir arbeiten, ein neues Ereignis, das wir beobachten (Klicks auf die Navigation), und schreiben eine kleine Funktion, um dieses Ereignis zu behandeln.
Wir wissen, wie weit wir die Scrollposition animieren müssen, wenn ein Navigationslink geklickt wird, basierend auf der ID im Link selbst. Der Link könnte `href="slide-1"` sein, von dem wir leicht "1" extrahieren können. Dann ist die Position, zu der wir scrollen müssen, (1 × Breite des Slides), also 300 in unserem Fall. Diesen Wert von 300 speichern wir direkt im JavaScript.
var slider = {
el: {
slider: $("#slider"),
allSlides: $(".slide"),
sliderNav: $(".slider-nav"),
allNavButtons: $(".slider-nav > a")
},
timing: 800,
slideWidth: 300, // could measure this
init: function() {
// You can either manually scroll...
this.el.slider.on("scroll", function(event) {
slider.moveSlidePosition(event);
});
// ... or click a thing
this.el.sliderNav.on("click", "a", function(event) {
slider.handleNavClick(event, this);
});
},
moveSlidePosition: function(event) {
// Magic Numbers
this.el.allSlides.css({
"background-position": $(event.target).scrollLeft()/6-100+ "px 0"
});
},
handleNavClick: function(event, el) {
// Don't change URL to a hash, remove if you want that
event.preventDefault();
// Get "1" from "#slide-1", for example
var position = $(el).attr("href").split("-").pop();
this.el.slider.animate({
scrollLeft: position * this.slideWidth
}, this.timing);
this.changeActiveNav(el);
},
changeActiveNav: function(el) {
// Remove active from all links
this.el.allNavButtons.removeClass("active");
// Add back to the one that was pressed
$(el).addClass("active");
}
};
slider.init();
Wir haben eine "active"-Klasse auf den Navigationslinks, um sie in CSS visuell anzuzeigen, welcher Slide aktiv ist. Wir behandeln dies, indem wir "active" von allen Links entfernen und dann dem geklickten wieder hinzufügen.
Demo!
Check out this Pen!
Das ist verdammt gut!
Das Nächste, woran ich jetzt denke, ist, ob es eine Möglichkeit gibt, Flicker-Fotos dynamisch zu laden.
Ich wünschte, ich könnte das "liken", haha.
Flickr bietet eine API: http://www.flickr.com/services/api/
Das ist großartig! Touch- und Swipe-Erkennung wären der letzte Schliff (Wortspiel beabsichtigt).
Einfach, es ist großartig. Danke!
Oh, das ist wirklich nett. Tolles Tutorial.
Gerade auf Windows Phone getestet, Touch-Slide funktioniert gut… Danke!
Ein wunderbar köstlicher und subtiler Effekt. Danke fürs Teilen. Leider habe ich das Konzept der *magischen Zahlen* nicht vollständig verstanden. Ich hoffe, jemand kann mich aufklären.
"Magische Zahlen" sind Zahlen, die nicht programmatisch gefunden werden – man muss mit ihnen spielen und herausfinden, welche die gewünschte Wirkung erzielen. In diesem Fall sieht der Effekt besser aus (für den Designer), wenn die `background-position` des Elements auf 100 weniger als die Entfernung von links (`.scrollLeft()`) geteilt durch 6 gesetzt wird.
Das ist großartig. Man kann sogar sehr einfach zusätzliche Bilder hinzufügen, indem man nur ein paar Änderungen vornimmt. Aber gibt es eine Möglichkeit, die Bilder auf einem Touchscreen-Gerät automatisch in der Mitte des Rahmens zu zentrieren, wenn sie geschoben werden? Das wäre perfekt.
Vielen Dank für Ihre harte Arbeit und die Bereitstellung toller Artikel.
Das ist ein wundervolles Tutorial… ich liebe es.
Das Setzen der Breite des Holders als Prozentsatz (300%) des Containers ist großartig. Sie können das Gleiche für die Slides tun – wenn Sie drei Slides haben, ist jeder Slide 33,333…% des Holders. Verwenden Sie genügend signifikante Ziffern, um Subpixelpräzision auf der Auflösung Ihres Zielgeräts zu ermöglichen, und Überlauf (Summe größer als 100%) wird nicht auftreten.
Eine bessere Lösung dafür, die es flexibel (in Design und Inhalt) macht
.slider {
height: 100%;
overflow-x: scroll;
-webkit-overflow-scroll: touch;
.holder {
height: 100%;
white-space: nowrap
}
.slide {
display: inline-block
width: 100%;
height: 100%;
}
Damit haben Sie beliebig viele Elemente. Wenn Sie es nicht im Vollbildmodus möchten, fügen Sie feste Werte zu `.slider` hinzu.
Eine Lösung ohne jQuery, die auch das automatische Scrollen zum "aktiven" Element unterstützt: http://codepen.io/Merri/pen/fdAaI
Das JavaScript ist gut kommentiert, aber man muss seine Closures gut verstehen, um zu begreifen, warum es funktioniert.
Das ist genau das, was ich meinte.
Danke Vesa Piittinen.
Ich habe den Code inzwischen etwas refaktorisiert und neue Funktionen wie Mausrad-Unterstützung und einen Fade-In-Effekt hinzugefügt. Der Code kennt nun immer den aktuellen Slide und setzt die aktive Klasse darauf. Einige Optimierungen wurden vorgenommen, aber die Mischung aus Effekten kann auf einigen Geräten etwas anspruchsvoll sein (box-shadow und text-shadow zusammen mit der Möglichkeit für mehrere Ebenen der Opazität).
Sehr schön, Vesa. Ich nehme an, du unterstützt Swipe-Events. Ich bin nicht in der Nähe eines Geräts, das dies unterstützt.
Hallo Vesa,
Ich habe gerade dein Codepen auf einem Nexus 7 getestet und es hat recht gut funktioniert, es war etwas träge, aber das könnte an all den von dir erwähnten Effekten liegen. Allerdings konnte ich aus irgendeinem Grund auf dem zweiten Slider nicht wischen, auf dem ersten schon. Liegt es daran, dass auf dem ersten Links sind und auf dem zweiten nicht?
Chris,
Nachdem ich kürzlich viel Ähnliches gemacht habe, habe ich festgestellt, dass eine sauberere Alternative zu
ist einfach
wobei Ihr Anker sein könnte
Offensichtlich ist diese Alternative im Kontext des Tutorials nur geringfügig besser, aber wenn Sie *viel* JavaScript oder komplexe Situationen haben, erleichtert die Vorgehensweise das Leben.
Alles andere war perfekt. Das ist ein großartiges Tutorial.
var position = $(el).attr("data-index");könnte auch vereinfacht werden zu
var position = $(el).data("index");Oliver, die jQuery `data`-Methode ist nicht dasselbe wie die Verwendung von HTML5 `data`-Attributen.
http://stackoverflow.com/questions/7261619/jquery-data-vs-attr
Ironischerweise habe ich an einem jQuery-"Plugin" für Lazy-Loading von Hintergrundbildern gearbeitet. https://gist.github.com/yramagicman/5602693
Derzeit funktioniert dies nicht mit Scrollen, aber ich arbeite daran.
Man kann die magischen Zahlen immer vermeiden. Aber es dauert etwas länger, um herauszufinden, woher
" $(event.target).scrollLeft()/6-100 " kommt. Ich habe heute tatsächlich etwas Ähnliches gemacht. Ich habe jQuery verwendet, um die Viewport-Breite, Element-Breite mit Rand usw. zu ermitteln. Und bin bei einer unschönen Gleichung gelandet… aber… keine magischen Zahlen und es funktioniert responsiv :)
Sie können dieses JavaScript verwenden, um 41% der ursprünglichen Größe zu sparen, es macht es irgendwie schneller.
var slider={el:{slider:$("#slider"),allSlides:$(".slide"),sliderNav:$(".slider-nav"),allNavButtons:$(".slider-nav > a")},timing:800,slideWidth:300,init:function(){this.bindUIEvents()},bindUIEvents:function(){this.el.slider.on("scroll",function(a){slider.moveSlidePosition(a)});this.el.sliderNav.on("click","a",function(a){slider.handleNavClick(a,this)})},moveSlidePosition:function(a){this.el.allSlides.css({"background-position":$(a.target).scrollLeft()/6-100+"px 0"})},handleNavClick:function(a,b){a.preventDefault(); var c=$(b).attr("href").split("-").pop();this.el.slider.animate({scrollLeft:c*this.slideWidth},this.timing);this.changeActiveNav(b)},changeActiveNav:function(a){this.el.allNavButtons.removeClass("active");$(a).addClass("active")}};slider.init();Tolle Grafiken, aber was ist das beste Word-Dokument zum Bearbeiten des CSS-Codes? Ich benutze Notepad, was gut funktioniert. Jede Idee wäre willkommen.
Wow! Das ist ein so sauberer Effekt. Ich liebe es!
Gut geschriebener Code… habe gerade versucht, ein paar Bilder mehr zum Slider hinzuzufügen, und es hat perfekt funktioniert..
Sieht einfach großartig aus, danke.
Einfach wunderschön
Wie üblich eine tolle Zusammenfassung, Chris. Danke!
Toller Artikel und Beispiel. Könnte mir jemand sagen, wie ich diesen Slider dazu bringe, von alleine zu laufen und anzuhalten, wenn die Maus über dem Bild ist? Vielen Dank im Voraus.
Das ist wirklich cool, ich mag besonders, wie du dich immer wieder selbst herausforderst, diese Art von Experimenten zum Selbstzweck durchzuführen! Danke!
Nun, wieder einmal inspiriert von CSS-Tricks… Nach der Müdigkeit eines langen Arbeitstages an Formularen und manchmal sinnlosen Kampagnen bringt Ihr Zeug frische Luft und Ideen, die ich kaum erwarten kann auszuprobieren… Und es ist schön zu sehen, wie Sie unter anderem Objekt-Literal-Notation in JS anwenden, DANKE FÜRS TEILEN
Sehr gut, es gibt viele CSS-Tricks, aber dieser hier ist einfach, aber erstaunlich. :)
Schönes Tutorial, aber ich konnte die Anker nicht zum Laufen bringen und das Layout war etwas durcheinander, bis ich "position: relative" zu den Slides (.slide) hinzufügte. Ich denke, das liegt an dem überlagerten Farbverlaufelement.
Sexy Stück Code hier!
Ich habe gesehen, wie das auf Webseiten-Hintergründen gemacht wurde…
Danke, ich suchte nach etwas, um meinen Hintergrund ein wenig gleiten zu lassen,
css-tricks rockt
Ich denke, es ist besser, die Option `overflow-x` auf `hidden` zu setzen.
JA!!! Das ist es, was ich gesucht habe, um diese klobige Scrollleiste unten zu verstecken. DANKE, Andrés.
Sieht super cool aus. Touch-Swipe macht es am besten.
Hallo, nette Sache! Funktioniert gut, aber wenn ich die Abmessungen zum Beispiel auf 900 Breite und 300 Höhe ändere, wird es etwas unordentlich. Hat das etwas mit dem 6-100 zu tun?
Das ist super sexy. Swipe funktioniert auf meinem Android 2.3.6 Handy mit Firefox. Ich glaube, ich werde das verwenden, wenn ich meine Website neu gestalte. :-)
Warum gleitende Hintergründe statt Bilder? Es sollte einfach genug sein, dasselbe mit `img`-Tags und `position` zu machen.
Forken Sie es und machen Sie es.
Ich halte mich immer an die Regel: Wenn es als Hintergrundbild dient, wird es als CSS-Regel verwendet und ich speichere das Bild in einem Ordner innerhalb von `css/images`. Wenn es ein Inhaltsbild ist (ein Logo, Produkt, Galeriebild usw.), wird es in ein `img`-Tag gesetzt. Das ist ein bisschen pingelig, aber so habe ich gelernt, mein Dateisystem organisiert zu halten, und es macht für mich semantisch Sinn.
In diesem Fall werden die Bilder als Hintergrundbild verwendet, warum sollten Sie es also in ein `img`-Tag setzen und zusätzliches CSS für die Positionierung hinzufügen, wenn Sie sonst einen natürlichen Fluss zu Ihrem Markup haben könnten?
Wenn ich den HTML-Code kopiere und einfüge, sodass er sich zweimal wiederholt, bewegt sich beim Verwenden der Scrollleiste des ersten Sliders auch der 2. Slider. Aber nicht umgekehrt.
Wenn ich 3 Slider habe, bewegt das Scrollen des ersten alle 3, aber das Scrollen des 2. bewegt nicht den 3.
Das ist großartig! Ich werde dies verwenden, um den RoyalSlider zu ersetzen, den ich benutze. Ich frage mich, wie einfach es wäre, "Zurück" & "Weiter" Schaltflächen für die Navigation hinzuzufügen…
Neugierig, wird der Parallax-Effekt brechen, wenn dies in Prozent umgewandelt wird? (100% Bildschirmbreite)
Ich bin ganz neu in Javascript / Jquery und bin zufällig auf dieses Tutorial gestoßen und dachte, ich probiere es aus.
Also habe ich den HTML-, CSS- und JS-Code kopiert und eingefügt, der in der Demo bereitgestellt wurde. HTML und CSS funktionieren gut, aber ich bekomme das JS nicht zum Laufen oder kann nicht herausfinden, warum es nicht funktioniert. Es muss etwas sein, das ich im HTML tue (oder nicht tue), da der gesamte Code in der Demo eindeutig funktioniert.
Im Moment versuche ich, eine externe JS-Datei zu verwenden, indem ich den folgenden Code im Kopfbereich des HTML-Dokuments verwende. Wie gesagt, ich bin darin sehr neu und habe das wahrscheinlich alles falsch gemacht.
Könnte mir jemand einem Noob wie mir einen Rat geben, damit das funktioniert?
Ich habe das gleiche Problem, alles außer dem JavaScript funktioniert gut, egal ob ich den Code im Header platziere oder auf eine .js-Datei verlinke. Weiß jemand, was schief gehen könnte?
Ich glaube, Sie müssen die jQuery-Bibliothek im Kopfbereich Ihres HTML-Dokuments importieren, damit die JS-Datei ordnungsgemäß funktioniert, entweder indem Sie auf die neueste gehostete Version verlinken oder indem Sie sie herunterladen und dann auf Ihrem Webserver hochladen.
Hier sind die Anleitungen für beide Methoden, einschließlich herunterladbarer Dateien.
Danke für die sehr gute Erklärung.
Das ist großartig! Es funktioniert für mich perfekt.
Jetzt möchte ich 2 weitere Funktionen hinzufügen:
1) Navigationspunkte können sich beim Touchen des Slides aktualisieren (das ist kein Problem beim Klicken auf die Punkte).
2) Automatisches Abspielen.
Wenn jemand weiß, wie man das macht, bitte um Rat. Danke ~
In unserer Webdesign-Agentur würden wir niemals Seiten mit endlosen Scrolling-Inhalten erstellen. Das ist eine sehr veraltete und unkreative Art des modernen Webdesigns.
Hallo Chris, danke für diesen großartigen Code-Snippet. Eine Sache, die ich bemerkt habe – wenn ich den Code von CODEPEN kopiere und die Dateien lokal neu erstelle – geht irgendwie die Geschmeidigkeit verloren? Was habe ich falsch gemacht?
THX für die Hilfe.
Ich hatte dasselbe Problem stundenlang, bis ich es auf meinen Internetserver hochgeladen habe und dann funktionierte die sanfte Gleitfunktion des JS anmutig! (Obwohl die unterschiedliche Größe meiner Fotos eine andere Geschichte ist. :/ )
Hallo Chris, das Ergebnis sieht toll aus, aber als ich es selbst ausprobiert habe, hat das JavaScript bei mir nicht funktioniert. Ich glaube, das Problem ist, dass ich nicht weiß, wie man mit JavaScript umgeht. Könntest du bitte den notwendigen Code eingeben, um die CSS- und JS-Dateien einzubinden?
Hallo nochmal, nachdem ich die folgenden zwei Codezeilen hinzugefügt habe, funktioniert alles einwandfrei, es ist wirklich großartig!! Danke. Bisher alles gut, aber ich möchte immer noch etwas. Wie kann man das (das Gleiten) automatisch nach, sagen wir mal, 10 Sekunden passieren lassen?
„Zwei Codezeilen“, welche sind das?
Hallo Chris
Ich versuche gerade, diesen Code zum Laufen zu bringen. Das HTML und CSS funktionieren einwandfrei, aber ich kann die Gleitanimation bei den Bildern nicht zum Laufen bringen. Ich kann mir nur denken, dass ich nicht die richtige jQuery-Quelle referenziere. Welche Links müsste ich einfügen, um die jQuery-Bibliothek zu laden?