Dem Attribut „lang“ kann nur eine Sprache zugeordnet werden. Das bedeutet, dass das <html>
-Attribut nur eine Sprache haben kann, auch wenn die Seite mehrere Sprachen enthält. Legen Sie für lang
die primäre Sprache der Seite fest.
<html lang="ar,en,fr,pt">...</html>
<html lang="ar">...</html>
Links
Ähnlich wie bei Schaltflächen wird der für Screenreader zugängliche Name von Links hauptsächlich aus dem Textinhalt abgeleitet. Ein guter Trick beim Erstellen eines Links besteht darin, den aussagekräftigsten Text in den Link selbst einzufügen, anstatt Füllwörter wie „Hier“ oder „Weitere Informationen“ zu verwenden.
Check out our guide to web performance <a href="/guide">here</a>.
Check out <a href="/guide">our guide to web performance</a>.
Prüfen, ob eine Animation das Layout auslöst
Eine Animation, bei der ein Element nicht mit transform
verschoben wird, ist wahrscheinlich langsam.
Im folgenden Beispiel habe ich dasselbe visuelle Ergebnis erzielt, indem ich top
und left
animiert und transform
verwendet habe.
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { top: calc(90vh - 160px); left: calc(90vw - 200px); } }
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { transform: translate(calc(90vw - 200px), calc(90vh - 160px)); } }
Sie können dies in den folgenden beiden Glitch-Beispielen testen und die Leistung mit den Entwicklertools analysieren.
Mit demselben Markup können wir padding-top: 56.25%
durch aspect-ratio: 16 / 9
ersetzen und aspect-ratio
auf ein bestimmtes Verhältnis von width
÷ height
festlegen.
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
Die Verwendung von aspect-ratio
anstelle von padding-top
ist viel verständlicher und die Eigenschaft „padding“ wird nicht überarbeitet, um etwas außerhalb ihres üblichen Umfangs zu tun.
Ja, das ist richtig. Ich verwende reduce
, um eine Abfolge von Versprechen zu verketten. Ich bin so klug. Aber das ist ein bisschen zu smart, um es zu verwenden.
Bei der Umwandlung in eine asynchrone Funktion ist es jedoch verlockend, zu sequentiell vorzugehen:
async function logInOrder(urls) { for (const url of urls) { const response = await fetch(url); console.log(await response.text()); } }
function markHandled(...promises) { Promise.allSettled(promises); } async function logInOrder(urls) { // fetch all the URLs in parallel const textPromises = urls.map(async (url) => { const response = await fetch(url); return response.text(); }); markHandled(...textPromises); // log them in sequence for (const textPromise of textPromises) { console.log(await textPromise); } }
reduce
-Bit wird durch eine standardmäßige, langweilige, lesbare For-Schleife ersetzt.
Benutzerdefinierte Houdini-Eigenschaften schreiben
Hier ein Beispiel für die Einstellung einer benutzerdefinierten Property (vergleichbar mit einer CSS-Variablen), jetzt aber mit einer Syntax (Typ), einem Anfangswert (Fallback) und einer booleschen Vererbung (wird der Wert vom übergeordneten Element übernommen oder nicht?). Derzeit ist dies nur über CSS.registerProperty()
in JavaScript möglich. Ab Chromium 85 wird die @property
-Syntax jedoch auch in CSS-Dateien unterstützt:
CSS.registerProperty({ name: '--colorPrimary', syntax: '' , initialValue: 'magenta', inherits: false });
@property --colorPrimary { syntax: '' ; initial-value: magenta; inherits: false; }
Sie können jetzt wie bei jeder anderen benutzerdefinierten CSS-Eigenschaft über var(--colorPrimary)
auf --colorPrimary
zugreifen. Der Unterschied besteht jedoch darin, dass --colorPrimary
nicht nur als String gelesen wird. Es gibt Daten!
Mit CSS backdrop-filter
werden ein oder mehrere Effekte auf ein Element angewendet, das durchscheinend oder transparent ist. Die folgenden Bilder veranschaulichen das.

.frosty-glass-pane { backdrop-filter: blur(2px); }

.frosty-glass-pane { opacity: .9; backdrop-filter: blur(2px); }
Das Bild auf der linken Seite zeigt, wie sich überlappende Elemente darstellen würden, wenn backdrop-filter
nicht verwendet oder unterstützt würde. Auf dem Bild rechts wurde mit backdrop-filter
ein Weichzeichnereffekt angewendet. Beachten Sie, dass neben backdrop-filter
auch opacity
verwendet wird. Ohne opacity
gäbe es nichts, auf das die Unkenntlichmachung angewendet werden könnte. Wenn opacity
auf 1
(vollkommen opak) gesetzt ist, hat das natürlich keine Auswirkungen auf den Hintergrund.
Im Gegensatz zum unload
-Ereignis gibt es jedoch legitime Verwendungsmöglichkeiten für beforeunload
. Beispielsweise, wenn Sie den Nutzer warnen möchten, dass seine nicht gespeicherten Änderungen verloren gehen, wenn er die Seite verlässt. In diesem Fall empfehlen wir, beforeunload
-Listener nur hinzuzufügen, wenn ein Nutzer nicht gespeicherte Änderungen hat, und sie dann sofort wieder zu entfernen, nachdem die nicht gespeicherten Änderungen gespeichert wurden.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });
beforeunload
-Listener ohne Bedingungen hinzugefügt.
function beforeUnloadListener(event) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; }; // A function that invokes a callback when the page has unsaved changes. onPageHasUnsavedChanges(() => { window.addEventListener('beforeunload', beforeUnloadListener); }); // A function that invokes a callback when the page's unsaved changes are resolved. onAllChangesSaved(() => { window.removeEventListener('beforeunload', beforeUnloadListener); });
beforeunload
-Listener nur hinzugefügt, wenn er benötigt wird, und entfernt, wenn er nicht benötigt wird.
Nutzung von Cache-Control: no-store
minimieren
Cache-Control: no-store
ist ein HTTP-Header, den Webserver in Antworten festlegen können, um den Browser anzuweisen, die Antwort nicht in einem HTTP-Cache zu speichern. Dieser sollte für Ressourcen verwendet werden, die vertrauliche Nutzerinformationen enthalten, z. B. Seiten, die durch eine Anmeldung geschützt sind.
Das Element fieldset
, das jede Eingabegruppe (.fieldset-item
) enthält, verwendet gap: 1px
, um die Haarstrichränder zwischen den Elementen zu erstellen. Keine komplizierte Lösung für den Rahmen!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
Natürlicher Rasterumbruch
Das komplexeste Layout war das Makro-Layout, das logische Layoutsystem zwischen <main>
und <form>
.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
Das Element fieldset
, das jede Eingabegruppe (.fieldset-item
) enthält, verwendet gap: 1px
, um die Haarstrichränder zwischen den Elementen zu erstellen. Keine komplizierte Lösung für Rahmen!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
<header>
-Layout für Tabs
Das nächste Layout ist fast identisch: Ich verwende Flex, um eine vertikale Anordnung zu erstellen.
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
Das .snap-indicator
sollte horizontal mit der Gruppe von Links wandern. Dieses Kopfzeilenlayout trägt dazu bei, diese Bühne zu schaffen. Hier gibt es keine absolut positionierten Elemente.
„Sanftes Flexen“ ist eine Strategie, bei der nur das Zentrieren im Vordergrund steht. Die Animation ist sanft und dezent, da im Gegensatz zu place-content: center
die Größe der Kinderfelder während der Zentrierung nicht geändert wird. Alle Elemente werden so schonend wie möglich gestapelt, zentriert und platziert.
.gentle-flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1ch;
}
- Nur Ausrichtung, Richtung und Verteilung
- Änderungen und Wartung an einem Ort
- Mit „Gap“ wird ein gleichmäßiger Abstand zwischen n untergeordneten Elementen garantiert.
- Die meisten Codezeilen
Gut geeignet für Makro- und Mikrolayouts.
Nutzung
gap
akzeptiert als Wert jede CSS-Länge oder Prozentzahl.
.gap-example {
display: grid;
gap: 10px;
gap: 2ch;
gap: 5%;
gap: 1em;
gap: 3vmax;
}
Für „Gap“ kann eine Länge von „1“ übergeben werden, die sowohl für Zeilen als auch für Spalten verwendet wird.
.grid { display: grid; gap: 10px; }
.grid { display: grid; row-gap: 10px; column-gap: 10px; }
Für „Lücke“ können zwei Längen übergeben werden, die für Zeile und Spalte verwendet werden.
.grid { display: grid; gap: 10px 5%; }
.grid { display: grid; row-gap: 10px; column-gap: 5%; }