Web-Styling-Funktionen von heute und morgen, wie sie auf der Google IO 2022 vorgestellt wurden, sowie einige Extras.
2022 wird eines der besten Jahre für CSS werden, sowohl in Bezug auf Funktionen als auch auf gemeinsame Browserfunktionsveröffentlichungen. Unser gemeinsames Ziel ist es, 14 Funktionen zu implementieren.
Übersicht
Dieser Artikel ist die schriftliche Fassung des Vortrags, der auf der Google IO 2022 gehalten wurde. Es ist nicht als ausführlicher Leitfaden zu den einzelnen Funktionen gedacht, sondern nur als Einführung und kurze Übersicht, um Ihr Interesse zu wecken. Wenn Ihr Interesse geweckt wurde, finden Sie am Ende eines Abschnitts Links zu Ressourcen mit weiteren Informationen.
Inhaltsverzeichnis
Über die Liste unten gelangen Sie zu den Themen, die Sie interessieren:
Browserkompatibilität
Ein Hauptgrund dafür, dass so viele CSS-Funktionen gemeinsam veröffentlicht werden, sind die Bemühungen von Interop 2022. Bevor wir uns die Bemühungen zur Interoperabilität ansehen, ist es wichtig, sich die Bemühungen von Compat2021 anzusehen.
Compat 2021
Die Ziele für 2021, die auf dem Feedback von Entwicklern in Umfragen basieren, waren die Stabilisierung der aktuellen Funktionen, die Verbesserung der Testsuite und die Steigerung der Bestehensnoten von Browsern für fünf Funktionen:
sticky
Positionierungaspect-ratio
Größe- Layout:
flex
- Layout:
grid
transform
Positionierung und Animation
Die Testergebnisse wurden insgesamt verbessert, was für eine bessere Stabilität und Zuverlässigkeit spricht. Herzlichen Glückwunsch an die Teams!
Interop 2022
In diesem Jahr haben sich die Browserhersteller getroffen, um die Funktionen und Prioritäten zu besprechen, an denen sie arbeiten wollten, und ihre Bemühungen zu bündeln. Es plante die Bereitstellung der folgenden Webfunktionen für Entwickler:
@layer
- Farbräume und Funktionen
- Eindämmung
<dialog>
- Formularkompatibilität
- Scrollen
- Unterraster
- Typografie
- Darstellungsbereichseinheiten
- Webkompatibilität
Das ist eine spannende und ehrgeizige Liste, die ich mit Spannung verfolge.
Neu für 2022
Unverwunderlich ist, dass der Stand von CSS 2022 stark von den Arbeiten an Interop 2022 beeinflusst wird.
Kaskadierende Ebenen
Vor @layer
war die Reihenfolge der geladenen Stylesheets sehr wichtig, da zuletzt geladene Stile zuvor geladene Stile überschreiben können. Dies führte zu sorgfältig verwalteten Einstiegs-Stylesheets, bei denen Entwickler weniger wichtige Stile zuerst und wichtigere Stile später laden mussten. Es gibt ganze Methodiken, die Entwicklern dabei helfen, diese Bedeutung zu verwalten, z. B. ITCSS.
Mit @layer
können in der Eingabedatei Ebenen und ihre Reihenfolge vorab definiert werden. Wenn Stile geladen oder definiert werden, können sie in einer Ebene platziert werden, wodurch die Wichtigkeit der Stilüberschreibung erhalten bleibt, ohne dass die Ladeabläufe akribisch verwaltet werden müssen.
Das Video zeigt, wie die definierten Kaskadenebenen einen flexibleren und freieren Erstellungs- und Ladevorgang ermöglichen, während die Kaskade nach Bedarf beibehalten wird.
Mit den Chrome-Entwicklertools können Sie sich ansehen, welche Stile aus welchen Ebenen stammen:
Ressourcen
- CSS Cascade 5-Spezifikation
- Erläuterung zu kaskadierenden Ebenen
- Kaskadierende Ebenen in der MDN
- Una Kravets: Cascade Layers
- Ahmad Shadeed: Hallo, CSS-Kaskadenschichten
Unterraster
Vor subgrid
konnte sich ein Raster innerhalb eines anderen Rasters nicht an den übergeordneten Zellen oder Rasterlinien ausrichten. Jedes Rasterlayout war einzigartig. Viele Designer platzieren ein einzelnes Raster über ihr gesamtes Design und richten Elemente darin konstant aus, was in CSS nicht möglich wäre.
Nach subgrid
kann ein untergeordnetes Element eines Rasters die Spalten oder Zeilen des übergeordneten Elements übernehmen und sich selbst oder seine untergeordneten Elemente an diesen ausrichten.
In der folgenden Demo wird mit dem Body-Element ein klassisches Raster mit drei Spalten erstellt: Die mittlere Spalte heißt main
und die linken und rechten Spalten haben die Namen ihrer Zeilen, also fullbleed
. Anschließend übernehmen alle Elemente im Textkörper, <nav>
und <main>
, die benannten Zeilen aus dem Textkörper, indem grid-template-columns: subgrid
festgelegt wird.
body {
display: grid;
grid-template-columns:
[fullbleed-start]
auto [main-start] min(90%, 60ch) [main-end] auto
[fullbleed-end]
;
}
body > * {
display: grid;
grid-template-columns: subgrid;
}
Untergeordnete Elemente von <nav>
oder <main>
können sich anhand der Spalten und Zeilen fullbleed
und main
ausrichten oder ihre Größe anpassen.
.main-content {
grid-column: main;
}
.fullbleed {
grid-column: fullbleed;
}
Mithilfe der Entwicklertools können Sie die Linien und Unterraster sehen (derzeit nur in Firefox). In der folgenden Abbildung wurden das übergeordnete Raster und die untergeordneten Gitter überlagert. Es ähnelt jetzt dem, was sich die Designer für das Layout vorgestellt hatten.
Im Bereich „Elemente“ der DevTools sehen Sie, welche Elemente Raster und untergeordnete Raster sind. Das ist sehr hilfreich für die Fehlerbehebung oder Validierung des Layouts.
Ressourcen
- Subgrid – Spezifikation
- Unterraster auf der MDN
- Bramus: Praktische Videoanleitungen für CSS-Subgrids
Containerabfragen
Vor @container
konnten Elemente einer Webseite nur auf die Größe des gesamten Darstellungsbereichs reagieren. Das ist hervorragend für Makro-Layouts geeignet, aber bei Mikrolayouts, bei denen ihr äußerer Container nicht den gesamten Darstellungsbereich ausmacht, kann das Layout nicht entsprechend angepasst werden.
Nach @container
können Elemente auf die Größe oder den Stil eines übergeordneten Containers reagieren.
Der einzige Vorbehalt besteht darin, dass die Container sich selbst als mögliche Abfrageziele deklarieren müssen. Dies ist nur eine geringe Voraussetzung für einen großen Nutzen.
/* establish a container */
.day {
container-type: inline-size;
container-name: calendar-day;
}
Durch diese Stile können die Spalten Mo, Di, Mi, Do und Fr im folgenden Video von den Ereigniselementen abgefragt werden.
Hier sehen Sie den CSS-Code, mit dem Sie die Größe des calendar-day
-Containers abfragen und dann das Layout und die Schriftgrößen anpassen:
@container calendar-day (max-width: 200px) {
.date {
display: block;
}
.date-num {
font-size: 2.5rem;
display: block;
}
}
Hier ist ein weiteres Beispiel: Eine Buchkomponente passt sich dem verfügbaren Platz in der Spalte an, in die sie gezogen wird:
Una hat die Situation richtig als das neue responsive bewertet. Bei der Verwendung von @container
müssen viele spannende und sinnvolle Designentscheidungen getroffen werden.
Ressourcen
- Spezifikation für Containerabfragen
- Erläuterung zu Containerabfragen
- Containerabfragen auf der MDN
- Das neue responsive Design auf web.dev
- Kalender-Demo von Una
- Awesome container queries collection
- So haben wir Designcember auf web.dev erstellt
- Ahmad Shadeed: Hallo CSS-Containerabfragen
accent-color
Vor accent-color
mussten Sie für ein Formular mit markenkonformen Farben komplexe Bibliotheken oder CSS-Lösungen verwenden, die mit der Zeit schwer zu verwalten waren. Sie haben zwar alle Optionen zur Verfügung gestellt und hoffentlich auch die Barrierefreiheit berücksichtigt, aber die Entscheidung, ob Sie die integrierten Komponenten verwenden oder Ihre eigenen verwenden möchten, wird immer mühsamer.
Nach accent-color
wird mit einer CSS-Zeile eine Markenfarbe für die integrierten Komponenten festgelegt. Zusätzlich zu einer Färbung wählt der Browser intelligent geeignete Kontrastfarben für die Nebenteile der Komponente aus und passt sich an die Systemfarbschemata (hell oder dunkel) an.
/* tint everything */
:root {
accent-color: hotpink;
}
/* tint one element */
progress {
accent-color: indigo;
}
Weitere Informationen zu accent-color
finden Sie in meinem Artikel auf web.dev, in dem ich viele weitere Aspekte dieser nützlichen CSS-Eigenschaft beschreibe.
Ressourcen
- Fokusfarbe
- accent-color in der MDN
- accent-color auf web.dev
- Bramus: Benutzeroberflächenelemente mit CSS-Akzentfarbe einfärben
Farbebene 4 und 5
In den letzten Jahrzehnten wurde das Web von sRGB dominiert. In der wachsenden digitalen Welt mit hochauflösenden Displays und Mobilgeräten mit OLED- oder QLED-Bildschirmen reicht sRGB jedoch nicht mehr aus. Außerdem werden dynamische Seiten erwartet, die sich an die Nutzereinstellungen anpassen. Die Farbverwaltung ist für Designer, Designsysteme und Code-Entwickler ein wachsendes Problem.
Aber nicht 2022. CSS bietet eine Reihe neuer Farbfunktionen und -räume: – Farben, die die HD-Farbfunktionen von Displays nutzen. – Farbräume, die einem Intent entsprechen, z. B. perzeptive Einheitlichkeit. – Farbräume für Farbverläufe, die die Interpolationsergebnisse drastisch verändern. – Farbfunktionen, mit denen Sie Farben kombinieren und Kontraste herstellen sowie den Arbeitsbereich auswählen können.
Vor all diesen Farbfunktionen mussten Designsysteme die richtigen kontrastierenden Farben vorab berechnen und eine entsprechend lebendige Farbpalette gewährleisten, während Präprozessoren oder JavaScript den Großteil der Arbeit übernahmen.
Nach all diesen Farbfunktionen können der Browser und CSS die gesamte Arbeit erledigen, dynamisch und genau zur richtigen Zeit. Anstatt viele KBs von CSS und JavaScript an Nutzer zu senden, um Farben für das Design und die Datenvisualisierung zu aktivieren, kann CSS die Orchestrierung und Berechnungen durchführen. Außerdem ist CSS besser in der Lage, vor der Verwendung die Unterstützung zu prüfen oder Fallbacks ordnungsgemäß zu verarbeiten.
@media (dynamic-range: high) {
.neon-pink {
--neon-glow: color(display-p3 1 0 1);
}
}
@supports (color: lab(0% 0 0)) {
.neon-pink {
--neon-glow: lab(150% 160 0);
}
}
hwb()
HWB steht für Farbton, Weiß und Schwarz. Es ist eine nutzerfreundliche Möglichkeit, Farbe auszudrücken, da es sich nur um einen Farbton und eine Menge Weiß oder Schwarz handelt, um die Farbe heller oder dunkler zu machen. Künstler, die Farben mit Weiß oder Schwarz mischen, werden diese Ergänzung der Farbsyntax zu schätzen wissen.
Die Verwendung dieser Farbfunktion führt zu Farben aus dem sRGB-Farbraum, genau wie bei HSL und RGB. Im Hinblick auf Neuheiten für 2022 gibt es keine neuen Farben, aber es kann einige Aufgaben für Fans der Syntax und des mentalen Modells erleichtern.
Ressourcen
Farbräume
Die Darstellung von Farben erfolgt über einen Farbraum. Jeder Farbraum bietet verschiedene Funktionen und Vor- und Nachteile für die Arbeit mit Farben. Manche packen alle leuchtenden Farben zusammen, andere ordnen sie zuerst nach Helligkeit an.
2022 wird CSS zehn neue Farbräume bieten, die jeweils über einzigartige Funktionen verfügen, um Designern und Entwicklern beim Darstellen, Auswählen und Mischen von Farben zu helfen. Früher war sRGB die einzige Option für die Arbeit mit Farben, aber jetzt erschließt CSS neue Möglichkeiten und einen neuen Standardfarbraum, LCH.
color-mix()
Vor color-mix()
benötigten Entwickler und Designer Pre-Prozessoren wie Sass, um die Farben zu mischen, bevor sie im Browser angezeigt wurden.
Bei den meisten Farbmischfunktionen konnte auch nicht angegeben werden, in welchem Farbraum die Mischung erfolgen soll, was manchmal zu verwirrenden Ergebnissen führte.
Nach color-mix()
können Entwickler und Designer Farben im Browser zusammen mit allen anderen Stilen kombinieren, ohne Build-Prozesse ausführen oder JavaScript einbinden zu müssen. Außerdem können sie angeben, in welchem Farbraum die Mischung erfolgen soll, oder den Standard-Farbraum für die Mischung (LCH) verwenden.
Häufig wird eine Markenfarbe als Basis verwendet und daraus werden Varianten erstellt, z. B. hellere oder dunklere Farben für Hover-Stile. Das sieht bei color-mix()
so aus:
.color-mix-example {
--brand: #0af;
--darker: color-mix(var(--brand) 25%, black);
--lighter: color-mix(var(--brand) 25%, white);
}
Wenn Sie diese Farben in einem anderen Farbraum wie sRGB mischen möchten, ändern Sie Folgendes:
.color-mix-example {
--brand: #0af;
--darker: color-mix(in srgb, var(--brand) 25%, black);
--lighter: color-mix(in srgb, var(--brand) 25%, white);
}
Hier ist eine Demo für die Themenfunktion mit color-mix()
. Probieren Sie, die Markenfarbe zu ändern, und sehen Sie sich das aktualisierte Design an:
Viel Spaß beim Mischen von Farben in verschiedenen Farbräumen in Ihren Stylesheets in 2022!
Ressourcen
- Spezifikation für „color-mix()“
- color-mix() in der MDN
- Demo für Designs
- Weitere Demo für das Design
- Fabio Giolito: Mit diesen anstehenden CSS-Funktionen ein Farbschema erstellen
color-contrast()
Vor color-contrast()
mussten Stylesheet-Entwickler die barrierefreien Farben im Voraus kennen. Oft zeigt eine Palette schwarzen oder weißen Text auf einem Farbmuster an, um Nutzern des Farbsystems zu zeigen, welche Textfarbe für einen angemessenen Kontrast mit diesem Muster erforderlich ist.
Nach color-contrast()
können Stylesheet-Autoren die Aufgabe vollständig an den Browser auslagern. Sie können den Browser nicht nur dazu verwenden, automatisch eine schwarze oder weiße Farbe auszuwählen, sondern auch eine Liste mit passenden Farben für das Designsystem angeben und die erste Farbe auswählen lassen, die das gewünschte Kontrastverhältnis erfüllt.
Hier ist ein Screenshot einer Demo für eine HWB-Farbpalette, bei der die Textfarben automatisch vom Browser basierend auf der Farbmusterfarbe ausgewählt werden:
Die grundlegende Syntax sieht so aus: Hier wird „grau“ an die Funktion übergeben und der Browser bestimmt, ob Schwarz oder Weiß den größten Kontrast hat:
color: color-contrast(gray);
Die Funktion kann auch mit einer Liste von Farben angepasst werden, um die Farbe mit dem höchsten Kontrast auszuwählen:
color: color-contrast(gray vs indigo, rebeccapurple, hotpink);
Falls Sie nicht die Farbe mit dem höchsten Kontrast aus der Liste auswählen möchten, können Sie auch ein Zielkontrastverhältnis angeben und die erste zu übergebende Farbe auswählen:
color: color-contrast(
var(--bg-blue-1)
vs
var(--text-lightest), var(--text-light), var(--text-subdued)
to AA /* 4.5 could also be passed */
);
Diese Funktion kann nicht nur für die Textfarbe verwendet werden, obwohl ich davon ausgehe, dass dies der Haupteinsatzzweck ist. Stellen Sie sich vor, wie viel einfacher es sein wird, barrierefreie und gut lesbare Oberflächen zu erstellen, wenn die Auswahl geeigneter kontrastreicher Farben in die CSS-Sprache selbst integriert ist.
Ressourcen
Syntax für relative Farben
Vor der relativen Farbsyntax mussten die Farbkanäle einzeln in benutzerdefinierte Properties eingefügt werden, um Farben zu berechnen und Anpassungen vorzunehmen. Aufgrund dieser Einschränkung wurde HSL auch zur primären Farbfunktion für die Farbmanipulation, da Farbton, Sättigung oder Helligkeit mit calc()
ganz einfach angepasst werden konnten.
Mit der relativen Farbsyntax kann jede Farbe in jedem Bereich in einer einzigen CSS-Zeile dekonstruiert, geändert und als Farbe zurückgegeben werden. HSL hat keine Einschränkungen mehr. Es können in jedem gewünschten Farbraum Änderungen vorgenommen werden und es müssen viel weniger benutzerdefinierte Eigenschaften erstellt werden, um dies zu vereinfachen.
Im folgenden Syntaxbeispiel wird eine Hexadezimalzahl für die Basisfarbe angegeben und zwei neue Farben werden relativ dazu erstellt. Die erste Farbe --absolute-change
erstellt eine neue Farbe im LCH-Farbraum aus der Grundfarbe und ersetzt dann die Helligkeit der Grundfarbe durch 75%
. Dabei bleiben der Farbton (h
) und die Farbsättigung (c
) unverändert. Die zweite Farbe --relative-change
erstellt eine neue Farbe im LCH-Farbraum aus der Grundfarbe, reduziert dabei aber die Farbsättigung (c
) um 20 %.
.relative-color-syntax {
--color: #0af;
--absolute-change: lch(from var(--color) 75% c h);
--relative-change: lch(from var(--color) l calc(c-20%) h);
}
Es ähnelt dem Mischen von Farben, ähnelt aber eher Änderungen als dem Mischen. Sie können eine Farbe von einer anderen Farbe ausgeben und erhalten Zugriff auf die drei Kanalwerte, die von der verwendeten Farbfunktion benannt werden. Außerdem haben Sie die Möglichkeit, diese Kanäle anzupassen. Alles in allem ist dies eine sehr coole und leistungsstarke Syntax für die Farbe.
In der folgenden Demo habe ich die relative Farbsyntax verwendet, um hellere und dunklere Varianten einer Grundfarbe zu erstellen. Außerdem habe ich color-contrast()
verwendet, damit die Labels einen geeigneten Kontrast haben:
Diese Funktion kann auch zum Erstellen einer Farbpalette verwendet werden. Hier ist eine Demo, in der ganze Paletten anhand einer bereitgestellten Grundfarbe generiert werden. Dieser CSS-Code wird für alle verschiedenen Paletten verwendet. Jede Palette bietet einfach eine andere Basis. Da ich LCH verwendet habe, sehen Sie sich als Bonus an, wie visuell gleichmäßig die Paletten sind. Dank dieses Farbraums sind keine Hotspots oder Totzonen zu sehen.
:root {
--_color-base: #339af0;
--color-0: lch(from var(--_color-base) 98% 10 h);
--color-1: lch(from var(--_color-base) 93% 20 h);
--color-2: lch(from var(--_color-base) 85% 40 h);
--color-3: lch(from var(--_color-base) 75% 46 h);
--color-4: lch(from var(--_color-base) 66% 51 h);
--color-5: lch(from var(--_color-base) 61% 52 h);
--color-6: lch(from var(--_color-base) 55% 57 h);
--color-7: lch(from var(--_color-base) 49% 58 h);
--color-8: lch(from var(--_color-base) 43% 55 h);
--color-9: lch(from var(--_color-base) 39% 52 h);
--color-10: lch(from var(--_color-base) 32% 48 h);
--color-11: lch(from var(--_color-base) 25% 45 h);
--color-12: lch(from var(--_color-base) 17% 40 h);
--color-13: lch(from var(--_color-base) 10% 30 h);
--color-14: lch(from var(--_color-base) 5% 20 h);
--color-15: lch(from var(--_color-base) 1% 5 h);
}
Hoffentlich haben Sie inzwischen verstanden, wie Farbräume und verschiedene Farbfunktionen je nach ihren Stärken und Schwächen für verschiedene Zwecke verwendet werden können.
Ressourcen
- Spezifikation der Syntax für relative Farben
- Farbpaletten mit relativer Farbsyntax erstellen
- Farbvarianten mit relativer Farbsyntax erstellen
Farbräume für Farbverläufe
Vor der Einführung von Farbräumen für Farbverläufe war sRGB der Standardfarbraum. sRGB ist im Allgemeinen zuverlässig, hat aber einige Schwächen wie die graue Totzone.
Geben Sie nach den Farbräumen für Farbverläufe an, welchen Farbraum der Browser für die Farbinterpolation verwenden soll. So können Entwickler und Designer den gewünschten Farbverlauf auswählen. Der Standardfarbraum wird ebenfalls von sRGB zu LCH geändert.
Die Syntaxerweiterung folgt der Richtung des Farbverlaufs, verwendet die neue in
-Syntax und ist optional:
background-image: linear-gradient(
to right in hsl,
black, white
);
background-image: linear-gradient(
to right in lch,
black, white
);
Hier sehen Sie einen einfachen und wichtigen Farbverlauf von Schwarz nach Weiß. Sehen Sie sich den Bereich der Ergebnisse in den einzelnen Farbräumen an. Einige erreichen dunkles Schwarz früher als andere, andere verblassen zu spät zu Weiß.
Im nächsten Beispiel wird Schwarz in Blau überführt, da es ein bekannter Problembereich für Farbverläufe ist. Bei der Farbinterpolation schleichen sich in den meisten Farbräumen Lilatöne ein. Ich denke dabei gerne an Farben, die innerhalb ihres Farbraums von Punkt A nach Punkt B wandern. Da der Farbverlauf eine gerade Linie von Punkt A nach Punkt B nimmt, ändern sich die Zwischentöne, die der Pfad auf dem Weg nimmt, drastisch durch die Form des Farbraums.
Ausführlichere Untersuchungen, Beispiele und Kommentare finden Sie in diesem Twitter-Thread.
Ressourcen
- Spezifikation für die Interpolation von Farbverläufen
- Demo zum Vergleichen von Farbverläufen in Gruppenbereichen
- Observable Notebook zum Vergleichen von Gradienten
inert
Vor inert
war es eine gute Praxis, die Aufmerksamkeit der Nutzer auf Bereiche der Seite oder App zu lenken, die sofortige Aufmerksamkeit erforderten. Diese geführte Fokusstrategie wurde als Fokustrapping bekannt, da Entwickler den Fokus auf einen interaktiven Bereich platzierten, auf Fokusänderungsereignisse warteten und den interaktiven Bereich wieder zurück in den Fokus brachte. Nutzer, die Tastaturen oder Screenreader verwenden, werden zum interaktiven Bereich zurückgeleitet, um sicherzustellen, dass die Aufgabe abgeschlossen ist, bevor sie fortfahren.
Nach dem inert
ist keine Überführung mehr erforderlich, da Sie ganze Bereiche der Seite oder App einfrieren oder schützen können. Klicks und Versuche, den Fokus zu ändern, sind einfach nicht mehr verfügbar, solange diese Teile eines Dokuments inaktiv sind. Man könnte sich das auch als Wachen statt als Falle vorstellen, bei der inert
nicht daran interessiert ist, Sie an einem Ort festzuhalten, sondern andere Orte unzugänglich zu machen.
Ein gutes Beispiel hierfür ist die JavaScript-Funktion alert()
:
Beachten Sie im vorherigen Video, dass die Seite mit Maus und Tastatur zugänglich war, bis alert()
aufgerufen wurde. Nachdem das Pop-up-Dialogfeld mit der Warnung angezeigt wurde, war der Rest der Seite eingefroren (inert
). Der Fokus des Nutzers wird innerhalb des Dialogfelds für Benachrichtigungen platziert, sodass er nichts weiter tun kann. Sobald der Nutzer interagiert und die Anfrage für eine Benachrichtigungsfunktion abgeschlossen hat, ist die Seite wieder interaktiv. Mit inert
können Entwickler genau diese geführte Fokussierung problemlos umsetzen.
Hier ist ein kleines Codebeispiel, das die Funktionsweise veranschaulicht:
<body>
<div class="modal">
<h2>Modal Title</h2>
<p>...<p>
<button>Save</button>
<button>Discard</button>
</div>
<main inert>
<!-- cannot be keyboard focused or clicked -->
</main>
</body>
Ein Dialogfeld ist ein gutes Beispiel, aber inert
ist auch hilfreich für Dinge wie das ausblendbare seitliche Menü. Wenn ein Nutzer das Seitenmenü ausblendet, darf die Maus oder Tastatur nicht mit der dahinter liegenden Seite interagieren. Das ist für Nutzer etwas schwierig. Wenn das Seitenmenü angezeigt wird, sollte die Seite stattdessen inaktiv sein. Nutzer müssen das Seitenmenü dann schließen oder sich darin bewegen. Sie werden also nicht auf einer anderen Seite mit einem geöffneten Menü landen.
Ressourcen
COLRv1-Schriftarten
Vor COLRv1-Schriftarten gab es im Web OT-SVG-Schriftarten, ein weiteres offenes Format für Schriftarten mit Farbverläufen und integrierten Farben und Effekten. Diese Elemente konnten sehr groß werden und ermöglichen zwar das Bearbeiten des Textes, die Anpassung war jedoch nicht groß.
Nach COLRv1-Schriftarten gibt es im Web eine kleinere Angriffsfläche, vektorskalierbare, neupositionierbare, Farbverlaufs- und Mischmodus-gestützte Schriftarten, die Parameter akzeptieren, um die Schriftart an den jeweiligen Anwendungsfall oder an eine Marke anzupassen.
Hier ist ein Beispiel aus dem Blogpost für Chrome-Entwickler zum Thema Emojis. Vielleicht haben Sie schon bemerkt, dass Emojis bei einer größeren Schriftgröße nicht mehr scharf sind. Es ist ein Bild und keine Vektorgrafik. In Anwendungen wird ein Emoji häufig durch ein Asset mit höherer Qualität ersetzt. Mit COLRv1-Schriftarten sind die Emojis vektorbasiert und ansprechend:
Mit Symbolschriften lassen sich mit diesem Format erstaunliche Dinge tun, z. B. benutzerdefinierte Duoton-Farbpaletten. Das Laden einer COLRv1-Schriftart funktioniert genauso wie bei jeder anderen Schriftdatei:
@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
Die Anpassung der COLRv1-Schrift erfolgt mit @font-palette-values
, einer speziellen CSS-At-Regel, mit der eine Reihe von Anpassungsoptionen zu einem Bundle gruppiert und benannt werden können, um sie später wiederverwenden zu können. Wie bei benutzerdefinierten Properties beginnt auch der Name eines benutzerdefinierten Namens mit --
:
@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
@font-palette-values --colorized {
font-family: "Bungee Spice";
base-palette: 0;
override-colors: 0 hotpink, 1 cyan, 2 white;
}
Nachdem Sie --colorized
als Alias für die Anpassungen festgelegt haben, besteht der letzte Schritt darin, die Palette auf ein Element anzuwenden, das die Farbschriftfamilie verwendet:
@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
@font-palette-values --colorized {
font-family: "Bungee Spice";
base-palette: 0;
override-colors: 0 hotpink, 1 cyan, 2 white;
}
.spicy {
font-family: "Bungee Spice";
font-palette: --colorized;
}
Da immer mehr variable Schriftarten und Farbschriftarten zur Verfügung stehen, ist die Webtypografie auf einem hervorragenden Weg zu vielfältigen Anpassungsmöglichkeiten und kreativen Ausdrucksmöglichkeiten.
Ressourcen
- Colrv1-Spezifikation auf GitHub
- Chrome-Entwickler: Colrv1 Fonts
- Erklärvideo für Entwickler zu BlinkOn
Darstellungsbereichseinheiten
Vor den neuen Darstellungsbereichsvarianten wurden im Web physische Einheiten verwendet, um Darstellungsbereiche anzupassen. Es gab eine für Höhe, Breite, kleinste Größe (vmin) und größte Seite (vmax). Das funktionierte für viele Dinge gut, aber mobile Browser führten zu einer gewissen Komplexität.
Auf Mobilgeräten wird beim Laden einer Seite die Statusleiste mit der URL angezeigt. Diese Leiste belegt einen Teil des Darstellungsbereichs. Nach einigen Sekunden und etwas Interaktivität kann die Statusleiste ausgeblendet werden, um dem Nutzer einen größeren Darstellungsbereich zu bieten. Verschiebt diese Leiste jedoch heraus, hat sich die Höhe des Darstellungsbereichs geändert und alle vh
-Einheiten werden verschoben und vergrößert, wenn sich die Zielgröße ändert.
In späteren Jahren musste die vh
-Abteilung speziell entscheiden, welche der beiden Viewport-Größen sie verwenden wollte, da es auf Mobilgeräten zu unschönen visuellen Layoutproblemen kam. Es wurde ermittelt, dass vh
immer den größten Darstellungsbereich darstellt.
.original-viewport-units {
height: 100vh;
width: 100vw;
--size: 100vmin;
--size: 100vmax;
}
Nach den neuen Darstellungsbereichsvarianten werden kleine, große und dynamische Darstellungsbereichseinheiten verfügbar gemacht. Außerdem werden den physischen Darstellungsbereichen logische Entsprechungen hinzugefügt. Die Idee ist, Entwicklern und Designern die Möglichkeit zu geben, die Einheit auszuwählen, die sie für ihr Szenario verwenden möchten. Vielleicht ist es in Ordnung, eine kleine irritierende Layoutverschiebung zu haben, wenn die Statusleiste ausgeblendet wird, damit dvh
(dynamische Höhe des Darstellungsbereichs) ohne Bedenken verwendet werden kann.
Hier finden Sie eine vollständige Liste aller neuen Optionen für die Darstellungseinheit, die mit den neuen Darstellungsvarianten verfügbar sind:
.new-height-viewport-units { height: 100vh; height: 100dvh; height: 100svh; height: 100lvh; block-size: 100vb; block-size: 100dvb; block-size: 100svb; block-size: 100lvb; }
.new-width-viewport-units { width: 100vw; width: 100dvw; width: 100svw; width: 100lvw; inline-size: 100vi; inline-size: 100dvi; inline-size: 100svi; inline-size: 100lvi; }
.new-min-viewport-units { --size: 100vmin; --size: 100dvmin; --size: 100svmin; --size: 100lvmin; }
.new-max-viewport-units { --size: 100vmax; --size: 100dvmax; --size: 100svmax; --size: 100lvmax; }
Wir hoffen, dass diese Funktionen Entwicklern und Designern die Flexibilität bieten, die sie für ihre responsiven Designs benötigen.
Ressourcen
:has()
Vor :has()
stand das Subjekt eines Auswählten immer am Ende. Das Subjekt dieses Selektors ist beispielsweise ein Listenelement: ul > li
. Pseudo-Auswahlen können die Auswahl ändern, aber nicht das Subjekt: ul > li:hover
oder ul >
li:not(.selected)
.
Nach :has()
kann ein übergeordnetes Element im Elementbaum das Subjekt bleiben und gleichzeitig eine Abfrage zu untergeordneten Elementen stellen: ul:has(> li)
. Es ist leicht nachvollziehbar, wie :has()
den allgemeinen Namen „Parent Selector“ erhalten hat, da das Subjekt des Selektors in diesem Fall jetzt das übergeordnete Element ist.
Hier ein einfaches Syntaxbeispiel, in dem die Klasse .parent
das Subjekt bleibt, aber nur ausgewählt wird, wenn ein untergeordnetes Element die Klasse .child
hat:
.parent:has(.child) {...}
Hier ist ein Beispiel, in dem ein <section>
-Element das Subjekt ist, die Auswahl aber nur dann erfolgt, wenn eines der untergeordneten Elemente :focus-visible
hat:
section:has(*:focus-visible) {...}
Die Auswahl :has()
wird zu einem fantastischen Tool, sobald sich praktische Anwendungsfälle zeigen. So ist es beispielsweise derzeit nicht möglich, <a>
-Tags auszuwählen, wenn sie Bilder umschließen. Das macht es schwierig, dem Anker-Tag beizubringen, wie es seine Stile in diesem Anwendungsfall ändern soll. Mit :has()
ist Folgendes möglich:
a:has(> img) {...}
Bei diesen Beispielen sieht :has()
nur wie eine übergeordnete Auswahl aus.
Angenommen, Sie möchten Bilder in <figure>
-Elementen einfügen und die Stile der Bilder anpassen, wenn die Abbildung ein <figcaption>
hat. Im folgenden Beispiel werden zuerst Abbildungen mit Bildunterschriften und dann Bilder in diesem Kontext ausgewählt. :has()
wird verwendet und ändert das Thema nicht, da es sich um Bilder handelt, nicht um Zahlen:
figure:has(figcaption) img {...}
Die Kombinationsmöglichkeiten sind schier endlos. Kombinieren Sie :has()
mit Anzahlabfragen und passen Sie die CSS-Rasterlayouts an die Anzahl der untergeordneten Elemente an. Kombinieren Sie :has()
mit interaktiven Pseudoklassenstatus und erstellen Sie Anwendungen, die auf neue, kreative Weise reagieren.
Mit @supports
und der Funktion selector()
lässt sich ganz einfach prüfen, ob der Browser die Syntax versteht, bevor sie verwendet wird:
@supports (selector(:has(works))) {
/* safe to use :has() */
}
Ressourcen
- :has()-Spezifikation
- :has() auf MDN
- Der CSS-Selektor
:has()
ist viel mehr als ein „übergeordneter Selektor“
2022 und darüber hinaus
Es gibt immer noch einige Dinge, die nach der Einführung dieser tollen Funktionen im Jahr 2022 nur schwer zu realisieren sein werden. Im nächsten Abschnitt werden einige der verbleibenden Probleme und die Lösungen beschrieben, die derzeit entwickelt werden, um sie zu beheben. Diese Lösungen sind experimentell, auch wenn sie in Browsern möglicherweise angegeben oder hinter Flags verfügbar sind.
Die Schlussfolgerung aus den nächsten Abschnitten sollte sein, dass es für die aufgeführten Probleme viele Personen aus vielen Unternehmen gibt, die eine Lösung suchen – nicht, dass diese Lösungen 2023 veröffentlicht werden.
Benutzerdefinierte Eigenschaften mit loser Typisierung
Benutzerdefinierte CSS-Eigenschaften sind unglaublich. Sie ermöglichen es, verschiedenste Dinge in einer benannten Variablen zu speichern, die dann erweitert, berechnet, gemeinsam genutzt und mehr. Sie sind sogar so flexibel, dass es schön wäre, wenn es auch weniger flexible Optionen gäbe.
Angenommen, ein box-shadow
verwendet benutzerdefinierte Properties für seine Werte:
box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);
Das funktioniert gut, bis eine der Eigenschaften in einen Wert geändert wird, der in CSS nicht zulässig ist, z. B. --x: red
. Der gesamte Schatten wird unterbrochen, wenn eine der verschachtelten Variablen fehlt oder auf einen ungültigen Werttyp festgelegt ist.
Hier kommt @property
ins Spiel: --x
kann ein typisiertes benutzerdefiniertes Attribut werden, das nicht mehr locker und flexibel, aber sicher mit einigen definierten Grenzen wird:
@property --x {
syntax: '<length>';
initial-value: 0px;
inherits: false;
}
Wenn in box-shadow
var(--x)
verwendet wird und später --x: red
versucht wird, wird red
ignoriert, da es sich nicht um ein <length>
handelt. Das bedeutet, dass der Schatten weiterhin funktioniert, auch wenn einer seiner benutzerdefinierten Properties ein ungültiger Wert zugewiesen wurde.
Statt eines Fehlers wird der initial-value
-Wert 0px
wiederhergestellt.
Animation
Neben der Typsicherheit eröffnet es auch viele Möglichkeiten für Animationen. Die Flexibilität der CSS-Syntax macht Animationen unmöglich, zum Beispiel Gradienten. @property
hilft hier, da die typisierte CSS-Eigenschaft den Browser über die Absicht eines Entwicklers in einer ansonsten übermäßig komplexen Interpolation informieren kann. Es schränkt im Wesentlichen die Möglichkeiten ein, insofern ein Browser Aspekte eines Stils animieren kann, die vorher nicht möglich waren.
In diesem Demobeispiel wird ein radialer Farbverlauf verwendet, um einen Teil eines Overlays zu erstellen und so einen Scheinwerfereffekt zu erzielen. JavaScript setzt die X- und Y-Position der Maus, wenn die Alt-/Opt-Taste gedrückt wird, und ändert dann die Brennweite in einen kleineren Wert wie 25 %. Dadurch wird der Kreis für den Spotfokus an der Mausposition erstellt:
.focus-effect {
--focal-size: 100%;
--mouse-x: center;
--mouse-y: center;
mask-image: radial-gradient(
circle at var(--mouse-x) var(--mouse-y),
transparent 0%,
transparent var(--focal-size),
black 0%
);
}
Sie können jedoch nicht animiert werden. Sie sind zu flexibel und zu komplex, sodass der Browser
nicht nur die Animation ableiten kann. Mit @property
kann jedoch eine Property einzeln eingegeben und animiert werden, deren Absicht der Browser leicht verstehen kann.
Bei Videospielen, in denen dieser Fokuseffekt verwendet wird, wird der Kreis immer animiert, von einem großen Kreis zu einem Lochkameraeffekt. So verwenden Sie @property
in unserer Demo, damit der Browser die Farbverlaufsmaske animiert:
@property --focal-size {
syntax: '<length-percentage>';
initial-value: 100%;
inherits: false;
}
.focus-effect {
--focal-size: 100%;
--mouse-x: center;
--mouse-y: center;
mask-image: radial-gradient(
circle at var(--mouse-x) var(--mouse-y),
transparent 0%,
transparent var(--focal-size),
black 0%
);
transition: --focal-size .3s ease;
}
Der Browser kann jetzt die Größe des Farbverlaufs animieren, da wir die Oberfläche der Änderung auf nur eine Eigenschaft reduziert und den Wert eingegeben haben, damit der Browser die Längen intelligent interpolieren kann.
@property
kann noch viel mehr, aber mit diesen kleinen Entwicklungen können Sie viel erreichen.
Ressourcen
- @property specification
- @property auf MDN
- @property auf web.dev
- Demo für den Zoom-Fokus
- CSS-Tricks: @property und seine Animationsmöglichkeiten entdecken
War in min-width
oder max-width
Vor den Bereichen einer Medienabfrage werden in einer CSS-Medienabfrage min-width
und max-width
verwendet, um Bedingungen für „über“ und „unter“ anzugeben. Dies kann so aussehen:
@media (min-width: 320px) {
…
}
Nach den Bereichen der Medienabfrage könnte dieselbe Medienabfrage so aussehen:
@media (width >= 320px) {
…
}
Eine CSS-Medienabfrage, die sowohl min-width
als auch max-width
verwendet, könnte so aussehen:
@media (min-width: 320px) and (max-width: 1280px) {
…
}
Nach den Bereichen der Medienabfrage könnte dieselbe Medienabfrage so aussehen:
@media (320px <= width <= 1280px) {
…
}
Je nach Ihrem Programmierhintergrund ist eine der beiden Optionen viel besser lesbar als die andere. Dank der Ergänzungen der Spezifikationen können Entwickler auswählen, welche sie bevorzugen, oder sie sogar synonym verwenden.
Ressourcen
- Syntaxspezifikation für Medienabfragebereiche
- Syntax für den Bereich von Medienabfragen in der MDN
- PostCSS-Plug-in für die Syntax von Mediaabfragebereichen
Keine Variablen für Medienabfragen
Vor @custom-media
mussten sich Medienabfragen immer wieder wiederholen oder Präprozessoren verwenden, um während der Build-Zeit die richtige Ausgabe basierend auf statischen Variablen zu generieren.
Nach @custom-media
können in CSS Aliasse für Medienabfragen erstellt und auf sie verwiesen werden, genau wie bei einer benutzerdefinierten Property.
Das Benennen von Dingen ist sehr wichtig: Sie kann den Zweck mit der Syntax in Einklang bringen, sodass Dinge einfacher geteilt und in Teams einfacher verwendet werden können. Hier sind einige benutzerdefinierte Medienabfragen, die mich zwischen Projekten begleiten:
@custom-media --OSdark (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);
@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse (hover) and (pointer: fine);
@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);
Nachdem ich sie definiert habe, kann ich eine davon so verwenden:
@media (--OSdark) {
:root {
…
}
}
Eine vollständige Liste der benutzerdefinierten Medienabfragen, die ich in meiner CSS-Bibliothek für benutzerdefinierte Properties Open Props verwende, finden Sie hier.
Ressourcen
- Spezifikation für benutzerdefinierte Medienabfragen
- PostCSS-Plug-in für benutzerdefinierte Medienabfragen
Selektoren verschachteln
Vor dem @nest
gab es viele Wiederholungen in Stylesheets. Dies wurde besonders unübersichtlich, wenn Selektoren lang waren und jeder auf kleine Unterschiede ausgerichtet war. Die einfache Verschachtelung ist einer der häufigsten Gründe für die Verwendung eines Preprozessors.
Nach @nest
Tagen ist die Wiederholung nicht mehr zu sehen. Nahezu alle Funktionen einer präprozessorfähigen Verschachtelung werden in CSS integriert sein.
article {
color: darkgray;
}
article > a {
color: var(--link-color);
}
/* with @nest becomes */
article {
color: darkgray;
& > a {
color: var(--link-color);
}
}
Das Wichtigste beim Verschachteln ist für mich, dass article
nicht in der verschachtelten Auswahl wiederholt wird und dass der Stilkontext innerhalb eines Stilblocks bleibt.
Anstatt von einem Selektor und seinen Stilen zu einem anderen Selektor mit Stilen zu wechseln (Beispiel 1), kann der Leser im Kontext eines Artikels bleiben und sehen, dass der Artikel Links enthält. Die Beziehung und der Stil werden zusammengeführt, sodass article
eigene Stile zu haben scheint.
Die Inhaberschaft kann auch als Zentralisierung betrachtet werden. Anstatt in einem Stylesheet nach relevanten Stilen zu suchen, sind sie alle in einem Kontext verschachtelt. Dies funktioniert für Beziehungen zwischen übergeordneten und untergeordneten Elementen, aber auch für Beziehungen von untergeordneten zu übergeordneten Elementen.
Angenommen, eine untergeordnete Komponente soll sich in einem anderen übergeordneten Kontext anpassen, anstatt dass das übergeordnete Element den Stil besitzt und ein untergeordnetes Element ändert:
/* parent owns this, adjusting children */
section:focus-within > article {
border: 1px solid hotpink;
}
/* with @nest becomes */
/* article owns this, adjusting itself when inside a section:focus-within */
article {
@nest section:focus-within > & {
border: 1px solid hotpink;
}
}
@nest
trägt insgesamt zu einer gesünderen Organisation, Zentralisierung und Inhaberschaft bei. Komponenten können ihre eigenen Stile gruppieren und besitzen, anstatt sie über andere Stilblöcke zu verteilen. In diesen Beispielen mag es unbedeutend erscheinen, aber es kann sehr große Auswirkungen haben, sowohl in Bezug auf die Nutzerfreundlichkeit als auch die Lesbarkeit.
Ressourcen
Stil für den Geltungsbereich festlegen
Vor @scope
gab es viele Strategien, da Stile in CSS kaskadieren, vererbt werden und standardmäßig global gelten. Diese CSS-Funktionen sind in vielerlei Hinsicht sehr praktisch. Bei komplexen Websites und Anwendungen mit potenziell vielen verschiedenen Komponentenstilen können der globale Platz und die Art der Kaskade jedoch dazu führen, dass Stile den Eindruck erweckt werden, sie würden auslaufen.
Nach @scope
können Stile nicht nur auf einen Kontext wie eine Klasse beschränkt werden, sondern auch angeben, wo die Stile enden und nicht weiter kaskadiert oder übernommen werden.
Im folgenden Beispiel kann die Benennung nach der BEM-Nomenklatur in die tatsächliche Absicht umgewandelt werden. Die BEM-Auswahl versucht, die Farbe eines header
-Elements auf einen .card
-Container mit Benennungskonventionen anzuwenden. Dazu muss die Kopfzeile diese Klassenbezeichnung enthalten. Bei @scope
sind keine Namenskonventionen erforderlich, um dasselbe Ziel zu erreichen, ohne das Header-Element zu markieren:
.card__header {
color: var(--text);
}
/* with @scope becomes */
@scope (.card) {
header {
color: var(--text);
}
}
Hier ist ein weiteres Beispiel, das weniger komponentenspezifisch ist und mehr auf den globalen Gültigkeitsbereich von CSS eingeht. Dunkle und helle Designs müssen in einem Stylesheet nebeneinander existieren. Die Reihenfolge ist dabei entscheidend für den Erfolg eines Stils. Normalerweise bedeutet das, dass dunkle Designvarianten nach dem hellen Design kommen. Das helle Design ist dann der Standardstil und das dunkle der optionale Stil. Mit @scope
können Sie Probleme mit Sortierung und Umfang vermeiden:
@scope (.light-theme) {
a { color: purple; }
}
@scope (.dark-theme) {
a { color: plum; }
}
Zur Vervollständigung: Mit @scope
können Sie auch festlegen, wo der Stilbereich endet. Das ist mit keiner Benennungskonvention oder keinem Preprozessor möglich. Es ist etwas Besonderes und kann nur mit im Browser integriertem CSS erfolgen. Im folgenden Beispiel werden die Stile img
und .content
ausschließlich angewendet, wenn ein Kind eines .media-block
ein Geschwister- oder übergeordnetes Element von .content
ist:
@scope (.media-block) to (.content) {
img {
border-radius: 50%;
}
.content {
padding: 1em;
}
}
Ressourcen
Maurerlayouts sind nicht mit CSS möglich
Vor CSS-Mauerwerk mit Raster war JavaScript die beste Möglichkeit, ein Mauerwerk-Layout zu erstellen, da alle CSS-Methoden mit Spalten oder Flexbox die Inhaltsreihenfolge nicht korrekt darstellen würden.
Nach der CSS-Mauerwerksanordnung mit Raster sind keine JavaScript-Bibliotheken erforderlich und die Inhaltsreihenfolge ist korrekt.
Die vorherige Demo wird mit dem folgenden CSS erzielt:
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
Es ist beruhigend zu wissen, dass diese Funktion als fehlende Layoutstrategie auf dem Radar ist. Außerdem können Sie sie schon heute in Firefox ausprobieren.
Ressourcen
- Masonry-Layoutspezifikation
- Masonry-Layout auf der MDN
- Smashing Magazine: Natives CSS-Mauerwerk-Layout mit CSS-Grid
Preisvergleichsportal kann Nutzern nicht helfen, Daten zu reduzieren
Vor der prefers-reduced-data
-Medienabfrage konnten JavaScript und ein Server ihr Verhalten basierend auf der „Datensparmodus“-Option des Betriebssystems oder Browsers eines Nutzers ändern, CSS jedoch nicht.
Nach der prefers-reduced-data
-Medienabfrage kann CSS dazu beitragen, die Nutzerfreundlichkeit zu verbessern und Daten zu sparen.
@media (prefers-reduced-data: reduce) {
picture, video {
display: none;
}
}
Der vorherige CSS-Code wird in dieser Komponente zum Scrollen von Medien verwendet. Die Einsparungen können enorm sein. Je nachdem, wie groß der Darstellungsbereich des Besuchers ist, sind beim Seitenaufbau mehr Einsparungen möglich. Das Speichern wird fortgesetzt, während Nutzer mit den Medien-Scrollern interagieren. Die Bilder haben alle loading="lazy"
-Attribute. In Kombination mit dem CSS-Code, der das Element vollständig ausblendet, wird nie eine Netzwerkanfrage für das Bild gesendet.
Für meine Tests wurden in einem mittelgroßen Darstellungsbereich 40 Anfragen und 700 KB an Ressourcen anfänglich geladen. Wenn ein Nutzer durch die Medienauswahl scrollt, werden mehr Anfragen und Ressourcen geladen. Mit CSS und der reduzierten Datenabfrage für Medien werden 10 Anfragen und 172 KB an Ressourcen geladen. Das entspricht einer Einsparung von einem halben Megabyte. Der Nutzer hat noch nicht einmal durch die Medien gescrollt, sodass keine zusätzlichen Anfragen gestellt werden.
Diese reduzierte Datennutzung bietet nicht nur Einsparungen bei den Daten, sondern auch weitere Vorteile. Es sind mehr Titel zu sehen und es gibt keine ablenkenden Coverbilder, die die Aufmerksamkeit ablenken. Viele Nutzer nutzen einen Datensparmodus, weil sie pro Megabyte Daten bezahlen. Es ist wirklich schön, dass CSS hier helfen kann.
Ressourcen
- prefers-reduced-data specification
- prefers-reduced-data auf MDN
- prefers-reduced-data in einer Benutzeroberfläche Herausforderung
- Smashing Magazine: Improving Core Web Vitals, A Smashing Magazine Case Study
Die Funktionen für das Scrollen zu Elementen sind zu eingeschränkt
Vor diesen Vorschlägen für Scroll-Snaps konnte es schnell kompliziert werden, eigenes JavaScript zu schreiben, um ein Karussell, einen Schieberegler oder eine Galerie zu verwalten, da alle Beobachter und die Zustandsverwaltung berücksichtigt werden mussten. Außerdem besteht die Gefahr, dass die natürlichen Scrollgeschwindigkeiten durch ein Script normalisiert werden, was die Nutzerinteraktion etwas unnatürlich und möglicherweise klobig erscheinen lässt.
Neue APIs
snapChanging()
Sobald der Browser ein untergeordnetes Snap-Element freigegeben hat, wird dieses Ereignis ausgelöst. Auf diese Weise kann die Benutzeroberfläche das Fehlen eines untergeordneten Andockens und den unbestimmten Andockstatus des Scrollers widerspiegeln, da er jetzt verwendet wird und an einer neuen Stelle landet.
document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()
Sobald der Browser zu einem neuen untergeordneten Element gewechselt ist und der Scroller nicht mehr bewegt wird, wird dieses Ereignis ausgelöst. So können alle UIs, die vom angedockten untergeordneten Element abhängen, aktualisiert und die Verbindung widergespiegelt werden.
document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
console.log('Snap changed', event.snappedTargetsList);
});
scroll-start
Scrollen beginnt nicht immer von vorn. Beispiele sind wischbare Komponenten, bei denen Wischen nach links oder rechts verschiedene Ereignisse auslöst, oder eine Suchleiste, die beim Laden der Seite zunächst ausgeblendet ist, bis Sie nach oben scrollen. Mit dieser CSS-Property können Entwickler angeben, dass ein Scroller an einem bestimmten Punkt beginnen soll.
:root { --nav-height: 100px }
.snap-scroll-y {
scroll-start-y: var(--nav-height);
}
:snap-target
Dieser CSS-Selektor gleicht Elemente in einem Scroll-Snap-Container ab, die aktuell vom Browser ausgerichtet werden.
.card {
--shadow-distance: 5px;
box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
transition: box-shadow 350ms ease;
}
.card:snapped {
--shadow-distance: 30px;
}
Nach diesen Vorschlägen für Scroll-Snaps ist es viel einfacher, einen Schieberegler, ein Karussell oder eine Galerie zu erstellen, da der Browser jetzt praktische Funktionen für diese Aufgabe bietet. Beobachter und Scroll-Orchestrierungscode werden durch integrierte APIs ersetzt.
Diese CSS- und JS-Funktionen befinden sich noch in der Anfangsphase. Wir werden aber bald polyfills sehen, die die Einführung und das Testen dieser Funktionen erleichtern.
Ressourcen
Zwischen bekannten Status wechseln
Vor toggle()
konnten nur bereits im Browser integrierte Status für Styling und Interaktion verwendet werden. Das Kästchen hat beispielsweise :checked
, einen intern verwalteten Browserstatus für die Eingabe, der mit CSS verwendet werden kann, um das Element optisch zu ändern.
Nach toggle()
können benutzerdefinierte Status für jedes Element erstellt werden, das CSS ändern und für das Styling verwenden kann. Sie können damit unter anderem Gruppen erstellen, zwischen mehreren Ansichten wechseln und die Ansichten gezielt umschalten.
Im folgenden Beispiel wird der gleiche Effekt eines durchgestrichenen Listenelements auf die Vollständigkeit erzielt, jedoch ohne Kästchenelemente:
<ul class='ingredients'>
<li>1 banana
<li>1 cup blueberries
...
</ul>
Und die relevanten CSS-toggle()
-Stile:
li {
toggle-root: check self;
}
li:toggle(check) {
text-decoration: line-through;
}
Wenn Sie mit Zustandsmaschinen vertraut sind, werden Sie feststellen, wie viele Überschneidungen es mit toggle()
gibt. Mit dieser Funktion können Entwickler einen größeren Teil ihres Zustands in CSS integrieren, was hoffentlich zu klareren und semantischen Möglichkeiten zur Orchestrierung der Interaktion und des Zustands führt.
Ressourcen
Ausgewählte Elemente anpassen
Vor <selectmenu>
konnten <option>
-Elemente mit Rich-HTML nicht mit CSS angepasst oder die Darstellung einer Optionsliste nicht wesentlich geändert werden.
Dies veranlasste die Entwickler, externe Bibliotheken zu laden, die einen Großteil der Funktionalität eines <select>
nachbilden, was am Ende viel Arbeit bedeutete.
Nach <selectmenu>
können Entwickler Rich-HTML-Code für Optionselemente zur Verfügung stellen und diese nach Bedarf gestalten. Dabei werden die Anforderungen an die Barrierefreiheit erfüllt und semantische HTML-Inhalte bereitgestellt.
Im folgenden Beispiel, das von der <selectmenu>
Erläuterungsseite stammt, wird ein neues Auswahlmenü mit einigen grundlegenden Optionen erstellt:
<selectmenu>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</selectmenu>
Mit CSS können Sie die Teile des Elements ansteuern und stylen:
.my-select-menu::part(button) {
color: white;
background-color: red;
padding: 5px;
border-radius: 5px;
}
.my-select-menu::part(listbox) {
padding: 10px;
margin-top: 5px;
border: 1px solid red;
border-radius: 5px;
}
Sie können das Element <selectmenu>
in Chromium in Canary ausprobieren, wenn das Flag für Webtests aktiviert ist. Ab 2023 werden ausgewählte Menüelemente anpassbar sein.
Ressourcen
Elemente aneinander ankern
Vor anchor()
wurden die absoluten und relativen Positionen als Positionsstrategien für Entwickler bereitgestellt, damit sich untergeordnete Elemente innerhalb eines übergeordneten Elements bewegen können.
Nach dem anchor()
können Entwickler Elemente an anderen Elementen platzieren, unabhängig davon, ob sie untergeordnete Elemente sind oder nicht. Außerdem können Entwickler angeben, an welcher Kante das Element positioniert werden soll, und andere nützliche Funktionen zum Erstellen von Positionierungsbeziehungen zwischen Elementen nutzen.
Wenn Sie mehr erfahren möchten, finden Sie in der Erklärung einige gute Beispiele und Codebeispiele.