Aufzeichnen und Wiedergeben von Website-Interaktionen für Tests

Dies ist der letzte Blog-Beitrag zum Thema Debugging für diesen Adventskalender. Für den letzten Beitrag habe ich mir etwas Besonderes aufgehoben. Vielleicht gibt es Dinge, die ihr im Frontend (oder Backend) eurer Seite immer wieder testen müsst, nachdem ihr etwas geändert habt. Sei es das Ausfüllen eines Formulars, das Klicken auf einige Elemente oder die Navigation durch die Seite. Es kann sehr mühsam sein, das immer wieder manuell zu tun. Aber wenn ihr Chrome für eure Tests verwendet, gibt es ein nettes eingebautes Tool, das ich durch eine Kollegin kennengelernt habe.

Die Rekorder Funktion in Chrome

Um zu dieser Funktion zu gelangen, haben ihr zwei Möglichkeiten. Ihr können das Panel auf ähnliche Weise öffnen, wie wir das „Rendering“ Panel geöffnet haben. Öffnen dazu die Entwicklertools, klickt auf die drei vertikalen Punkte, wählt „Weitere Tools“ und dann „Rekorder“ aus:

Screenshot, wie man die "Weitere Tools > Rekorder" Einstellungen öffnet.

Die zweite Möglichkeit ist die Verwendung des Dialogs „Befehl ausführen“, den ihr mit „Strg+ Umschalt + P“ (oder „Cmd+ Umschalt + P“ auf einem Mac) öffnen könnt. Dort sucht ihr dann nach „Rekorder“. Sobald das Panel geöffnet ist, klickt auf die blaue Schaltfläche „Neue Aufzeichnung erstellen“:

Screenshot der geöffneten Chrome Rekorder-Funktion mit dem blauen Button „Neue Aufzeichnung erstellen“.

Auf der nächsten Seite erstellt Chrome automatisch einen „Name der Aufzeichnung“ mit dem aktuellen Datum und der Uhrzeit für eure Aufzeichnung, den ihr aber mit einem aussagekräftigeren Titel überschreiben könnt:

Chrome-Recorder-Funktion mit geändertem „Name der Aufzeichnung“, bevor die Aufzeichnung gestartet wird.

Wenn ihr fertig seid, klickt auf den roten Button am Ende der Seite oder drücken Sie „Strg + E“. Dann macht irgendetwas auf der Seite. In diesem Beispiel habe ich oben rechts auf die Suche geklickt, „Adventskalender“ in das Suchfeld eingegeben und auf ENTER gedrückt. Nachdem die Seite neu geladen wurde, habe ich wieder auf den Button unten geklickt, um die Aufzeichnung zu beenden. Ihr solltet dann in etwa so etwas sehen:

Chrome Rekorder nach der Aufzeichnung.

Wenn du nach oben scrollst, findest du oben links einen Button „Code anzeigen“. Wenn ihr dort darauf klickt, können ihr die technische Datei für die Aufzeichnung in verschiedenen Formaten sehen:

Chrome Rekorder mit geöffneter Code-Ansicht.

Der interessanteste Button ist aber der blaue Button „Noch einmal wiedergeben“. Links davon können ihr zuvor noch die Wiedergabegeschwindigkeit auswählen. Wenn ihr nun auf den Button klickt, zeigt Chrome die Meldung „Chrome wird automatisierter Testsoftware gesteuert“ an. Es werden dann alle Schritte abgespielt und einzeln überprüft. Wenn alles erfolgreich war, ist die vertikale Linie für einige Sekunden grün:

Chrome Rekorder direkt nach der erneuten Wiedergabe.

Oben links in der Leiste seht ihr ein Dropdown-Menü. Hier findet ihr alle Aufzeichnungen, die ihr jemals in diesem Chrome-Profil gemacht habt. Mit den Schaltflächen daneben können ihr sie importieren, exportieren und löschen. Wenn ihr eine solche JSON-Datei exportiert und an eine andere Person senden, könnt ihr die wiederholbaren Testschritte mit anderen teilen.

Ihr könnt auch jeden Schritt ausklappen und die Einstellungen des Schritts ändern. Auf der Seite Chrome for Developer findet ihr hierzu ein kurzes Video, in dem der Rekorder etwas genauer erklärt wird.

Fazit

Wenn ihr einen Test auf einer Seite wiederholen möchtet, aber nicht jeden Klick und jeden Tastendruck manuell wiederholen wollt, ist der Chrome Rekorder ein großartiges Tool, das ihr verwenden könnt. Es hat auch eine Exportoption, die ich wahrscheinlich in einem anderen Blog-Beitrag behandeln werde. Da dieses Thema aber nicht ganz in unsere vier Themen für den Adventskalender 2024 passt, müssen ihr bis 2025 warten.

Ich konnte keine ähnliche Funktion in Firefox finden, aber wenn ihr eine Erweiterung kennt, die etwas Ähnliches in anderen Browsern anbietet, hinterlasst bitte einen Kommentar.

Barrierefreie Akkordeons mit dem details HTML-Element erstellen

In meinem vorletzten Blog-Beitrag zum Thema HTML in dieser Adventskalender-Serie möchte ich ein Element vorstellen, das einige von euch vielleicht schon benutzt haben, ohne es zu kennen. Aber die Funktionalität, die es euch bietet, haben viele von euch vielleicht schon in einer Website verwendet.

Toggle- und Akkordeon-Elemente

Wenn wir nur ein Element haben, das beim Anklicken eines Buttons oder Textes zusätzlichen Text einblendet, sprechen wir oft von „Toggle-Elementen“. Gibt es mehrere, von denen immer nur eines gleichzeitig geöffnet sein kann, spricht man von „Akkordeons“.

In der Vergangenheit hätten wir für eine solche Funktionalität eine JavaScript-Bibliothek verwenden und den Inhalt in einigen Container-Elementen platziert, die dann über einen Button oder Link angezeigt werden. Aber jetzt haben wir ein Element für diese Funktion. Wenn wir einen einzelnen Toggle haben wollen, wäre dies unser Markup:

<details open>
	<summary>Erfahre mehr über das details Element</summary>
	Dies ist Text, der nur angezeigt wird, wenn das Element geöffnet wird.
	Ihr können hier auch beliebige andere HTML-Elemente verwenden, ihr müsst 
	also nicht nur einfachen Text verwenden.
</details>

In diesem Beispiel wird der „versteckte Text“ nicht in ein Element eingeschlossen. Wahrscheinlich würdet ihr hier ein <p> oder <div> verwenden, aber eigentlich wird jeder Inhalt, der nach dem <summary> Element kommt, ausgeblendet. Das Element wird standardmäßig „geschlossen“ angezeigt uns es würde so aussehen:

Ein nach rechts zeigendes Dreieck mit dem Text „Erfahre mehr über das details Element“ daneben.

Der nach rechts zeigende Pfeil wird standardmäßig angezeigt. Die Form wird in den verschiedenen Browsern etwas unterschiedlich aussehen. Wenn ihr auf den Pfeil oder den Text klickt, wird das Element geöffnet, und der Pfeil zeigt jetzt nach unten. Damit wird angezeigt, dass das Element geöffnet ist:

Ein nach unten zeigendes Dreieck, mit dem Text des details Elements rechts davon und dem restlichen Inhalt innerhalb des details Elements darunter.

Wie bereits erwähnt, ist das Element standardmäßig geschlossen, ihr können es aber auch öffnen, indem ihr ein leeres open Attribut zum Element hinzufügt:

<details open>
<!--... -->
</details>

Wenn ihr nun auf das <summary> Element klickt, wird das <details> Element geschlossen. Ich kann mir nicht wirklich einen Anwendungsfall vorstellen, in dem man dies für einen einzelnen Toggle verwenden würde. Warum sollte man mit einem Klick etwas ausblenden, das bereits sichtbar war?

Erstellen eines Akkordeons mit mehreren „gruppierten“ details Elementen

Das <details> Element hat nur zwei spezifische Attribute. Das Attribut open haben wir bereits kennengelernt, das zweite ist name. Wenn ihr mehreren <Details> Elementen dieses Attribut mit demselben Wert gebt, werden sie zu einem Akkordeon gruppiert, wobei immer nur eines zur gleichen Zeit geöffnet sein kann:

<h2>Gruppe eins</h2>
<details name="group-one">
	<summary>Erstes Element von Gruppe eins</summary>
	<p>Der Inhalt des ersten Elements von Gruppe eins.</p>
</details>
<details name="group-one">
	<summary>Zweites Element von Gruppe eins</summary>
	<p>Der Inhalt des zweiten Elements von Gruppe eins.</p>
</details>
<h2>Gruppe zwei</h2>
<details name="group-two">
	<summary>Erstes Element von Gruppe zwei</summary>
	<p>Der Inhalt des ersten Elements von Gruppe zwei.</p>
</details>
<blockquote>
	<q>Ein zufälliges Zitat dazwischen</q>
	<p>Eine berühmte Person</p>
</blockquote>
<details name="group-two" open>
	<summary>Zweites Element von Gruppe zwei</summary>
	<ul>
		<li>Punkt 1</li>
		<li>Punkt 2</li>
	</ul>
</details>

Ich habe hier ein etwas komplexeres Beispiel gewählt, um mehrere Dinge auf einmal zu zeigen. Zunächst einmal haben wir zwei Akkordeons, die jeweils die Werte group-one bzw. group-two für das name Attribut verwenden. Das HTML-Markup würde folgendermaßen dargestellt werden:

Zwei details Akkordeongruppen mit einem Zitat zwischen den Elementen der zweiten Gruppe, die eine ungeordnete Liste als Inhalt des zweiten details Elements hat.

In Gruppe eins hat kein Element das open Attribut, also sind beide standardmäßig geschlossen, während in Gruppe zwei das zweite Element das open Attribut hat und seinen Inhalt anzeigt. In diesem Fall ist der Inhalt eine ungeordnete Liste, was zeigt, dass das Element beliebigen HTML-Code und nicht nur statischen Text enthalten kann.

Zwischen dem ersten und dem zweiten Element der zweiten Gruppe befindet sich auch ein „Blockquote“ (Zitatblock). Dies soll verdeutlichen, dass nicht alle <details> Elemente direkt neben-/untereinander stehen müssen. Ihr könnt auch Inhalte dazwischen haben.

Wenn ihr eines der anderen Elemente in derselben Gruppe öffnet, wird automatisch das aktuell geöffnete Element geschlossen. Wenn ihr das geöffnete Element ebenfalls schließt, sind dann alle geschlossen. Es gibt keine (native) Möglichkeit, das Schließen aller Elemente zu verbieten.

Wenn ihr ermöglichen wollt, dass alle Elemente offen sind, verwenden einfach nicht das Attribut name für diese Elemente. Ihr könnt auch ein wenig JavaScript für zwei Buttons „Alle öffnen“ und „Alle schließen“ verwenden, die alle Elements öffnen oder schließen würden. Es gibt sogar ein toggle Event, für das ihr einen Event-Listener registrieren könnet. Mehr dazu finden ihr in der Dokumentation.

Styling des Elements

Die Dokumentation enthält auch einige grundlegende Beispiele für die Gestaltung. Wenn ihr noch kreativere Möglichkeiten zur Gestaltung des Elements sehen möchten, kann ich euch den CSS-Tricks-Blogbeitrag zu diesem Element sehr empfehlen..

Fazit

Wenn ihr wirklich ein Toggle-/Akkordeon-Element auf eurer Website benötigt, kann ich die Verwendung der nativen HTML-Elemente sehr empfehlen. Ich persönlich mag keine Toggles oder Akkordeons. Ich blättere lieber durch eine längere Seite, als auf all diese „Toggle-Buttons“ klicken zu müssen, die die Seite auch noch nach oben/unten verschieben, womit man das nächste Element erst einmal anvisieren muss. Das frustriert mich wirklich.

Wenn ihr WordPress verwendet, benutzt einfach den „Details“ Block, der euch genau dieses Element liefert. Ihr habt dann eine Zeile für die Zusammenfassung und dann einen „Absatz“ Block für den Inhalt. Ihr könnt hier aber jeden beliebigen Block verwenden, sogar mehrere oder Blöcke wie „Gruppe“, „Spalten“ usw., um wirklich kreativ zu werden.

Die prefers-color-scheme Media-Query

Heute möchte ich über etwas sprechen, das viele von euch wahrscheinlich sehr mögen: Dark-Modes! Oder genauer gesagt, wie man das Farbschema auf den dunklen Modus umstellt, diese Präferenz eingestellt ist. Ich verwende den Dark-Mode für meine IDE und für einige Online-Dienste, aber für viele bin ich immer noch auf der hellen Seite.

Erkennung des Dark-Modes und Anpassung der Styles

Die Aktivierung des Dark-Mode kann durch eine Einstellung im Betriebssystem oder Browser vorgenommen werden oder durch das Klicken auf einen Button passieren. Unabhängig davon, wie zum Dark-Mode gewechselt wird, sollte euer CSS-Code die Media-Query wie folgt verwenden:

button {
	padding: 10px 20px;
	font-size: 2rem;
	background-color: #eee;
	border: 3px solid #333;
	border-radius: 10px;
	color: #333;
}
@media (prefers-color-scheme: dark) {
	button {
		background: #333;
		border-color: #333;
		color: #eee;
	}
}

Dieses CSS geht davon aus, dass ihr standardmäßig ein helles Farbschema verwenden. Wenn nun die Präferenz auf dark gesetzt wird, werden alternative Farben für die Buttons verwendet. So würde ein Button in hellen oder dunklen Farben aussehen:

Ein Button mit dem Text „light colors“ auf der linken Seite, mit einer hellgrauen Hintergrundfarbe und einer dunkelgrauen Text- und Rahmenfarbe. Ein zweiter Button auf der rechten Seite mit dem Text „dark colors“, dem Text in hellgrau und dem Hintergrund und Rahmen in dunkelgrau für ein „ausgefülltes“ Design.

Durch die Verwendung der gleichen Farbe für Hintergrund und Rahmen haben wir die dunkle Version des Buttons „ausgefüllt“. Ihr müsst aber nicht immer alle Farben invertieren/vertauschen. Einige generische Plugins tun dies jedoch. Wie ich im Beitrag „Präferenzen im Browser simulieren“ erklärt habe, könnt ihr diese Dark-Mode-Styles einfach testen, ohne die Einstellungen in eurem Betriebssystem ändern zu müssen. Chrome verfügt noch über eine Option „Automatischer dunkler Modus“, aber diese würde nur versuchen zu „erraten“, welche Farben verwendet werden könnten. Wir hätten dann ein etwas helleres Grau für den Hintergrund und ein helleres Grau für den Rahmen:

Zwei Buttons, einer mit der Bezeichnung „light colors“ und einer mit der Bezeichnung „dark colors“. Beide haben die gleichen Farben, mit einem mittelgrauen Rand, einem dunkelgrauen Hintergrund und einer hellgrauen Textfarbe.

Wie ihr sehen könnt, würden sogar unsere definierten Farben für den Dark-Mode eines Buttons nicht mehr verwendet werden. Stattdessen zeigt Chrome jeden Button in diesem „automatischen dunklen Modus“ an. Ich bin mir aber auch nicht sicher, ob viele Leute das wirklich nutzen.

Verwendung des hellen Dark-Modes als Standard

Viele Leute entwerfen eine Website mit einem hellen Modus als Standard und verwenden dann die Medienabfrage wie oben gezeigt, um die Farben für einen dunklen Modus zu ändern. Wenn ihr allerdings eine Seite mit einem Dark-Mode als Standard gestalten möchtet, wäre das eine Menge CSS in dieser Media-Query. Was ihr hier stattdessen tun könnt: ändern die Farben, wenn jemand ausdrücklich einen hellen Modus bevorzugt. So in etwa macht ihr das:

button {
	padding: 10px 20px;
	font-size: 2rem;
	background-color: #333;
	border: 3px solid #333;
	border-radius: 10px;
	color: #eee;
}
@media (prefers-color-scheme: light) {
	button {
		background: #eee;
		border-color: #eee;
		color: #333;
	}
}

Dieser Code-Schnipsel ist im Grunde genommen wieder der Erste, es sind nur (fast) alle Farben vertauscht und wir haben den bedeutenden Unterschied, dass wir jetzt in der Media-Query prefers-color-scheme nach light abfragen. Der Button sieht nun im Standard-Dark-Mode und im hellen Modus wie folgt aus:

Zwei Buttons, der linke mit dem Text „dark colors“, einem dunkelgrauen Hintergrund und hellgrauen Text. Der rechte mit dem Text „dark colors“, einem hellgrauen Hintergrund und dunkelgrauem Text.

Je nach euren eigenen Vorlieben könnt ihr also entscheiden, welches Farbschema ihr als Standard für eure Website verwenden möchtet. Das Hinzufügen des anderen Farbschemas kann allerdings einen großen Unterschied in Bezug auf Lesbarkeit und Barrierefreiheit machen. Vor allem, wenn ihr einen Dark-Mode als Standardeinstellung haben wollte, sollten ihr unbedingt in Erwägung ziehen, auch ein helles Farbschema anzubieten.

Fazit

Das Hinzufügen eines Dark-Mode zu eurem CSS war noch nie so einfach wie mit dieser Media-Query. Wenn ihr die Möglichkeit zur Auswahl der Modus geben wollt, kann ein „Umschalt-Button“ oder eine Profileinstellung sinnvoll sein. Dafür ist eine weitere Eigenschaft sehr nützlich. Aber das wird das Thema unseres letzten Blogbeitrags im Adventskalender 2024 zu CSS sein.

Tagged Template Literals in JavaScript

Im Blogbeitrag vor 8 Tagen mit dem Titel „Dynamische Parameter in JavaScript“ habe ich euch gezeigt, wie Funktionen mit einer variablen Anzahl von Parametern funktionieren. Heute möchte ich über die Funktion „getaggte Template“ („Tagged Template Literals“) in JavaScript sprechen, als eine Art von Funktion, die variable Anzahl von Parametern hat.

Template-Literale

Bevor wir uns dem Thema zuwenden, sollten wir zunächst über „Template Literals“ sprechen. In alten Versionen von JavaScript hätte man Folgendes getan, wenn man eine Variable zwischen statischem Text einfügen möchte:

var name = "Bernhard";
var country = "Finland";
var greet = "Hi, my name is " + name + " and I'm currently in " + country + ".";
console.log(greet);
//Hi, my name is Bernhard and I'm currently in Finland.

Mit modernem JavaScript könnt ihr „Template Literals“ verwenden, um eine Variable (oder sogar Code) in euren Strings zu platzieren, die dann interpretiert werden:

const name = "Bernhard";
const country = "Finland";
const greet = `Hi, my name is ${name} and I'm currently in ${country}.`;
console.log(greet);
//Hi, my name is Bernhard and I'm currently in Finland.

Durch die Verwendung von „Backticks“ anstelle von Anführungszeichen verwandeln wir unseren einfachen String in ein Template Literal. Ist das nicht viel einfacher zu lesen? Ah, und ja, ich bin derzeit in Finnland und nicht in Berlin. Auf den Åland-Inseln, um genau zu sein.

Tagged Template Literals

Nach dieser kurzen Einführung kommen wir nun zu den „getaggten“ Template Literals. Wenn ihr sie zum ersten Mal seht, dann kommen sie euch vielleicht ein bisschen seltsam aus. So könnte ein Beispiel aussehen:

const name = "Bernhard";
const country = "Finland";
const greet = makeItBold`Hi, my name is ${name} and I'm currently in ${country}.`;

function makeItBold(strings, ...values) {
	// strings => ['Hello, my name is ', " and I'm currently in ", '.']
	// values => ['Bernhard', 'Finland']

	let result = "";

	// Loop through the strings and values
	for (let i = 0; i < values.length; i++) {
		result += strings[i] + `<b>${values[i]}</b>`;
	}

	// Append the last string (after the last variable)
	result += strings[values.length];

	return result;
}

console.log(greet);
// Hi, my name is <b>Bernhard</b> and I'm currently in <b>Finland</b>.

Wir definieren eine Funktion(makeItBold) und schreiben dann einfach den Funktionsnamen vor das Template Literal. In der Funktion erhalten wir das „statische Strings-Array“ als ersten strings Parameter und dann eine dynamische Anzahl von Parametern für jede „Variable“ (oder genauer gesagt jeden Ausdruck) im Template Literal als zweiten values Parameter. Wir könnten diese Funktion auch so schreiben:

function makeItBold(strings, name, country) {
	// ...
}

Aber das wäre nicht wirklich flexibel, wenn wir die Variablen vertauschen oder mehr/weniger Variablen in einem anderen String haben.

Eine Möglichkeit, die Funktion etwas kürzer zu machen, ist die Verwendung von modernem JavaScript-Code, der mit Arrays arbeitet (zur besseren Lesbarkeit in mehreren Zeilen geschrieben):

function makeItBold(strings, ...values) {
	return strings.reduce(
		(result, str, i) => result + str + (values[i] ? `<b>${values[i]}</b>` : ""),
		""
	);
}

Diejenigen unter euch, die mit modernem JavaScript vertraut sind, können dies wahrscheinlich leicht lesen. Ich muss immer noch zweimal hinschauen und es sorgfältig lesen.

Ich hatte Schwierigkeiten, ein gutes „Praxisbeispiel“ zu finden, aber nachdem ich das obige Beispiel gefunden hatte, ist mir sogar eines eingefallen, das wirklich nützlich sein könnte. Es arbeitet auch nicht mit skalaren Werten, sondern mit Objekten. Was haltet ihr von diesem Beispiel?

function schema(strings, ...values) {
	return strings.reduce((result, str, i) => {
		const value = values[i];
		if (value) {
			// Check for specific schema.org types and add relevant markup
			if (value.type === "Person") {
				return (
					result +
					str +
					`<span itemscope itemtype="https://schema.org/Person">
						<span itemprop="name">${value.name}</span>
					</span>`
				);
			} else if (value.type === "Place") {
				return (
					result +
					str +
					`<span itemscope itemtype="https://schema.org/Place">
						<span itemprop="name">${value.name}</span>
					</span>`
				);
			}
		}
		return result + str;
	}, "");
}

// Usage
const name = { type: "Person", name: "Bernhard" };
const country = { type: "Place", name: "Finland" };

const greet = schema`Hello, my name is ${name} and I'm currently in ${country}.`;

console.log(greet);
// Hello, my name is <span itemscope itemtype="https://schema.org/Person"><span itemprop="name">Bernhard</span></span> and I'm currently in <span itemscope itemtype="https://schema.org/Place"><span itemprop="name">Finland</span></span>.

Fazit

Wie bereits erwähnt, war es nicht einfach, ein gutes Beispiel zu finden. Man könnte argumentieren, dass man in vielen Fällen auch einfach ein Template Literal und etwas Inline-HTML-Markup verwenden könnte. Aber trotzdem gibt es diese Funktionalität und ihr sollten wissen, wie solcher Code funktioniert.

Wenn ihr ein Beispiel mit Tagged Template Literals aus einem eurer Projekte habt, hinterlasst bitte einen Kommentar.

JavaScript mit dem debugger Keyword pausieren lassen

Dieser Blogbeitrag soll keine grundlegende Einführung in das Debugging mit JavaScript sein. Wir könnten wahrscheinlich einen ganzen Adventskalender mit allen Aspekten füllen. Aber ich möchte ein kleines Schlüsselwort für eure Debugging-Toolbox vorstellen.

Einen Breakpoint im Browser setzen

Wenn ihr einen JavaScript-Code debuggen wollt, dann setzt ihr wahrscheinlich irgendwann einen Breakpoint in eurem Code. Wenn ihr eine kleine JavaScript-Datei habt, die schön formatiert ist, sieht sie in Chrome vielleicht so aus:

Chrome Entwicklertools mit einem manuellen gesetzten Breakpoint, der den Browser an dieser Zeile pausieren lässt.

Ihr öffnet dazu die Entwicklertools, navigieren auf der Registerkarte „Quellcode“ („Sources“) zur JavaScript-Datei, setzen einen Breakpoint und laden die Seite neu. Chrome hält dann an der Zeile an, und ihr könnt euren Code debuggen.

Das Problem mit kompiliertem JavaScript-Code

Diejenigen unter euch, die Code mit React, Vue usw. entwickeln und Webpack oder ähnliche Tools zum Kompilieren eures Codes verwenden, die erhalten keinen so schön formatierten Code, der auch noch leicht zu lesen ist. Fügen wir unseren Code von oben in den Kompilierungs-Workflow aus dem Paket @wordpress/scripts ein und kompilieren ihn:

npm run build

Jetzt erhalten wir eine kompilierte „Produktions-Datei“, und unser schön formatierter Code ist jetzt nur noch eine einzige Zeile in dieser kompilierten Datei:

Chrome Entwicklertools, die eine minifizierte Datei anzeigen.

Wie setzen wir jetzt einen Breakpoint? Wenn ihr einen Breakpoint in einer „einzeiligen JavaScript-Datei“ setzen wollt, gibt es eine kleine Funktion, die ihr verwenden können. Klickt dazu einfach auf das „{}“ Symbol („Quelltextformatierung“) unten links in der mittleren Spalte, und ihr erhaltet etwas wie im folgenden Screenshot. Hier könnt ihr nun einen Haltepunkt in der „virtuellen Zeile“ setzen:

Chrome dev tools "pretty printing" the one-line JavaScript file and a manual break point set on a prettified line.

Das funktioniert einigermaßen. Aber wenn ihr den Aufruf von console.log() am Ende der Datei debuggen wollt, dann stehen sie immer noch in einer Zeile und auch noch zusätzlich in einem ternären Operator.

Verwendung des debugger Keywords für einen „erzwungenen Breakpoint“

Nach dieser kurzen Einführung kommen wir nun zu dem Keyword, über das ich heute sprechen wollte. Während ihr euren Code entwickelt, können ihr das debugger Keyword an eine beliebige Zeile eures Codes einfügen, wodurch der Browser gezwungen wird, an dieser Stelle zu pausieren. Verwenden wir es also in der kompilierten Version, um den „if“-Teil des ternären Operators zu debuggen. Wir verwenden nun einen anderen Befehl, um die „Entwicklungsversion“ zu erhalten, der auch einen Watcher startet und den Code kompiliert, sobald wir etwas ändern:

npm run start

In unserem JavaScript-Code fügen wir außerdem das debugger Keyword wie folgt am Ende des if/else ein:

if (found) {
    debugger;
    console.log(`there is a 4 in array ${found}'`);
} else {
    console.log("There is no 4 in the array");
}

Wenn wir den Browser jetzt aktualisieren, wird er bei diesem Keyword in Zeile 17 anhalten. Wir müssen hier keinen Breakpoint setzen:

Chrome dev tool showing a JavaScript file stopped at the "debugger" keyword.

Oben rechts seht ihr „Debugger paused“ und das Skript ist angehalten, genau wie bei einem von uns manuell gesetzten Breakpoint in dieser Ansicht. Wir können nun mit unserem Debugging fortfahren.

Verwendung des debugger Keywords in minifizierten Dateien

Eine Anmerkung vorweg: ihr solltet das wahrscheinlich nicht tun. Wenn ihr das „build“-Skript verwendet, dann erstellt ihr normalerweise Dateien für den produktiven Einsatz und diese sollten kein debugger Keyaord enthalten. Aus diesem Grund entfernt das Webpack-Minifizierungs-Plugin dieses Keyword automatisch. Wenn ihr, aus welchen Gründen auch immer, das debugger Keyword in den kompilierten Dateien haben wollt, müsst ihr eine eigene webpack.config.js Webpack-Konfigurationsdatei schreiben:

const defaultConfig = require('@wordpress/scripts/config/webpack.config');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    ...defaultConfig,
    optimization: {
        ...defaultConfig.optimization,
        minimize: true,
        minimizer: [
            new TerserPlugin({
                terserOptions: {
                    compress: {
                        drop_debugger: false,
                    },
                },
            }),
        ],
    },
};

Wenn wir jetzt npm run build ausführen und den Browser aktualisieren, sehen wir das Keyword und der Browser bleibt dort stehen:

Chrome dev tool showing a JavaScript file stopped at the "debugger" keyword in a "prettified" minified code.

Dies würde auch automatisch das „Quelltextformatierung“-Symbol unten links aktivieren und euren Code wie oben zeigen.

Fazit

Es kann manchmal schwierig sein, einen Breakpoint manuell zu setzen, besonders wenn eure JavaScript-Dateien kompiliert, kombiniert und sogar minifiziert wird und ihr keine Ahnung haben, wo eine Zeile, die ihr gerade geschrieben habt, am Ende zu finden ist. Ihr können das debugger Keyword auch nur vorübergehend setzen, und sobald das Skript angehalten wurde, einen regulären Haltepunkt setzen, um das Schlüsselwort dann sofort zu entfernen, damit ihr nicht versehentlich Code mit dem Keyword darin veröffentlicht.

Das HTML meter Element und wie es funktioniert

Dieser Blogbeitrag behandelt ein Element, das dem progress Element aus einem vorherigen Blogbeitrag sehr ähnlich ist. Es wird verwendet, um eine Art „Füllstand“ wie bei einer Batterie oder eine „Score“ (Punktzahl) wie bei einem Online-Test anzuzeigen. Diese Visualisierungen werden in der Regel durch einen Minimal- und Maximalwert definiert.

Ein einfaches Beispiel für das meter Element

Beginnen wir mit einem sehr einfachen Beispiel, mit nur den Attributen, die mindestens notwendig sind. Die folgenden müssen wir implementieren:

<label for="score">Score:</label>
<meter id="score" value="0.5">50%</meter>

OK, das zugehörige <label> ist optional. Aber vermutlich habe ihr mittlerweile bemerkt, dass ich immer versuche Beispiele zu geben, bei denen die Barrierefreiheit beachtet wird.

Das Element hat ein min Attribut, das standardmäßig auf 0 gesetzt wird, wenn es nicht definiert wurde, während max auf 1 gesetzt wird. Wenn wir sie also nicht definieren, würden wir einen Wertebereich zwischen 0 und 1 verwenden und damit würde unser Wert von 0,5 dann 50% auf dem Zähler darstellen. Das Ergebnis würde dann so aussehen:

A label "Score" followed by the meter element that is half "filled" with a green background.

Ähnlich wie beim <progress> Element sehen wir den „Textknoten“, auf dem „50%“ steht, nicht. Dieser wird nur angezeigt, wenn das Element vom Browser nicht unterstützt wird.

Verwendung der zusätzlichen Attribute, um das Element noch nützlicher zu machen

Beim <progress> Element gab es nur ein max und value Attribut. Das <meter> Element hat viel mehr Attribute und sie machen den großen Unterschied zwischen den beiden Elementen aus. Hier ist ein Beispiel mit allen Attributen, die wir verwenden können:

<meter min="-20" max="100" low="10" high="40" optimum="25" value="10">10°C</meter>

Wir können die Attribute min und max explizit angeben. Das min Attribut ist auch nicht auf 0 festgelegt, sondern kann jeden beliebigen Wert annehmen, auch einen negativen, z. B. für eine Temperaturskala mit Minusgraden. So würde das für verschiedene Temperaturwerte aussehen:

Seven meter elements ranging from -20°C to 100°C with the temperature 10°C, 25°C and 40°C with a green background, the other ones with a yellow background.

Wenn wir einen optimum Wert zwischen dem min und dem max Attributwert festlegen (der Wert kann zwischen 10 und 40 liegen), wird dieser Bereich mit einem grünen Hintergrund dargestellt. Jeder Bereich, der unter dem min Wert oder über dem max Wert liegt, wird gelb dargestellt.

Ein meter Element mit drei verschiedenen Farben

Nehmen wir ein weiteres Beispiel mit einem Test-Score. Wir würden den Test als „bestanden“ definieren, wenn wir 50 % oder mehr erreichen und er wäre „gut“, wenn wir 80 % oder mehr schaffen. Diese Elemente würden unterschiedliche Punktzahlen darstellen:

<meter min="0" max="100" low="50" high="80" optimum="100" value="0">    0%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="10">  10%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="20">  20%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="30">  30%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="40">  40%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="50">  50%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="60">  60%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="70">  70%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="80">  80%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="90">  90%</meter>
<meter min="0" max="100" low="50" high="80" optimum="100" value="100">100%</meter>

In diesem Codebeispiel liegt unser optimum Wert zwischen high und max. Wenn der Wert von optimum größer ist als der Wert von max (wir haben ihn einfach auf 100 gesetzt), erhalten wir drei verschiedene Hintergrundfarben:

Eleven meter elements ranging from 0% to 100%. The background at 0% is not visible and values 10% to 40% have a green red background. Values 50% to 70% have a yellow and values 80% to 100% have a green background.

Das spiegelt unsere Definition der Punktzahl perfekt wider, oder nicht? Wenn ihr euch sich nicht sicher seid, wie ihr die Werte für die Attribute festlegen müsst, schaut in der Dokumentation nach und testet verschiedene Werte in verschiedenen Browsern.

Styling des Elements

Es gibt nur wenige CSS-Eigenschaften, die wir in WebKit-Browsern verwenden können. Safari benötigen sogar einen JavaScript-Hack, damit sie funktionieren. Ihr findet sie im Abschnitt „See more“ der Dokumentation verlinkt.

In Chrome können wir sie mit einem Attributselektor kombinieren, um die Hintergrundfarbe des genauen „optimalen Werts“ für das Temperaturbeispiel wie folgt zu ändern:

meter[value="25"]::-webkit-meter-optimum-value {
	background-color: blue;
}

In Firefox hätte dies jedoch keine Auswirkung. Sobald ihr den Hintergrund des Elements ändern, sieht es völlig anders aus (genau als wenn ihr "appearance: none“ darauf anwendet). Ich euch empfehlen, einfach mal ein wenig mit dem Element zu experimentieren.

Fazit

Das <meter> Element ist wahrscheinlich eines der weniger bekannten Elemente, aber es kann eine nette Ergänzung für eure Benutzeroberfläche sein, um Zahlen besser zu visualisieren. Für das <progress> Element hatten wir die ProgressBar-Komponente für WordPress, aber für <meter> gibt es leider keine Komponente in WordPress.

Bessere Lesbarkeit mit reduzierter Transparenz

Heute möchte ich über eine CSS-Funktion schreiben, die noch experimentell ist. Aber sie kann einen Unterschied für alle machen, die Schwierigkeiten haben, Text auf transparenten Elementen zu lesen.

Auf vielen Websites finden wir Elemente, die Text auf einem Bild platzieren. Dies ist oft ein großes Problem für die Lesbarkeit des Textes.

Text auf einem Bild

Sehen wir uns hierzu ein kleines Beispiel an. WordPress bietet den „Cover“-Block an. Wenn wir ihn verwenden, wird das Bild zu einem Hintergrundbild. Der Block verfügt über ein Steuerelement für die „Overlay-Deckkraft“. Wenn die Deckkraft auf einen Wert von 21 oder weniger eingestellt ist, wird der Text standardmäßig schwarz angezeigt. Wenn der Wert auf 22 oder höher gesetzt ist, wird die Textfarbe auf Weiß umgestellt.

Cliffs in the archipelago of Åland with stones coverd in lichen in the front and the sea (blurred) in the back.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Wie wir im obigen Beispiel sehen können, ist der Text im oberen Teil schwer zu lesen, selbst wenn man normalerweise keine Probleme mit dem Lesen von Text auf Bildern hat. Für mich als Legastheniker kann das extrem frustrierend sein, Text so zu lesen.

Verwendung einer Präferenz zur Verringerung der Transparenz

Die neue CSS-Eigenschaft, über die ich heute schreiben möchte, heißt prefers-reduced-transparency und verwendet genau wie die Präferenz für reduzierte Bewegungen den Wert reduce. Hier ist ein Beispiel für den Cover-Block:

@media (prefers-reduced-transparency: reduce) {
    .has-background-dim {
        opacity: .7;
    }
}

In einem früheren Blogbeitrag habe ich erklärt, wie man Präferenzen im Browser simulieren kann. Wenn ihr die Rendering-Einstellung bei euch simuliert, dann würde der Cover-Block nach der Änderung der Deckkraft so aussehen:

Cliffs in the archipelago of Åland with stones coverd in lichen in the front and the sea (blurred) in the back.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Ist das nicht viel besser zu lesen? Die Deckkraft zu ändern, wenn jemand eine geringere Transparenz bevorzugt, ist ziemlich einleuchtend. Aber wie bei jeder anderen Media-Query könnt ihr auch hier beliebige CSS-Eigenschaften verwenden. Anstatt also die Deckkraft zu ändern, könntet ihr auch das Element ändern.

Wie wäre es z.B. damit, den Text unterhalb des Bildes ohne Transparenz und mit schwarzem Text auf weißem Hintergrund zu platzieren? Oder wir richten den Text neben dem Bild aus. Seid kreativ und macht eure Inhalte für Menschen mit unterschiedlichen Präferenzen und Bedürfnissen besser lesbar.

Fazit

Es gibt so viele CSS-Eigenschaften, die unbekannt oder noch nicht weit verbreitet sind. Diese spezielle Eigenschaft kann bereits in Chromium-Browsern verwendet werden und Firefox-Benutzer können ein Flag setzen, um sie zu verwenden. Wenn ihr Windows 10/11, macOS oder iOS verwenden, können ihr diese Präferenz ebenfalls bereits einstellen, wie in der Dokumentation erklärt wird. Angesichts der bereits guten Betriebssystem-Unterstützung würde es mich überraschen, wenn diese neue Media-Query noch lange experimentell bleiben würde.

Natürliche Sortierung in JavaScript

Wenn ihr in eurem Code nur mit englischen Strings zu tun habt, dann können ihr jetzt aufhören weiter zu lesen. Es sei denn, ihr sind neugierig und wollt etwas Neues lernen, dann bleiben bitte dran. 😉

In Sprachen wie Deutsch gibt es Zeichen, die im englischen Alphabet nicht vorkommen. Manche sehen anderen Zeichen ähnlich, aber manche sind extra. Und im Deutschen haben wir nur 4 davon, andere Sprachen haben viele mehr.

Wie Strings normalerweise sortiert werden

Wenn ihre ein Array von Strings habt, gibt es verschiedene Möglichkeiten, wie sie sortiert werden. Schauen wir uns einige Beispiele an:

console.log(['c', 'b', 'a', 'B', 'A', 'C'].sort())
// (6) ['A', 'B', 'C', 'a', 'b', 'c']

Diejenigen von euch, die schon einmal Code geschrieben und mit einer einfachen Sortierfunktion ein Array von Strings sortiert haben, ist vielleicht aufgefallen, dass viele dieser Funktionen die Reihenfolge der Zeichen in der ASCII-Tabelle verwenden. Deshalb sehen wir zuerst die Großbuchstaben, gefolgt von den Kleinbuchstaben.

Das mag für Englisch genau das sein, was wir erwarten und wollen. Aber was passiert, wenn wir ein paar deutsche Umlaute in das Array einfügen:

console.log(['ä', 'b', 'a', 'B', 'Ä', 'A'].sort())
// (6) ['A', 'B', 'a', 'b', 'Ä', 'ä']

Hm, das große „Ä“ kommt nach allen anderen Kleinbuchstaben, das hätten wir selbst eher nicht so sortiert. Da die Umlaute nicht Teil der ASCII-Tabelle sind (wie die meisten Buchstaben, die nicht in „Basic Latin“ enthalten sind), verwendet JavaScript die UTF-16 Codes, um sie zu sortieren. Diese stellen jedes Zeichen mit einer Zahl dar. Der Buchstabe „Ä“ zum Beispiel hat den numerischen Wert 228, während „z“ den Wert 122 hat, und deshalb ist er wie oben vor dem „Ä“ angeordnet.

Einsatz des Intl.Collator Objekts für die natürliche Sortierung

Die Lösung für dieses Problem ist wirklich sehr einfach. Die sort() Funktion für ein Array kann eine Callback-Funktion als Parameter übergeben bekommen. Dieser Funktion werden zwei Werte des Arrays übergeben. Sie soll eine negative Zahl zurückgeben, wenn der erste Wert kleiner ist als der zweite, eine positive Zahl, wenn das Gegenteil der Fall ist, oder 0, wenn beide den gleichen Wert haben.

Aber wir müssen eine solche Callback-Funktion nicht für jede Sprache selbst schreiben. Stattdessen können wir das Intl.Collator Objekt verwenden. Für unser Beispiel mit den deutschen Umlauten würde der Code wie folgt aussehen:

console.log(['ä', 'b', 'a', 'B', 'Ä', 'A'].sort(new Intl.Collator('de').compare));
// (6) ['a', 'A', 'ä', 'Ä', 'b', 'B']

Jetzt haben wir nicht nur unsere Umlaute neben den ähnlich aussehenden Buchstaben, sondern wir erhalten auch jeden Kleinbuchstaben gefolgt von seinem Großbuchstaben. Das ist auch das, was man von einer „Wörterbuchsortierung“ erwarten würde.

Direkte Verwendung der Vergleichsfunktion

Wie bereits erwähnt, erwartet die Funktion sort() eine Callback-Funktion, der eine negative oder positive Zahl oder eine 0 zurückgibt. Und genau das tut die Funktion auch. Wir können diese Funktion direkt aufrufen (und nicht nur auf ihren Namen übergeben) und zwei Buchstaben zum Vergleich übergeben:

new Intl.Collator('de').compare('ä', 'a')
// 1
new Intl.Collator('de').compare('a', 'ä')
// -1
new Intl.Collator('de').compare('a', 'a')
// 0

Um zu zeigen, dass diese Funktion nicht einfach eine statische Liste von Zahlen für jedes Zeichen verwendet, sondern wirklich nach einer bestimmten Sprache sortiert, habe ich hier ein gutes Beispiel dafür:

new Intl.Collator('de').compare('ä', 'z')
// -1
new Intl.Collator('sv').compare('ä', 'z')
// 1

Die schwedische Sprache, die ich gerade versuche zu lernen, hat auch den Buchstaben „ä“. Er ist jedoch anders sortiert als ein deutscher Umlaut, und man findet Wörter, die mit „ä“ beginnen, in einem schwedischen Wörterbuch fast am Ende (erst danach folgen Wörter, die mit „ö“ beginnen).

Erweiterte Optionen verwenden

Es gibt einige Optionen, die ihre zusätzlich als ein Objekt an die Funktion sort() übergeben könnt, wie in diesem Beispiel, wenn ihr die Großbuchstaben zuerst haben möchtet:

console.log(
	['ä', 'b', 'a', 'B', 'Ä', 'A'].sort(
		new Intl.Collator(
			'de', 
			{
				caseFirst: 'upper'
			}
		).compare
	)
);
// (6) ['A', 'a', 'Ä', 'ä', 'B', 'b']

Weitere Optionen finden ihr auf der Dokumentationsseite oder eine vollständige Liste in der ECMA-Spezifikation. Es gibt sogar einige wilde „Sprachen“ wie"de-u-co-phonebk„, um ein Array so anzuordnen, wie es in einem deutschen Telefonbuch stehen würde – falls ihr wisst, wovon ich rede. 😁

Bonus: Zahlenreihen sortieren

Ich möchte nicht über alle Optionen schreiben, aber eine könnte in eurem Code wirklich hilfreich sein. Wenn ihr schon einmal ein Array mit Zahlen als Strings sortiert habt, dann wissen ihr bestimmt, dass die alphanumerische Sortierung hier nicht funktioniert:

console.log(['1', '2', '11', '101', '3'].sort());
// (5) ['1', '101', '11', '2', '3']

Aber mit der Option numeric erhält man eine Sortierung, die man erwarten würde (der erste Parameter „Sprache“ ist hier vermutlich nicht so wichtig):

console.log(
	['1', '2', '11', '101', '3'].sort(
		new Intl.Collator(
			'en',
			{
				numeric: true
			}
		).compare
	)
);
// (5) ['1', '2', '3', '11', '101']

Genau das, was wir haben wollten. 😊

Fazit

Die Sortierung von Strings nach ihrer natürlichen Reihenfolge in einer bestimmten Sprache kann wirklich einen großen Unterschied in Bezug auf die Nutzbarkeit eures Codes machen (oder sogar dazu führen, dass der Code kaputt ist, wenn falsch sortiert wird). Mit dem Intl.Collator Objekt ist das in JavaScript auch recht einfach möglich. Andere Programmiersprachen bieten oft kein so mächtiges Werkzeug an.

Präferenzen im Browser simulieren

Bevor wir uns mit einigen weiteren Themen im Adventskalenders beschäftigen, müssen wir etwas über eine Browserfunktion erfahren, die wir dazu brauchen werden. Deshalb habe ich die Reihenfolge meiner geplanten Themen zum Debugging ein wenig umgestellt, um dieses Thema früher zu behandeln.

In einigen meiner nächsten Blog-Beiträge werde ich über ein paar CSS-Funktionen sprechen, die bestimmten Personen zugutekommen können, die eure Website besuchen. Vor fast 5 Jahren habe ich in einem Blog-Beitrag beschrieben, wieso man „Bewegungen auf einer Webseite für eine bessere Barrierefreiheit reduzieren“ sollte. In diesem Blogbeitrag habe ich erklärt, wie ihr die Einstellungen in Windows 10 oder Android 9 ändern könnt, um die Präferenz für reduzierte Bewegungen zu simulieren. Aber vielleicht verwendet ihr ein anderes Betriebssystem (wie ich z.B. Manjaro Linux für die Arbeit), bei dem es keine Schnelleinstellung gibt. Oder aber, ihr möchtet die Einstellung schneller umschalten können. Glücklicherweise gibt es bei einigen Browsern einen solchen Umschalter für euch.

Einstellungen in Chrome vornehmen

In Chrome (und anderen auf dem Chromium-Projekt basierenden Browsern wie Edge) finden ihr die meisten Einstellungen, indem ihr auf die drei vertikalen Punkte oben rechts klicken, dann „Weitere Tools“ auswählt und dort die „Rendering“ Einstellungen anklickt:

Screenshot, wie man die "Weitere Tools > Rendering" Einstellungen öffnet.

Dadurch öffnet sich ein weiteres Panel in den Entwicklertools. Wenn ihr ein wenig nach unten scrollt, finden ihr dort diese Einstellungen, mit denen ihr verschiedene Vorlieben simulieren könnt. In diesem Beispiel setze ich prefers-reduced-motion auf reduce:

Screenshot mit den diversen Rendering Einstellungen und der "prefers-reduced-motion" Einstellung geöffnet.

Der einzige Nachteil dieser Einstellung: sobald ihr die Entwicklertools schließt, wird die Einstellung auf ihren Standardwert zurückgesetzt. Wenn ihr also eine Website testen möchten, auf der mehr vertikaler Platz zur Verfügung stehen soll (da die beiden Panels viel Höhe beanspruchen), würde ich vorschlagen, die Entwicklertools in einem separaten Fenster anzuzeigen.

Wir werden diese Einstellungen für die kommenden Themen benötigen. Aber es gibt noch mehr Möglichkeiten, Einstellungen zu simulieren, die das Verhalten und das Aussehen eurer Website verändern. Wenn ihr beispielsweise eure Website schnell mal mit einem dunklen Farbschema anzeigen lassen möchtet, dann müssen ihr nicht euer Betriebssystem auf ein dunkles Farbschema umstellen oder die Rendering-Einstellungen öffnen. Stattdessen finden ihr im Abschnitt „Stile“ eine nette Umschaltfunktion. Klickt einfach auf das „Pinsel“-Symbol und wechselt hier zu dem Farbschema, das ihr testen möchtet.

Screenshot des geöffneten Umschalters für die "prefers-color-scheme" Einstellung.

Leider wird das Farbschema, genau wie beim Rendering-Panel, wieder auf den Standardwert zurückgesetzt, sobald ihr die Entwicklertools schließen.

Einstellungen in Edge vornehmen

Obwohl Edge auf Chromium basiert und viele Entwicklertools genau gleich aussehen, finden ihr in Edge nicht das Panel „Weitere Tools > Rendering“. Stattdessen öffnen ihr hierzu erst die Entwicklertools. Auf Panels wie „Elements“ seht ihr im unteren Teil die „Konsole“ und „Probleme“. Hier klickt ihr dann auf das „+“-Symbol und wählt die „Rendering Schnellansicht“. Nach dem Öffnen sieht sie den Einstellungen in Chrome sehr ähnlich.

Screenshot des geöffneten "Tools zur Schnellansicht hinzufügen" Panels in Edge.

Auch in Edge können ihr das Farbschema mit einem „Pinsel“-Symbol schnell umschalten, genau wie in Chrome.

Einstellungen in Firefox vornehmen

In Firefox sind die Einstellungen nicht leicht zugänglich. Außerdem befinden sie sich an verschiedenen Stellen. Wenn ihr prefers-reduced-motion einstellen möchtet, müsst ihr zur URL about:config navigieren, dann nach ui.prefersReducedMotion suchen, einen booleschen Wert hinzufügen und ihn auf false setzen. Für prefers-reduced-transparency müsste ihr hingegen nach layout.css.prefers-reduced-transparency.enabled suchen und diesen Wert auf true setzen. Das ist alles sehr inkonsistent und ärgerlicherweise nicht an einem Ort.

Wenn wir das Farbschema umschalten wollen, haben wir mehr Glück. Firefox bietet zwei Schaltflächen an. Mit dem „Sonnensymbol“ können ihr den hellen Farbmodus und mit dem „Mondsichelsymbol“ den dunklen Farbmodus erzwingen.

Screenshots des Buttons zur Simulation des dunkeln Farbschemas in Firefox.

Wenn ihr eine der beiden Schaltflächen aktiviert, wird automatisch die andere deaktiviert. Wenn ihr beide deaktiviert, wird wider der Standardmodus verwendet.

Bonus: schnelleres Umschalten der Einstellungen in Chromium-Browsern

Ich kann euch leider nicht sagen, wie ihr die Einstellungen in Safari ändern könnt, da ich keinen Mac benutze (oder Safari nicht oft genug simuliere). Aber ich habe einen netten kleinen Bonus-Tipp für euch. Wenn ihr eine dieser Einstellungen schnell ändern möchtet, können ihr die Funktion „Befehl ausführen“ in Chromium-Browsern verwenden.

Drücken hierzu bei geöffneten Entwicklertools die Tastenkombination „Strg + Umschalt + P“ (oder „Cmd + Umschalt + P“ auf einem Mac) und sucht dann nach der Einstellung, die ihr umschalten möchten:

Screenshot vom "Ausführen" Dialog in Chrome.

Ich habe keine entsprechende Funktion in Firefox gefunden, aber vielleicht kennt sie ja jemand von euch?

Fazit

Wenn ihr eine Website entwickelt, die sich je nach Einstellungen des Betriebssystems anders verhält oder anders gerendert wird, sollten ihr dies immer testen. Aber ihr müssen dazu nicht die Einstellungen eures Betriebssystems ändern. Browser haben normalerweise Optionen, um diese zu emulieren.

Wenn jemand von euch bessere Optionen für diese Einstellungen in Firefox oder eine Erweiterung kennt, mit der man diese einfacher umstellen kann, dann teilt den Tipp bitte in den Kommentaren.

Einen Fortschrittsbalken auf eurer Website anzeigen

Wenn Sie eine Webanwendung programmiert, bei der die Anzeige des aktuellen Fortschritts die UX verbessern würde, kann ein netter kleiner Fortschrittsbalken helfen. Und es gibt eine einfache Möglichkeit, einen hinzuzufügen. In der Vergangenheit haben wir dazu etwas wie jQuery UI Progressbar verwendet. Heute können wir jetzt ein natives HTML-Element verwenden.

Das progress HTML-Element

Stellt euch vor, ihr müsst ein Element zur Visualisierung eines Fortschritts auf einer Website erfinden. Wenn ihr überlegt, wie es aussehen würde und welche Attribute es haben sollte, dann kommt ihr vielleicht auf etwas Ähnliches wie das Range-Input, über das ich in einem früheren Beitrag geschrieben habe. Aber das Element ist viel einfacher:

<label for="progress-bar">Progress:</label>
<progress id="progress-bar" value="30" max="100">30 %</progress>

So sieht das native <progress> HTML-Element in Chrome mit dem obigen Code aus:

A label "Progress:" followed by the progress element with a 30% progress.

Wie ihr sehen könnt, ist das Element inline. Und fällt euch etwas auf? Obwohl es sich nicht um ein Formularelement handelt, wurde es mit einem Label kombiniert. Das verbessert seine Barrierefreiheit. Wenn ihr den Wert als Text-Kind-Element hinzufügen, wird dieser Text im Browser nicht angezeigt, wenn das Element unterstützt wird. Es ist also nur notwendig, wenn ihr es mit einem wirklich alten Browser zu tun habt, der das Element nicht unterstützt. Dann wird stattdessen dieser Text inline angezeigt.

Fortgeschrittene Verwendung des Elements

Ist euch aufgefallen, dass wir in dem Beispiel kein min Attribut gesetzt haben? Dieses Attribut ist nicht einmal verfügbar, denn der Standardwert für min ist immer 0.

Aber wussten ihr auch, dass ihr sogar auf das value Attribut verzichten könnt und was dann passieren würde? Vermutlich würde man nicht sofort vermuten, dass das hier passiert:

Ganz richtig! Ihr würdt einen animierten Fortschrittsbalken erhalten. Kein JavaScript, keine CSS-Animation, nur ein <progress> Element ohne Wert. Und um es noch toller zu machen, könnt ihr es mit einigen zusätzlichen Attributen zu einer barrierefreien Fortschrittsanzeige für einen anderen Bereich der Website machen. Hier ist ein Beispiel aus der Dokumentationsseite:

<div aria-busy="true" aria-describedby="progress-bar">
  <!-- content is for this region is loading -->
</div>

<!-- ... -->

<progress id="progress-bar" aria-label="Content loading…"></progress>

Wenn ihr in einem WordPress-Projekt seid, können ihr auch die ProgressBar-Komponente verwenden. Im WordPress-Core scheint sie nur für einen Fortschrittsbalken mit „Ladeanimation“, wie oben gezeigt, verwendet zu werden. Sie verwendet zwar ebenfalls das <progress> Element, aber auch hier wird die Standarddarstellung des Browsers durch benutzerdefiniertes HTML-Markup ersetzt, damit sie in allen Browsern das gleiche Design hat.

Fazit

Ein Fortschrittsbalken kann die UX einer Webanwendung wirklich verbessern. Wenn ihr einen braucht, sollten ihr euch für das native Element entscheiden. Ihr könnt es auch ein wenig stylen. Mehr dazu finden ihr auf den verlinkten Dokumentationsseiten. Wenn ihr ein <progress> Element hinzufügen, achten bitte darauf, dass es auch ein Label bekommt. Das hilft nicht nur Nutzern mit assistiven Technologien. Die Angabe, wofür der Fortschritt steht, hilft allen das Element besser zu verstehen.