Das Preisvergleichsportal 2022

Web-Styling-Funktionen von heute und morgen, wie auf der Google I/O 2022 vorgestellt, sowie einige Extras.

2022 wird ein großartiges Jahr für CSS, sowohl in Bezug auf Funktionen als auch auf die gemeinsame Veröffentlichung von Browserfunktionen. Das gemeinsame Ziel ist die Implementierung von 14 Funktionen.

Übersicht

Dieser Beitrag ist die Artikelversion des Vortrags, der auf der Google I/O 2022 gehalten wurde. Es ist nicht als detaillierter Leitfaden für jede Funktion gedacht, sondern als Einführung und kurzer Überblick, um Ihr Interesse zu wecken. Es bietet also eher Breite als Tiefe. Wenn Sie mehr erfahren möchten, finden Sie am Ende eines Abschnitts Links zu weiteren Informationen.

Inhaltsverzeichnis

Über die Liste unten können Sie zu Themen springen, die Sie interessieren:

Browserkompatibilität

Ein Hauptgrund dafür, dass so viele Preisvergleichsportal-Funktionen gemeinsam veröffentlicht werden, sind die Bemühungen von Interop 2022. Bevor wir uns die Interop-Bemühungen ansehen, ist es wichtig, sich die Bemühungen von Compat 2021 anzusehen.

Compat 2021

Die Ziele für 2021, die auf Entwicklerfeedback aus Umfragen basieren, waren, aktuelle Funktionen zu stabilisieren, die Testsuite zu verbessern und die Bestehensquoten von Browsern für fünf Funktionen zu erhöhen:

  1. sticky-Positionierung
  2. aspect-ratio Größe
  3. Layout: flex
  4. Layout: grid
  5. transform-Positionierung und ‑Animation

Die Testergebnisse wurden insgesamt verbessert, was auf eine höhere Stabilität und Zuverlässigkeit hinweist. Herzlichen Glückwunsch an die Teams!

Interop 2022

In diesem Jahr haben sich Browseranbieter getroffen, um die Funktionen und Prioritäten zu besprechen, an denen sie arbeiten möchten, und ihre Bemühungen zu vereinen. Folgende Webfunktionen für Entwickler waren geplant:

  1. @layer
  2. Farbräume und Funktionen
  3. Eindämmung
  4. <dialog>
  5. Formular-Kompatibilität
  6. Scrollen
  7. Unterraster
  8. Typografie
  9. Einheiten für den Darstellungsbereich
  10. Webkompatibilität

Das ist eine spannende und ehrgeizige Liste, auf deren Umsetzung ich schon gespannt bin.

Neu im Jahr 2022

Es überrascht nicht, dass der Zustand von CSS 2022 stark von der Arbeit an Interop 2022 beeinflusst wird.

Kaskadenebenen

Browser Support

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97.
  • Safari: 15.4.

Source

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 Styles zuerst und wichtigere Styles später laden mussten. Es gibt ganze Methoden, die Entwicklern helfen, diese Wichtigkeit zu verwalten, z. B. ITCSS.

Mit @layer können in der Einstiegsdatei Ebenen und ihre Reihenfolge vorab definiert werden. Wenn Stile geladen oder definiert werden, können sie in einer Ebene platziert werden. So bleibt die Wichtigkeit von Stilüberschreibungen erhalten, ohne dass das Laden sorgfältig orchestriert werden muss.

Das Video zeigt, wie die definierten Kaskadenebenen einen freieren und flexibleren Erstellungs- und Ladeprozess ermöglichen, während die Kaskade bei Bedarf beibehalten wird.

Mit den Chrome-Entwicklertools lässt sich gut visualisieren, welche Stile aus welchen Ebenen stammen:

Screenshot der Seitenleiste „Styles“ der Chrome-Entwicklertools, in der zu sehen ist, wie Stile in neuen Ebenengruppen angezeigt werden.

Ressourcen

Unterraster

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 71.
  • Safari: 16.

Source

Vor subgrid konnte ein Raster innerhalb eines anderen Rasters nicht an den übergeordneten Zellen oder Rasterlinien ausgerichtet werden. Jedes Rasterlayout war einzigartig. Viele Designer legen ein einzelnes Raster über ihr gesamtes Design und richten Elemente darin aus. Das ist in CSS nicht möglich.

Nach subgrid kann ein untergeordnetes Element eines Grids die Spalten oder Zeilen des übergeordneten Elements übernehmen und sich selbst oder untergeordnete Elemente daran ausrichten.

Im folgenden Beispiel wird mit dem body-Element ein klassisches Raster mit drei Spalten erstellt: Die mittlere Spalte heißt main und die linke und rechte Spalte benennen ihre Zeilen fullbleed. Anschließend werden die benannten Zeilen aus dem Textkörper auf jedes Element im Textkörper, <nav> und <main>, angewendet, 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;
}

Schließlich können Kinder von <nav> oder <main> sich mithilfe der Spalten und Zeilen fullbleed und main ausrichten oder ihre Größe anpassen.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

Mit den Entwicklertools können Sie die Linien und Unterraster sehen (derzeit nur in Firefox). Im folgenden Bild wurden das übergeordnete Raster und die untergeordneten Raster übereinandergelegt. Es ähnelt nun der Art und Weise, wie Designer über das Layout nachgedacht haben.

Screenshot einer Subgrid-Demo, in der die Chrome-Entwicklertools zum Überlagern von Rastern verwendet werden, um die durch CSS definierten Linien zu zeigen.

Im Elementbereich der Entwicklertools können Sie sehen, welche Elemente Raster und Unterraster sind. Das ist sehr hilfreich beim Debuggen oder Validieren des Layouts.

Screenshot des Bereichs „Elements“ in den Chrome-Entwicklertools, in dem Elemente mit Raster- oder Unterrasterlayouts gekennzeichnet sind.
Screenshot aus den Firefox-Entwicklertools

Ressourcen

Containerabfragen

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

Vor @container konnten Elemente einer Webseite nur auf die Größe des gesamten Darstellungsbereichs reagieren. Das ist ideal für Makro-Layouts. Bei Mikro-Layouts, bei denen der äußere Container nicht den gesamten Viewport umfasst, kann das Layout jedoch nicht entsprechend angepasst werden.

Nach @container können Elemente auf die Größe oder den Stil eines übergeordneten Containers reagieren. Die einzige Einschränkung besteht darin, dass die Container sich als mögliche Abfrageziele deklarieren müssen. Das ist jedoch eine kleine Anforderung für einen großen Vorteil.

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

Diese Formatierungen ermöglichen es, die Spalten „Mo“, „Di“, „Mi“, „Do“ und „Fr“ im folgenden Video anhand der Ereigniselemente abzufragen.

Demo von Una Kravets

Hier ist das CSS zum Abfragen der Größe des calendar-day-Containers und zum Anpassen eines Layouts und von Schriftgrößen:

@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 an den verfügbaren Platz in der Spalte an, in die sie gezogen wird:

Demo von Max Böck

Una hat die Situation richtig als die neue Reaktionsfähigkeit eingeschätzt. Bei der Verwendung von @container gibt es viele spannende und wichtige Designentscheidungen zu treffen.

Ressourcen

accent-color

Browser Support

  • Chrome: 93.
  • Edge: 93.
  • Firefox: 92.
  • Safari: 15.4.

Source

Vor accent-color mussten Sie, wenn Sie ein Formular mit markenkonformen Farben erstellen wollten, komplexe Bibliotheken oder CSS-Lösungen verwenden, die mit der Zeit schwer zu verwalten waren. Sie haben zwar alle Optionen erhalten und hoffentlich auch die Barrierefreiheit berücksichtigt, aber die Entscheidung, ob Sie die integrierten Komponenten verwenden oder eigene erstellen, wird mit der Zeit mühsam.

Nach accent-color wird mit einer Zeile CSS eine Markenfarbe in die integrierten Komponenten eingefügt. Neben einer Tönung wählt der Browser auf intelligente Weise passende Kontrastfarben für untergeordnete Teile der Komponente aus und passt sich an die Farbschemata des Systems (hell oder dunkel) an.

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

Helle und dunkle akzentuierte HTML-Elemente nebeneinander zum Vergleich.

Weitere Informationen zu accent-color finden Sie in meinem Beitrag auf web.dev, in dem ich viele weitere Aspekte dieser nützlichen CSS-Eigenschaft untersuche.

Ressourcen

Farbe 4 und 5

Das Web wurde in den letzten Jahrzehnten von sRGB dominiert. In einer sich ausweitenden digitalen Welt mit hochauflösenden Displays und Mobilgeräten, die mit OLED- oder QLED-Bildschirmen ausgestattet sind, reicht sRGB jedoch nicht mehr aus. Außerdem werden dynamische Seiten erwartet, die sich an die Nutzerpräferenzen anpassen. Das Farbmanagement ist für Designer, Designsysteme und Code-Maintainer immer wichtiger geworden.

2022 wurden in CSS eine Reihe neuer Farbfunktionen und ‑räume eingeführt: - Farben, die die HD-Farbfunktionen von Displays nutzen. – Farbräume, die einem Zweck entsprechen, z. B. die wahrnehmungsbezogene Einheitlichkeit. – Farbräume für Verläufe, die die Interpolationsergebnisse drastisch verändern. – Farbfunktionen, mit denen Sie Farben mischen und kontrastieren und auswählen können, in welchem Bereich Sie die Arbeit ausführen.

Vor der Einführung dieser Farbfunktionen mussten in Designsystemen geeignete Kontrastfarben vorab berechnet und für ausreichend lebendige Paletten gesorgt werden. Die Vorverarbeitung oder JavaScript erledigten dabei die Hauptarbeit.

Nachdem alle diese Farbfunktionen definiert wurden, können der Browser und CSS die gesamte Arbeit dynamisch und just-in-time erledigen. Anstatt viele Kilobyte an CSS und JavaScript an Nutzer zu senden, um die Farbgebung und Datenvisualisierung zu ermöglichen, kann CSS die Orchestrierung und Berechnungen übernehmen. Außerdem kann CSS besser prüfen, ob eine Funktion unterstützt wird, bevor sie verwendet wird, oder Fallbacks elegant 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()

Browser Support

  • Chrome: 101.
  • Edge: 101.
  • Firefox: 96.
  • Safari: 15.

Source

HWB steht für Farbton, Weißanteil und Schwarzanteil. Sie ist eine benutzerfreundliche Methode, um Farben zu beschreiben, da sie nur aus einem Farbton und einer Menge Weiß oder Schwarz besteht, um die Farbe aufzuhellen oder abzudunkeln. Künstler, die Farben mit Weiß oder Schwarz mischen, werden diese Ergänzung der Farbsyntax zu schätzen wissen.

Bei Verwendung dieser Farbfunktion werden Farben aus dem sRGB-Farbraum verwendet, genau wie bei HSL und RGB. 2022 gibt es keine neuen Farben, aber für Fans der Syntax und des mentalen Modells werden einige Aufgaben einfacher.

Ressourcen

Farbräume

Die Darstellung von Farben erfolgt über einen Farbraum. Jeder Farbraum bietet verschiedene Funktionen und Kompromisse für die Arbeit mit Farben. Einige packen möglicherweise alle hellen Farben zusammen, andere ordnen sie zuerst nach Helligkeit an.

2022 sollen im CSS 10 neue Farbräume eingeführt werden, die jeweils einzigartige Funktionen bieten, um Designern und Entwicklern bei der Darstellung, Auswahl und Mischung von Farben zu helfen. Bisher war sRGB die einzige Option für die Arbeit mit Farben. Mit CSS werden jedoch neue Möglichkeiten und ein neuer Standardfarbraum, LCH, eröffnet.

color-mix()

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Source

Vor color-mix() benötigten Entwickler und Designer Vorprozessoren wie Sass, um die Farben zu mischen, bevor der Browser sie sah. Bei den meisten Farbmischfunktionen konnte auch nicht angegeben werden, in welchem Farbraum die Mischung erfolgen sollte, was manchmal zu verwirrenden Ergebnissen führte.

Nach color-mix() können Entwickler und Designer Farben im Browser mischen, zusammen mit allen anderen Stilen, ohne Build-Prozesse auszuführen oder JavaScript einzubinden. Außerdem können sie angeben, in welchem Farbraum die Mischung erfolgen soll, oder den Standard-Mischfarbraum LCH verwenden.

Häufig wird eine Markenfarbe als Grundlage verwendet und daraus werden Varianten erstellt, z. B. hellere oder dunklere Farben für Hover-Stile. So sieht das mit color-mix() 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 den Code so:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

Im Folgenden sehen Sie eine Demo zum Theming mit color-mix(). Ändern Sie die Markenfarbe und sehen Sie zu, wie sich das Design aktualisiert:

2022 können Sie in Ihren Stylesheets Farben in verschiedenen Farbräumen mischen.

Ressourcen

color-contrast()

Vor color-contrast() mussten Stylesheet-Autoren im Voraus wissen, welche Farben barrierefrei sind. Häufig wird in einer Palette schwarzer oder weißer Text auf einem Farbfeld angezeigt, um Nutzern des Farbsystems mitzuteilen, welche Textfarbe für einen guten Kontrast mit diesem Farbfeld erforderlich ist.

Screenshot von drei Material-Paletten mit 14 Farben und den entsprechenden weißen oder schwarzen Kontrastfarben für Text.
Beispiel aus den Material Design-Farbpaletten von 2014

Nach color-contrast() können Stylesheet-Autoren die Aufgabe vollständig an den Browser auslagern. Der Browser kann nicht nur automatisch eine schwarze oder weiße Farbe auswählen, sondern Sie können ihm auch eine Liste mit Farben geben, die für das Designsystem geeignet sind, und ihn die erste Farbe auswählen lassen, die das gewünschte Kontrastverhältnis erfüllt.

Hier ist ein Screenshot einer HWB-Farbpalettengruppe, in der die Textfarben automatisch vom Browser auf Grundlage der Musterfarbe ausgewählt werden:

Screenshot der HWB-Demo, in der jede Palette eine andere Kombination aus hellem oder dunklem Text hat, die vom Browser bestimmt wird.
Demo testen

Die Grundlagen der Syntax sehen so aus. Dabei wird „gray“ an die Funktion übergeben und der Browser ermittelt, ob Schwarz oder Weiß den größten Kontrast bietet:

color: color-contrast(gray);

Die Funktion kann auch mit einer Liste von Farben angepasst werden, aus der die Farbe mit dem höchsten Kontrast ausgewählt wird:

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

Wenn Sie nicht die Farbe mit dem höchsten Kontrast aus der Liste auswählen möchten, können Sie ein Zielkontrastverhältnis angeben. Die erste Farbe, die dieses Verhältnis erreicht, wird dann ausgewählt:

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 für mehr als nur die Textfarbe verwendet werden, aber ich schätze, dass das der primäre Anwendungsfall sein wird. Stellen Sie sich vor, wie viel einfacher es sein wird, barrierefreie und gut lesbare Oberflächen zu erstellen, wenn die Auswahl geeigneter Kontrastfarben in die CSS-Sprache selbst integriert ist.

Ressourcen

Syntax für relative Farben

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 15.

Source

Vor der relativen Farbsyntax mussten die Farbkanäle einzeln in benutzerdefinierte Eigenschaften eingefügt werden, um Berechnungen an Farben vorzunehmen und Anpassungen vorzunehmen. Diese Einschränkung machte HSL auch zur primären Farbfunktion für die Bearbeitung von Farben, da Farbton, Sättigung oder Helligkeit alle auf einfache Weise mit calc() angepasst werden konnten.

Nach der relativen Farbsyntax kann jede Farbe in jedem Farbraum in einer einzigen CSS-Zeile zerlegt, geändert und als Farbe zurückgegeben werden. Keine Einschränkungen mehr für HSL: Manipulationen können in jedem gewünschten Farbraum vorgenommen werden. Außerdem müssen dafür viel weniger benutzerdefinierte Eigenschaften erstellt werden.

Im folgenden Syntaxbeispiel wird ein Basis-Hexadezimalwert angegeben und zwei neue Farben werden relativ dazu erstellt. Die erste Farbe --absolute-change erstellt eine neue Farbe in LCH aus der Grundfarbe und ersetzt dann die Helligkeit der Grundfarbe durch 75%, wobei die Chroma (c) und der Farbton (h) beibehalten werden. Die zweite Farbe --relative-change erstellt eine neue Farbe in LCH aus der Grundfarbe, reduziert aber diesmal die Chroma (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 ist wie beim Mischen von Farben, aber eher wie bei Änderungen als beim Mischen. Sie können eine Farbe aus einer anderen Farbe ableiten und so auf die drei Channel-Werte zugreifen, die von der verwendeten Farbfunktion benannt werden. Außerdem haben Sie die Möglichkeit, diese Channels anzupassen. Insgesamt ist das eine sehr coole und leistungsstarke Syntax für Farben.

In der folgenden Demo habe ich die relative Farbsyntax verwendet, um hellere und dunklere Varianten einer Grundfarbe zu erstellen, und color-contrast() verwendet, um sicherzustellen, dass die Labels einen angemessenen Kontrast haben:

Screenshot mit drei Spalten, die jeweils dunkler oder heller als die mittlere Spalte sind.
Demo testen

Diese Funktion kann auch zum Generieren von Farbpaletten verwendet werden. Hier sehen Sie eine Demo, in der ganze Paletten auf Grundlage einer bereitgestellten Grundfarbe generiert werden. Dieses eine CSS-Set ist für alle verschiedenen Paletten zuständig. Jede Palette bietet lediglich eine andere Grundlage. Da ich LCH verwendet habe, sind die Paletten sehr gleichmäßig. Dank dieses Farbraums gibt es keine Hotspots oder Deadspots.

: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);
}
Screenshot von 15 Paletten, die alle dynamisch mit CSS generiert wurden.
Demo testen

Hoffentlich können Sie jetzt nachvollziehen, wie Farbräume und verschiedene Farbfunktionen je nach ihren Stärken und Schwächen für unterschiedliche Zwecke verwendet werden können.

Ressourcen

Farbverläufe

Vor der Einführung von Verlaufsfarbräumen war sRGB der standardmäßig verwendete Farbraum. sRGB ist im Allgemeinen zuverlässig, hat aber einige Schwächen, z. B. die graue Totzone.

Vier Farbverläufe in einem Raster, alle von Cyan bis Tiefrosa. LCH und LAB haben eine konsistentere Lebendigkeit, während sRGB in der Mitte etwas entsättigt ist.

Geben Sie nach den Farbverlaufsfarbräumen 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 in LCH anstelle von sRGB geändert.

Die zusätzliche Syntax wird nach der Richtung des Verlaufs eingefügt, 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 zu Weiß. Sehen Sie sich den Bereich der Ergebnisse in den einzelnen Farbräumen an. Bei einigen wird Schwarz früher erreicht als bei anderen, bei einigen wird zu spät zu Weiß übergegangen.

11 Farbräume im Vergleich von Schwarz zu Weiß.

Im nächsten Beispiel wird Schwarz in Blau überblendet, da dies ein bekanntes Problem bei Verläufen ist. Die meisten Farbräume gehen bei der Farbinterpolation ins Violette über oder, wie ich es gerne sehe, wenn Farben in ihrem Farbraum von Punkt A nach Punkt B wandern. Da der Farbverlauf eine gerade Linie von Punkt A nach Punkt B bildet, ändert sich die Form des Farbraums drastisch, wenn der Pfad sich bewegt.

11 Farbräume, in denen Blau mit Schwarz verglichen wird.

In diesem Twitter-Thread finden Sie weitere Informationen, Beispiele und Kommentare.

Ressourcen

inert

Browser Support

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 112.
  • Safari: 15.5.

Source

Vor inert war es üblich, die Aufmerksamkeit des Nutzers auf Bereiche der Seite oder App zu lenken, die sofortige Aufmerksamkeit erforderten. Diese Strategie wurde als „Fokus-Trap“ bekannt, da Entwickler den Fokus in einen interaktiven Bereich platzierten, auf Fokusänderungsereignisse warteten und den Fokus zurück in den interaktiven Bereich zwangen, wenn er diesen verließ. Nutzer, die eine Tastatur oder einen Screenreader verwenden, werden zurück zum interaktiven Bereich geleitet, damit die Aufgabe abgeschlossen wird, bevor sie fortfahren.

Nach inert ist kein Trapping mehr erforderlich, da Sie ganze Abschnitte der Seite oder App einfrieren oder schützen können. Klicks und Versuche, den Fokus zu ändern, sind einfach nicht möglich, solange diese Teile eines Dokuments inaktiv sind. Man könnte sich das auch wie Wachen statt einer Falle vorstellen. inert möchte nicht, dass Sie an einem bestimmten Ort bleiben, sondern dass andere Orte nicht verfügbar sind.

Ein gutes Beispiel dafür ist die JavaScript-Funktion alert():

Die Website wird als interaktiv angezeigt, dann wird „alert()“ aufgerufen und die Seite ist nicht mehr aktiv.

Im vorherigen Video sehen Sie, dass die Seite bis zum Aufruf von alert() per Maus und Tastatur zugänglich war. Nachdem das Warnungsdialogfeld angezeigt wurde, wurde der Rest der Seite eingefroren oder inert. Der Fokus der Nutzer wird in das Benachrichtigungsdialogfeld verlagert und kann nicht mehr verschoben werden. Erst wenn der Nutzer mit der Benachrichtigungsfunktion interagiert und die Anfrage abgeschlossen hat, ist die Seite wieder interaktiv. inert ermöglicht Entwicklern, diese geführte Fokusfunktion ganz einfach zu implementieren.

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 für Dinge wie das Einblendmenü hilfreich. Wenn ein Nutzer das Seitenmenü einblendet, darf die Maus oder Tastatur nicht mit der Seite dahinter interagieren. Das ist für Nutzer etwas schwierig. Stattdessen wird die Seite inaktiv, wenn das Seitenmenü angezeigt wird. Nutzer müssen das Seitenmenü schließen oder darin navigieren und können sich nicht mehr auf der Seite mit einem geöffneten Menü verirren.

Ressourcen

COLRv1-Schriftarten

Vor COLRv1-Schriftarten gab es im Web OT-SVG-Schriftarten, ebenfalls ein offenes Format für Schriftarten mit Verläufen und integrierten Farben und Effekten. Diese konnten jedoch sehr groß werden und obwohl der Text bearbeitet werden konnte, gab es nicht viel Spielraum für Anpassungen.

Nach COLRv1-Schriftarten bietet das Web Schriftarten mit kleinerem Speicherbedarf, Vektorskalierbarkeit, Neupositionierung, Farbverläufen und Mischmodi, die Parameter akzeptieren, um die Schriftart für den jeweiligen Anwendungsfall anzupassen oder an eine Marke anzupassen.

Vergleichsvisualisierung und Balkendiagramm, die zeigen, dass COLRv1-Schriftarten schärfer und kleiner sind.
Bildquelle: https://developer.chrome.com/blog/colrv1-fonts/

Hier ein Beispiel aus dem Chrome-Entwicklerblogbeitrag zu Emojis: Vielleicht haben Sie schon einmal bemerkt, dass Emojis nicht scharf bleiben, wenn Sie die Schriftgröße vergrößern. Es handelt sich um ein Bild und nicht um Vektorgrafiken. Häufig wird in Anwendungen, wenn ein Emoji verwendet wird, dieses durch ein hochwertigeres Asset ersetzt. Mit COLRv1-Schriftarten sind die Emojis Vektoren und sehen toll aus:

Mit diesem Format lassen sich mit Symbolschriftarten beeindruckende Dinge anstellen, z. B. benutzerdefinierte Duoton-Farbpaletten. Das Laden einer COLRv1-Schriftart erfolgt wie bei jeder anderen Schriftartdatei:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

Die Anpassung der COLRv1-Schriftart erfolgt mit @font-palette-values, einer speziellen CSS-At-Rule zum Gruppieren und Benennen einer Reihe von Anpassungsoptionen in einem Bundle für den späteren Bezug. Beachten Sie, dass Sie einen benutzerdefinierten Namen wie eine benutzerdefinierte Eigenschaft angeben, beginnend 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;
}

Da --colorized ein Alias für die Anpassungen ist, müssen Sie die Palette im letzten Schritt auf ein Element anwenden, das die Schriftfamilie mit Farbunterstützung 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;
}
Screenshot der Schriftart „Bungee Spice“ mit dem Wort „DUNE“.
Die Schriftart „Bungee Spice“ mit benutzerdefinierten Farben, Quelle: https://developer.chrome.com/blog/colrv1-fonts/

Da immer mehr variable Schriftarten und Farbschriftarten verfügbar werden, ist die Webtypografie auf dem besten Weg zu umfassenden Anpassungen und kreativen Ausdrucksmöglichkeiten.

Ressourcen

Einheiten für den Darstellungsbereich

Grafik, die zeigt, wie der Gerätebildschirm, das Browserfenster und ein iFrame unterschiedliche Viewports haben.

Vor den neuen Darstellungsbereichsvarianten wurden im Web physische Einheiten verwendet, um die Anpassung von Darstellungsbereichen zu erleichtern. Es gab eine für Höhe, Breite, kleinste Größe (vmin) und längste Seite (vmax). Diese funktionierten für viele Dinge gut, aber mobile Browser brachten eine Komplexität mit sich.

Auf Mobilgeräten wird beim Laden einer Seite die Statusleiste mit der URL angezeigt. Diese Leiste nimmt einen Teil des Darstellungsbereichs ein. Nach einigen Sekunden und Interaktionen wird die Statusleiste möglicherweise ausgeblendet, um dem Nutzer einen größeren sichtbaren Bereich zu bieten. Wenn die Leiste jedoch ein- oder ausgeblendet wird, ändert sich die Höhe des Darstellungsbereichs. Alle vh-Einheiten werden dann verschoben und in der Größe angepasst, da sich ihre Zielgröße ändert. In späteren Jahren musste die vh-Einheit speziell entscheiden, welche der beiden Darstellungsbereichsgrößen verwendet werden sollte, da dies auf Mobilgeräten zu störenden Problemen mit dem visuellen Layout führte. Es wurde festgelegt, 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 mit logischen Äquivalenten zu den physischen Einheiten bereitgestellt. Die Idee ist, Entwicklern und Designern die Möglichkeit zu geben, die Einheit auszuwählen, die sie für ihr jeweiliges Szenario verwenden möchten. Vielleicht ist es in Ordnung, wenn es zu einer kleinen, störenden Layoutverschiebung kommt, wenn die Statusleiste verschwindet. Dann könnte dvh (dynamische Höhe des Darstellungsbereichs) ohne Bedenken verwendet werden.

Eine Grafik mit drei Smartphones zur Veranschaulichung von DVH, LVH und SVH. Das Beispiel-Smartphone für DVH hat zwei vertikale Linien: eine zwischen dem unteren Rand der Suchleiste und dem unteren Rand des Viewports und eine zwischen dem Bereich über der Suchleiste (unter der Systemstatusleiste) und dem unteren Rand des Viewports. So wird gezeigt, dass DVH eine dieser beiden Längen haben kann. LVH wird in der Mitte angezeigt, mit einer Zeile zwischen dem unteren Rand der Gerätestatusleiste und der Schaltfläche des Smartphone-Viewports. Das letzte Beispiel zeigt eine Linie von der Unterseite der Suchleiste des Browsers bis zur Unterseite des Viewports.

Hier finden Sie eine vollständige Liste aller neuen Optionen für Viewporteinheiten, die mit den neuen Viewportvarianten verfügbar sind:

Einheiten für die Höhe des Darstellungsbereichs
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
Breite des Darstellungsbereichs
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
Einheiten für die kleinste Seite des Darstellungsbereichs
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
Einheiten für die längste Seite des Darstellungsbereichs
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

Wir hoffen, dass Entwickler und Designer damit die Flexibilität erhalten, die sie für ihre responsiven Viewport-Designs benötigen.

Ressourcen

:has()

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

Vor :has() stand das Subjekt eines Selektors immer am Ende. Das Subjekt dieses Selektors ist beispielsweise ein Listenelement: ul > li. Pseudoselektoren können den Selektor ändern, aber nicht das Subjekt: ul > li:hover oder ul > li:not(.selected).

Nach :has() kann ein Thema, das in der Elementstruktur höher angesiedelt ist, das Thema bleiben, während eine Anfrage zu untergeordneten Elementen gestellt wird: ul:has(> li). Es ist leicht nachzuvollziehen, warum :has() den gebräuchlichen Namen „übergeordneter Selektor“ erhalten hat, da das Subjekt des Selektors in diesem Fall das übergeordnete Element ist.

Hier ist 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 übereinstimmt, wenn eines der untergeordneten Elemente :focus-visible hat:

section:has(*:focus-visible) {...}

Der Selektor :has() wird erst dann wirklich nützlich, wenn sich praktische Anwendungsfälle ergeben. Derzeit ist es beispielsweise nicht möglich, <a>-Tags auszuwählen, wenn sie Bilder umschließen. Das macht es schwierig, dem Anker-Tag beizubringen, wie es seine Formatierungen in diesem Anwendungsfall ändern soll. Mit :has() ist das jedoch möglich:

a:has(> img) {...}

In diesen Beispielen sieht :has() nur wie ein übergeordneter Selektor aus. Berücksichtigen Sie den Anwendungsfall von Bildern innerhalb von <figure>-Elementen und passen Sie die Formatierungen der Bilder an, wenn die Abbildung ein <figcaption>-Element enthält. 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 das Thema, auf das wir uns beziehen, Bilder und nicht Zahlen ist:

figure:has(figcaption) img {...}

Die Kombinationsmöglichkeiten sind schier endlos. Kombinieren Sie :has() mit Mengenabfragen und passen Sie CSS-Grid-Layouts basierend auf der Anzahl der untergeordneten Elemente an. Kombinieren Sie :has() mit interaktiven Pseudoklassen-Status und erstellen Sie Anwendungen, die auf neue kreative Weise reagieren.

Mit @supports und der zugehörigen Funktion selector() lässt sich ganz einfach prüfen, ob die Syntax unterstützt wird. Die Funktion testet, ob der Browser die Syntax versteht, bevor sie verwendet wird:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

Ressourcen

2022 und darüber hinaus

Es gibt aber auch einige Dinge, die nach der Einführung dieser tollen Funktionen im Jahr 2022 schwierig werden. Im nächsten Abschnitt werden einige der verbleibenden Probleme und die Lösungen, die derzeit entwickelt werden, um sie zu beheben, näher betrachtet. Diese Lösungen sind experimentell, auch wenn sie in Browsern angegeben oder hinter Flags verfügbar sein können.

In den nächsten Abschnitten geht es darum, dass viele Personen aus vielen Unternehmen nach Lösungen für die aufgeführten Probleme suchen – nicht darum, dass diese Lösungen 2023 veröffentlicht werden.

Benutzerdefinierte Eigenschaften mit schwacher Typisierung

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

Benutzerdefinierte CSS-Eigenschaften sind einfach toll. Sie ermöglichen es, alle möglichen Dinge in einer benannten Variablen zu speichern, die dann erweitert, berechnet, geteilt usw. werden kann. Tatsächlich sind sie so flexibel, dass es schön wäre, wenn es auch weniger flexible gäbe.

Angenommen, für eine box-shadow werden benutzerdefinierte Attribute für die Werte verwendet:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

Das funktioniert so lange gut, bis eine der Eigenschaften in einen Wert geändert wird, der von CSS nicht akzeptiert wird, 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 zu einer typisierten benutzerdefinierten Property werden, die nicht mehr lose und flexibel, sondern sicher mit einigen definierten Grenzen ist:

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

Wenn der box-shadow var(--x) verwendet und später --x: red versucht wird, wird red ignoriert, da es sich nicht um einen <length> handelt. Das bedeutet, dass der Schatten weiterhin funktioniert, obwohl einer seiner benutzerdefinierten Eigenschaften ein ungültiger Wert zugewiesen wurde. Stattdessen wird der initial-value auf 0px zurückgesetzt.

Animation

Neben der Typsicherheit bietet es auch viele Möglichkeiten für Animationen. Die Flexibilität der CSS-Syntax macht die Animation einiger Dinge unmöglich, z. B. von Verläufen. @property hilft hier, da die typisierte CSS-Eigenschaft den Browser über die Absicht eines Entwicklers bei einer ansonsten zu komplexen Interpolation informieren kann. Dadurch wird der Umfang der Möglichkeiten im Wesentlichen so weit eingeschränkt, dass ein Browser Aspekte eines Stils animieren kann, die er zuvor nicht animieren konnte.

In diesem Beispiel wird ein radialer Farbverlauf verwendet, um einen Teil eines Overlays zu gestalten und so einen Spotlight-Fokuseffekt zu erzeugen. In JavaScript werden die Mauskoordinaten x und y festgelegt, wenn die Alt- oder Wahltaste gedrückt wird. Anschließend wird die Brennweite auf einen kleineren Wert wie 25 % geändert, wodurch der Spotlight-Fokuskreis an der Mausposition entsteht:

Demo testen
.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%
  );
}

Verläufe können jedoch nicht animiert werden. Sie sind zu flexibel und zu komplex, als dass der Browser einfach ableiten könnte, wie sie animiert werden sollen. Mit @property kann jedoch eine Property isoliert typisiert und animiert werden, sodass der Browser die Absicht leicht nachvollziehen kann.

In Videospielen, in denen dieser Fokuseffekt verwendet wird, wird der Kreis immer animiert, von einem großen Kreis zu einem winzigen Kreis. So verwenden Sie @property in unserem Beispiel, damit der Browser die Verlaufsmaske 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;
}
Demo ausprobieren

Der Browser kann die Größe des Verlaufs jetzt animieren, da wir die Oberfläche der Änderung auf nur eine Eigenschaft reduziert und den Wert so eingegeben haben, dass der Browser die Längen intelligent interpolieren kann.

@property kann noch viel mehr, aber auch diese kleinen Verbesserungen können viel bewirken.

Ressourcen

War in min-width oder max-width

Vor der Einführung von Media Query-Bereichen wurden in CSS-Media Queries min-width und max-width verwendet, um Bedingungen für „über“ und „unter“ auszudrücken. Dies kann so aussehen:

@media (min-width: 320px) {
  
}

Nach der Einführung von Media Query Ranges könnte dieselbe Media Query so aussehen:

@media (width >= 320px) {
  
}

Eine CSS-Media-Query, die sowohl min-width als auch max-width verwendet, könnte so aussehen:

@media (min-width: 320px) and (max-width: 1280px) {
  
}

Nach der Einführung von Media Query Ranges könnte dieselbe Media Query so aussehen:

@media (320px <= width <= 1280px) {
  
}

Je nach Ihren Programmierkenntnissen ist eine der beiden Varianten viel lesbarer als die andere. Dank der Ergänzungen der Spezifikation können Entwickler auswählen, welche sie bevorzugen, oder sie sogar abwechselnd verwenden.

Ressourcen

Keine Variablen für Media-Queries

Vor @custom-media mussten Media-Anfragen immer wiederholt werden oder auf Präprozessoren angewiesen sein, um den richtigen Output basierend auf statischen Variablen während der Build-Zeit zu generieren.

Nach @custom-media können Medienabfragen in CSS wie eine benutzerdefinierte Eigenschaft aliasiert und referenziert werden.

Die Benennung ist sehr wichtig, da sie den Zweck mit der Syntax in Einklang bringen kann. So lassen sich Dinge leichter teilen und in Teams verwenden. Hier sind einige benutzerdefinierte Media-Anfragen, die ich in verschiedenen Projekten verwende:

@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 sie definiert wurden, kann ich sie so verwenden:

@media (--OSdark) {
  :root {
    
  }
}

Eine vollständige Liste der benutzerdefinierten Media-Abfragen, die ich in meiner CSS-Bibliothek für benutzerdefinierte Eigenschaften Open Props verwende.

Ressourcen

Selektoren verschachteln

Vor @nest gab es viele Wiederholungen in Stylesheets. Das wurde besonders unhandlich, wenn Selektoren lang waren und jeweils auf kleine Unterschiede ausgerichtet waren. Die Möglichkeit, Elemente zu verschachteln, ist einer der häufigsten Gründe für die Verwendung eines Präprozessors.

Nach @nest ist die Wiederholung nicht mehr vorhanden. Fast alle Funktionen der Vorprozessor-Nesting werden in CSS integriert.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

Das Wichtigste an der Verschachtelung ist für mich, dass der Stilkontext in einem Stilblock bleibt und article nicht im verschachtelten Selektor wiederholt wird. Anstatt von einem Selektor und seinen Formatierungen zu einem anderen Selektor mit Formatierungen 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 zusammengefasst, sodass article den Eindruck erweckt, eigene Stile zu haben.

Die Inhaberschaft kann auch als Zentralisierung betrachtet werden. Anstatt in einem Stylesheet nach relevanten Stilen zu suchen, sind sie alle in einem Kontext verschachtelt. Das funktioniert sowohl mit Übergeordnet/Untergeordnet- als auch mit Untergeordnet/Übergeordnet-Beziehungen.

Stellen Sie sich ein untergeordnetes Element vor, das sich in einem anderen übergeordneten Kontext anpassen soll, 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 besseren Organisation, Zentralisierung und Inhaberschaft von Stilen bei. Komponenten können ihre eigenen Stile gruppieren und besitzen, anstatt sie auf andere Stilblöcke zu verteilen. In diesen Beispielen mag es klein erscheinen, aber es kann sowohl die Benutzerfreundlichkeit als auch die Lesbarkeit erheblich beeinträchtigen.

Ressourcen

Stile sind schwer zu definieren

Browser Support

  • Chrome: 118.
  • Edge: 118.
  • Firefox: behind a flag.
  • Safari: 17.4.

Source

Vor @scope gab es viele Strategien, da Stile in CSS standardmäßig kaskadieren, vererbt werden und global sind. Diese CSS-Funktionen sind für viele Dinge sehr praktisch, aber bei komplexen Websites und Anwendungen mit potenziell vielen verschiedenen Komponentenstilen kann der globale Bereich und die Art der Kaskade dazu führen, dass sich Stile so anfühlen, als würden sie „durchsickern“.

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 kaskadieren oder vererbt werden.

Im folgenden Beispiel kann die BEM-Benennungskonvention in die tatsächliche Absicht umgekehrt werden. Der BEM-Selektor versucht, die Farbe eines header-Elements auf einen .card-Container mit Namenskonventionen zu beschränken. Dazu muss der Header diese Klasse enthalten. Mit @scope sind keine Namenskonventionen erforderlich, um dasselbe Ziel zu erreichen, ohne das Header-Element zu kennzeichnen:

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

Hier ist ein weiteres Beispiel, das weniger komponentenspezifisch ist und sich mehr auf den globalen Umfang von CSS bezieht. Dunkle und helle Designs müssen in einem Stylesheet nebeneinander existieren. Die Reihenfolge ist wichtig, um den Gewinnerstil zu bestimmen. Normalerweise bedeutet das, dass die Formatierungen für das dunkle Design nach dem hellen Design stehen. Dadurch wird das helle Design als Standard und das dunkle Design als optional festgelegt. Vermeiden Sie die Sortierung und den Umfangskampf mit @scope:

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

Um die Geschichte hier zu vervollständigen, ermöglicht @scope auch die Festlegung des Endes des Stilbereichs. Das ist mit keiner Namenskonvention oder keinem Präprozessor möglich. Es ist eine spezielle Funktion, die nur in CSS im Browser verfügbar ist. Im folgenden Beispiel werden die Stile img und .content nur angewendet, wenn ein untergeordnetes Element von .media-block ein gleichgeordnetes Element oder übergeordnetes Element von .content ist:

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

Ressourcen

Keine CSS-Methode für ein Mauerwerk-Layout

Vor CSS-Mauerwerk mit Grid war JavaScript die beste Möglichkeit, ein Mauerwerk-Layout zu erstellen, da bei allen CSS-Methoden mit Spalten oder Flexbox die Inhaltsreihenfolge ungenau dargestellt wurde.

Nach der Einführung von CSS-Mauerwerk mit Grid sind keine JavaScript-Bibliotheken mehr erforderlich und die Reihenfolge der Inhalte ist korrekt.

Screenshot des Mauerwerkslayouts, auf dem Zahlen oben entlanglaufen und dann nach unten gehen.
Bild und Demo von Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

Die obige Demo wird mit dem folgenden CSS erreicht:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

Es ist beruhigend zu wissen, dass dies als fehlende Layoutstrategie auf dem Radar ist. Außerdem können Sie sie bereits heute in Firefox ausprobieren.

Ressourcen

CSS kann Nutzern nicht helfen, Daten zu reduzieren

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Source

Vor der Media-Query prefers-reduced-data konnten JavaScript und ein Server ihr Verhalten basierend auf der Option „Datensparmodus“ des Betriebssystems oder Browsers eines Nutzers ändern, CSS jedoch nicht.

Nach der Media-Anfrage prefers-reduced-data kann CSS zur Verbesserung der Nutzerfreundlichkeit beitragen und Daten sparen.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

Das oben genannte CSS wird in dieser Media-Scroll-Komponente verwendet. Die Einsparungen können enorm sein. Je größer der Darstellungsbereich ist, desto mehr lässt sich beim Seitenaufbau einsparen. Die Speicherung wird fortgesetzt, während Nutzer mit den Media-Scrollern interagieren. Die Bilder haben alle loading="lazy"-Attribute. In Kombination damit, dass das Element durch CSS vollständig ausgeblendet wird, wird nie eine Netzwerkanfrage für das Bild gestellt.

Screenshot einer Benutzeroberfläche mit einem Karussell für Serien, in dem viele Thumbnails und Titel zu sehen sind.

Bei meinen Tests wurden auf einem mittelgroßen Darstellungsbereich zuerst 40 Anfragen und 700 KB an Ressourcen geladen. Wenn ein Nutzer durch die Media-Auswahl scrollt, werden weitere Anfragen und Ressourcen geladen. Mit CSS und der Media-Query für reduzierte Daten werden 10 Anfragen und 172 KB an Ressourcen geladen. Das sind 0, 5 MB weniger Datenvolumen. Der Nutzer hat noch nicht einmal die Medien gescrollt. In diesem Fall werden keine zusätzlichen Anfragen gesendet.

Screenshot einer Karusselloberfläche für Serien ohne Thumbnails und mit vielen Titeln.

Die Nutzung von weniger Daten bietet nicht nur Vorteile in Bezug auf das Datenvolumen. Es können mehr Titel angezeigt werden und es gibt keine ablenkenden Coverbilder. Viele Nutzer verwenden einen Datensparmodus, weil sie pro Megabyte Daten bezahlen. Es ist wirklich schön zu sehen, dass CSS hier helfen kann.

Ressourcen

Die Funktionen für das Scroll-Snapping sind zu eingeschränkt.

Vor diesen Vorschlägen für das Scroll-Snapping konnte das Schreiben von eigenem JavaScript zum Verwalten eines Karussells, Sliders oder einer Galerie schnell komplex werden, da viele Beobachter und Zustandsverwaltung erforderlich waren. Außerdem kann es passieren, dass die natürlichen Scrollgeschwindigkeiten durch das Skript normalisiert werden, was die Nutzerinteraktion etwas unnatürlich und möglicherweise umständlich macht.

Neue APIs

snapChanging()

Dieses Ereignis wird ausgelöst, sobald der Browser ein untergeordnetes Snap-Element freigegeben hat. So kann die Benutzeroberfläche das Fehlen eines Snap-Child-Elements und den unbestimmten Snap-Zustand 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()

Dieses Ereignis wird ausgelöst, sobald der Browser zu einem neuen untergeordneten Element gescrollt hat und der Scroller sich im Ruhezustand befindet. So kann jede Benutzeroberfläche, die vom angedockten untergeordneten Element abhängt, aktualisiert werden, um die Verbindung widerzuspiegeln.

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

Das Scrollen beginnt nicht immer am Anfang. Verwenden Sie wischbare Komponenten, bei denen durch Wischen nach links oder rechts unterschiedliche Ereignisse ausgelöst werden, oder eine Suchleiste, die beim Laden der Seite zunächst ausgeblendet ist, bis Sie nach oben scrollen. Mit dieser CSS-Eigenschaft können Entwickler festlegen, 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 stimmt mit Elementen in einem Scroll-Snap-Container überein, die derzeit vom Browser eingerastet 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 Scroll-Snap-Vorschlägen ist es viel einfacher, einen Slider, ein Karussell oder eine Galerie zu erstellen, da der Browser jetzt Annehmlichkeiten für die Aufgabe bietet. Beobachter und Scroll-Orchestration-Code werden zugunsten der Verwendung integrierter APIs eliminiert.

Diese CSS- und JS-Funktionen befinden sich noch in der Anfangsphase. Achten Sie aber auf Polyfills, die die Einführung und das Testen dieser Funktionen bald erleichtern können.

Ressourcen

Wechseln zwischen bekannten Status

Vor toggle() konnten nur Status genutzt werden, die bereits im Browser integriert waren. Das Kontrollkästchen hat beispielsweise :checked, einen intern verwalteten Browserstatus für die Eingabe, der von CSS verwendet werden kann, um das Element visuell zu ändern.

Nach toggle() können benutzerdefinierte Status für jedes Element erstellt werden, damit CSS sie ändern und für das Styling verwenden kann. Es ermöglicht das Gruppieren, das Umschalten in eine bestimmte Richtung und vieles mehr.

Im folgenden Beispiel wird derselbe Effekt eines durchgestrichenen Listenelements bei „complete“ erzielt, aber ohne Kontrollkästchen:

<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 Zustandsautomaten vertraut sind, werden Sie feststellen, wie viele Überschneidungen es mit toggle() gibt. Mit dieser Funktion können Entwickler mehr Status in CSS einbauen, was hoffentlich zu klareren und semantischeren Möglichkeiten führt, Interaktion und Status zu orchestrieren.

Ressourcen

Ausgewählte Elemente anpassen

Vor <selectmenu> konnten <option>-Elemente in CSS nicht mit Rich-HTML angepasst werden. Außerdem war es nicht möglich, die Darstellung einer Liste von Optionen zu ändern. Daher mussten Entwickler externe Bibliotheken laden, die einen Großteil der Funktionalität eines <select> nachbildeten, was mit viel Aufwand verbunden war.

Nach <selectmenu> können Entwickler umfangreichen HTML-Code für Options-Elemente bereitstellen und sie nach Bedarf gestalten. Dabei werden weiterhin die Anforderungen an die Barrierefreiheit erfüllt und semantisches HTML bereitgestellt.

Im folgenden Beispiel, das von der <selectmenu>-Erklärungsseite 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 die einzelnen Teile des Elements angesprochen und gestaltet werden:

.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;
}

Ein elegantes Menü mit roten Akzentfarben.

Sie können das <selectmenu>-Element in Chromium in Canary mit aktiviertem Web-Experiments-Flag ausprobieren. Ab 2023 werden anpassbare select-Menüelemente verfügbar sein.

Ressourcen

Element an ein anderes Element ankeren

Vor anchor() waren „position: absolute“ und „position: relative“ Positionierungsstrategien, mit denen Entwickler untergeordnete Elemente innerhalb eines übergeordneten Elements verschieben konnten.

Mit anchor() können Entwickler Elemente relativ zu anderen Elementen positionieren, unabhängig davon, ob sie untergeordnet sind oder nicht. Außerdem können Entwickler angeben, an welcher Kante ein Element positioniert werden soll, und andere nützliche Funktionen nutzen, um Positionsbeziehungen zwischen Elementen zu erstellen.

In der Erläuterung finden Sie einige gute Beispiele und Codebeispiele, wenn Sie mehr erfahren möchten.

Ressourcen