Blurry Transparent Header Effect from iOS7 in CSS

Avatar of Fabrice Weinberg
Fabrice Weinberg on

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Beitrag ist ein Gastbeitrag von Fabrice Weinberg. Fabrice ist ein regelmäßiger Mitarbeiter hier. Er ist immer auf der Suche nach den neuesten Technologien und Möglichkeiten. Hier, am Anfang von iOS7, schaut er sich an, wie man einen bestimmten Effekt nachbildet, von dem man vielleicht nicht ahnt, dass er im Web überhaupt möglich ist. Es ist knifflig, nutzt brandneue Features, aber machbar!

Beginnen wir mit dem Hintergrund. @simurai fragte vor einiger Zeit, ob es möglich sei, einen Blur-Effekt auf beliebige DOM-Knoten anzuwenden, um den Translucent-Effekt von iOS7 im Control Center zu simulieren (seinen Pen finden Sie hier).

Ich werde nicht genau erklären, wie man diesen Effekt für das Control Center erstellt, sondern mich darauf konzentrieren, wie man etwas Ähnliches wie den Blurred-Header-Effekt erstellt, den man in iMessage und vielen anderen Apps in iOS7 findet. Aber die Tricks, die Sie lernen werden, machen es auch möglich, den Effekt des Control Centers zu erstellen.

iMessage auf iOS 7

Verwendete Technologien

Diese Lösung nutzt intensiv CSS Regions, die noch ein Entwurf sind, aber dank Adobe heute in WebKit/Blink implementiert sind.

Mit der Veröffentlichung von iOS7 ist Mobile Safari der erste Browser, der dieses Feature standardmäßig aktiviert (immer noch mit dem Präfix -webkit-). In Google Chrome 29 müssen Sie nur experimental-webkit-features aktivieren. In Google Chrome 30+ ist es experimental-web-platform-features unter about:flags.

CSS-Regionen

Kurze Einführung in CSS Regions: Es geht darum, die Struktur der Seite vom Inhalt zu trennen. Es gibt zwei neue CSS-Eigenschaften flow-into: named-region; und flow-from: named-region;, die verwendet werden, um eine sogenannte named-region zu definieren. Sie können sich das wie eine Variable vorstellen, die beliebige Inhalte aufnehmen kann.

Das Element mit flow-into darauf ist wie ein Reservoir für Inhalte. Diese Inhalte "fließen" in andere Elemente mit flow-onto darauf.

Ein einfaches Beispiel

Siehe den Pen %= penName %> von Fabrice Weinberg (@FWeinb) auf CodePen

Wenn Ihr Browser Regions unterstützt, werden Sie sehen, dass die Struktur vom Inhalt getrennt ist. Mit flow-into: content wird der Inhalt aus dem Div mit der Klasse .main-content durch beide Divs mit der Klasse .region mithilfe von flow-from: content; geleitet.

Für einen tieferen Einblick in CSS Regions lesen Sie den großartigen Artikel von Arno Gourdol CSS3 regions: Rich page layout with HTML and CSS3

Erste Schritte

Beginnen wir mit der Definition der HTML-Struktur. Sie ist recht einfach. Wir brauchen eine Art Header und einen Container für die Nachrichten. Aufgrund der Verwendung von CSS Regions wird ein weiterer Container benötigt, um den Inhalt zu halten, der durch den Header und den Nachrichten-Container fließen wird.

Siehe den Pen # von Fabrice Weinberg (@FWeinb) auf CodePen

Hier gibt es CSS, um den .header zu verwischen.

Wie im ersten Beispiel fließt alles, was nicht in den .header passt, durch den .content-container.

Das ist nicht das Verhalten, das wir wollen. Wir wollen den gesamten Inhalt im .content-container haben und nur Inhalte verwischen, die vom .header "verdeckt" werden. Lassen Sie uns das beheben.

CSS Regions verwenden, um den DOM zu "beamen"

Dieser Teil ist etwas hacky, da das Verhalten, overflow-y: auto auf ein Element anzuwenden, das die CSS-Eigenschaft flow-into: named-region; erhält, nicht in der Spezifikation beschrieben ist und somit von der Implementierung abhängt.

CSS Regions ermöglichen es uns, den Fluss beliebiger DOM-Knoten zu definieren und sogar overflow-y: auto hinzuzufügen, um den Inhalt scrollbar zu machen. Zusätzlich ist eine definierte Höhe erforderlich.

Verwenden wir das obige Beispiel, indem wir .main-content eine feste Höhe und overflow-y: scroll hinzufügen

Siehe den Pen %= penName %> von Fabrice Weinberg (@FWeinb) auf CodePen

Das sieht noch nicht gut aus. Das Scrollen funktioniert, aber der .header bleibt leer.

Jetzt kommt der spaßige Teil: Wir werden den Inhalt von .main-content zum .header-Element "beamen". Dies kann mit CSS3 geschehen, indem die gesamte Inhaltsebene von .main-content mit transform: translateY() transformiert wird, um .main-content um die Höhe des .headers nach oben zu verschieben.

Siehe den Pen %= penName %> von Fabrice Weinberg (@FWeinb) auf CodePen

Das sieht besser aus! Aber immer noch stimmt etwas nicht. Es gibt immer Inhalt, der vom .header verdeckt wird. Um dies zu beheben, müssen wir einfach die Höhe des .header als padding-top zum .main-content hinzufügen, um den beanspruchten Platz auszugleichen.

Siehe den Pen b8cc5b9a310ff94de8c707c24a3c99d0 von Fabrice Weinberg (@FWeinb) auf CodePen

Das war's. Das ist die Kerntechnik, die verwendet wird, um den iOS7-Translucent/Blurry-Effekt zu erzielen. Basierend auf dieser Technik habe ich dieses kleine Spielplatz gebaut, auf dem Sie den Header anpassen und sogar eine Tintenfarbe hinzufügen können.

Siehe den Pen iOS7 Translucent CSS von Fabrice Weinberg (@FWeinb) auf CodePen

Performance zählt

Werfen wir einen Blick auf die Renderleistung dieses Effekts

Chrome DevTools „Vorher“-Timeline
Tipp: Verwenden Sie die Debug-Ansicht auf CodePen zum Messen von Timelines. Stellen Sie sicher, dass Sie alle Ihre Plugins deaktivieren. Navigieren Sie einfach zu http://codepen.io/[username]/debug/[penid]. Denken Sie daran, dass dies nur für Pens funktioniert, die Ihnen gehören und während Sie angemeldet sind.

Oben sehen Sie eine Timeline, die während des Scrollens nach oben und unten aufgenommen wurde. Sie sehen, dass fast die Hälfte der verfügbaren Zeit pro Frame (16,66 ms) für das Painting verwendet wird. Bevor wir uns damit befassen, möchte ich Ihnen von einer großartigen neuen Funktion in den Chrome DevTools erzählen: Layers. Dies ist ein neuer Tab in den DevTools, in dem Sie sehen können, welche Elemente Chrome auf seine eigene Ebene in einem Dokument befördert. Es ist noch experimentell, daher müssen Sie das devtools-experiments-Flag in about:flags aktivieren. Starten Sie Chrome danach neu. Um das Layers-Experiment zu aktivieren, öffnen Sie die DevTools, klicken Sie auf das Schraubenschlüssel-Symbol unten rechts (oder drücken Sie ?), um die Einstellungen zu öffnen.

Aktivieren des Layers-Panels

Verwendung des Layers-Tabs

Oben sehen Sie den geöffneten Layers-Tab. Chrome hat nur eine Ebene für das gesamte Dokument erstellt, das bedeutet, dass jede Änderung auf der Seite ein Repainting des gesamten Dokuments auslöst. Das ist teuer! Möglicherweise haben Sie das Kontrollkästchen in der oberen linken Ecke bemerkt. Es wird verwendet, um transform: translateZ(0) auf das .header-Element anzuwenden. Sie finden den Pen hier. Der transform: translateZ(0)-Hack wird verwendet, um ein Element auf seine eigene Ebene auf der GPU zu befördern.

Tipp: Sie können die Layers im Layers Tab durch Ziehen mit der Maus drehen.

Wie Sie sehen, gibt es jetzt eine zusätzliche Ebene für das div.header. Machen wir eine weitere Timeline, jetzt mit dem transform: translateZ(0)-Hack

Chrome DevTools „Nachher“-Timeline

Das sieht schon viel besser aus. Die Paint-Kosten betragen jetzt nur noch etwa 1/10 der Gesamtzeit pro Frame. Mit dem neuen Layers-Tab ist es nun viel einfacher zu sehen, wo Chrome Ebenen erstellt hat und wo potenzielle Leistungsengpässe liegen.

Zusammenfassung

Es ist faszinierend zu sehen, dass dies heute in WebKit/Blink möglich ist. Aber (es gibt immer ein Aber) diese Technik ist noch nicht für die Produktion bereit. Obwohl sie auf dem Desktop recht gut funktioniert, funktioniert sie derzeit nicht unter iOS7, sie ist **langsam** und **Scrollen funktioniert überhaupt nicht**.

Ich habe ein GitHub-Repository erstellt, in dem Sie den Quellcode für den Spielplatz finden.

Wenn jemand eine Idee hat, wie man das Scrollen unter iOS7 realisieren kann (vorzugsweise ohne JavaScript), würde ich es gerne wissen! Ich hoffe, Sie haben ein oder zwei neue Tricks gelernt. Danke fürs Lesen!