Ein grundlegender Überblick über das Erstellen einer adaptiven und barrierefreien Toast-Komponente.
In diesem Beitrag möchte ich erklären, wie man eine Toast-Komponente erstellt. Testen Sie die Demo ansehen.
<ph type="x-smartling-placeholder">Falls Sie Videos bevorzugen, finden Sie hier eine YouTube-Version dieses Beitrags:
Übersicht
Toasts sind nicht interaktive, passive und asynchrone Kurznachrichten für Nutzer. In der Regel werden sie als Oberflächen-Feedback-Muster verwendet, um die Nutzenden zu informieren. zu den Ergebnissen einer Aktion.
Interaktionen
Toasts unterscheiden sich von Benachrichtigungen, Benachrichtigungen und Aufforderungen, sie sind nicht interaktiv; dass sie nicht geschlossen werden sollen. Benachrichtigungen sind für wichtigere Informationen, synchrone Nachrichten, erfordert Interaktionen oder Mitteilungen auf Systemebene (im Gegensatz zu Meldungen auf Seitenebene). Toasts sind passiver als andere Benachrichtigungsstrategien.
Markup
Die
<output>
-Element ist eine gute Wahl für den Toast, da es dem Bildschirm vorgelesen wird.
Lesern. Korrekter HTML-Code bietet uns eine sichere Basis für die Optimierung mit JavaScript und
und es wird viel JavaScript geben.
Ein Toast
<output class="gui-toast">Item added to cart</output>
Es kann mehr
inklusive
indem Sie role="status"
hinzufügen. Dies bietet eine
ein Fallback, falls der Browser <output>
-Elementen nicht die implizite
Rolle
gemäß der Spezifikation.
<output role="status" class="gui-toast">Item added to cart</output>
Ein Toast-Container
Es können mehrere Toasts gleichzeitig angezeigt werden. Um mehrere Toasts enthält, wird ein Container verwendet. Dieser Container verarbeitet auch die Position des Toasts auf dem Bildschirm.
<section class="gui-toast-group">
<output role="status">Wizard Rose added to cart</output>
<output role="status">Self Watering Pot added to cart</output>
</section>
Layouts
habe ich Toasts an die
inset-block-end
des Darstellungsbereichs entfernt. Wenn weitere Toasts hinzugefügt werden, werden sie über diesen Bildschirmrand gestapelt.
GUI-Container
Der Toast-Container übernimmt das gesamte Layout für die Präsentation von Toasts. Es ist
fixed
zum Darstellungsbereich und verwendet das logische Attribut
Mit inset
geben Sie an,
Kanten zum Anpinnen sowie ein wenig padding
von derselben Seite block-end
.
.gui-toast-group {
position: fixed;
z-index: 1;
inset-block-end: 0;
inset-inline: 0;
padding-block-end: 5vh;
}
Der Toast-Container positioniert sich nicht nur innerhalb des Darstellungsbereichs, sondern ist auch ein
Rasterbehälter, mit dem Toasts ausgerichtet und verteilt werden können. Elemente werden als
Gruppe mit justify-content
und individuell zentriert mit justify-items
.
Geben Sie gap
ein, damit Toasts nicht anfassen.
.gui-toast-group {
display: grid;
justify-items: center;
justify-content: center;
gap: 1vh;
}
Toast auf der Benutzeroberfläche
Ein einzelner Toast hat padding
, einige weichere Ecken mit
border-radius
,
und eine min()
-Funktion,
bei der Größenanpassung für Mobilgeräte und Desktop-Computer. Die responsive Größe im folgenden CSS-Code
verhindert, dass Toasts mehr als 90% des Darstellungsbereichs ausdehnen
25ch
.gui-toast {
max-inline-size: min(25ch, 90vw);
padding-block: .5ch;
padding-inline: 1ch;
border-radius: 3px;
font-size: 1rem;
}
Stile
Wenn Sie Layout und Positionierung festgelegt haben, können Sie CSS-Code hinzufügen, der die Anpassung an den Nutzer erleichtert. Einstellungen und Interaktionen.
Toast-Container
Toasts sind nicht interaktiv, das Antippen oder Wischen verarbeiten jedoch aktuell Zeigerereignisse. Verhindern, dass Toasts gestohlen werden mit folgendem CSS-Code erstellen:
.gui-toast-group {
pointer-events: none;
}
Toast auf der Benutzeroberfläche
Verleihe den Toasts mit benutzerdefinierten Eigenschaften, HSL und bevorzugte Medienabfrage.
.gui-toast {
--_bg-lightness: 90%;
color: black;
background: hsl(0 0% var(--_bg-lightness) / 90%);
}
@media (prefers-color-scheme: dark) {
.gui-toast {
color: white;
--_bg-lightness: 20%;
}
}
Animation
Ein neuer Toast sollte mit einer Animation angezeigt werden, sobald er auf dem Bildschirm erscheint.
Um reduzierte Bewegungen zu berücksichtigen, setzen Sie translate
-Werte auf 0
, indem Sie
Standardeinstellung. Der Bewegungswert wird jedoch auf eine Länge in einem Medien mit Bewegungspräferenz aktualisiert.
Suchanfrage . Alle werden Animationen gezeigt, aber nur ein paar Nutzer sehen die Reise
Entfernung.
Dies sind die Keyframes, die für die Toast-Animation verwendet werden. Das Preisvergleichsportal steuert die Eingang, Warten und Ausgang des Toasts in einer Animation.
@keyframes fade-in {
from { opacity: 0 }
}
@keyframes fade-out {
to { opacity: 0 }
}
@keyframes slide-in {
from { transform: translateY(var(--_travel-distance, 10px)) }
}
Das Toast-Element richtet dann die Variablen ein und orchestriert die Keyframes.
.gui-toast {
--_duration: 3s;
--_travel-distance: 0;
will-change: transform;
animation:
fade-in .3s ease,
slide-in .3s ease,
fade-out .3s ease var(--_duration);
}
@media (prefers-reduced-motion: no-preference) {
.gui-toast {
--_travel-distance: 5vh;
}
}
JavaScript
Wenn die Stile und den Screenreader für den barrierefreien HTML-Code bereit sind, ist JavaScript erforderlich, das Erstellen, Hinzufügen und Vernichten von Toasts nutzungsbasiert orchestrieren Ereignisse. Die Toast-Komponente sollte für Entwickler nur minimal und ganz einfach:
import Toast from './toast.js'
Toast('My first toast')
Toastgruppe und Toasts erstellen
Wenn das Toast-Modul aus JavaScript geladen wird, muss ein Toast-Container erstellt werden
und fügen es der Seite hinzu. Ich habe das Element vor body
hinzugefügt. Dadurch wird
Es ist unwahrscheinlich, dass z-index
Stapelprobleme auftreten, da sich der Container für längere Zeit über dem Container befindet.
alle body-Elemente.
const init = () => {
const node = document.createElement('section')
node.classList.add('gui-toast-group')
document.firstElementChild.insertBefore(node, document.body)
return node
}
Die Funktion init()
wird intern im Modul aufgerufen, wodurch das Element
als Toaster
:
const Toaster = init()
Das Pop-up-HTML-Element wird mit der Funktion createToast()
erstellt. Die
Funktion benötigt Text für den Toast, erstellt ein <output>
-Element, verziert
mit einigen Klassen und Attributen, legt den Text fest und gibt den Knoten zurück.
const createToast = text => {
const node = document.createElement('output')
node.innerText = text
node.classList.add('gui-toast')
node.setAttribute('role', 'status')
return node
}
Einen oder mehrere Toasts verwalten
JavaScript fügt dem Dokument jetzt einen Container für Toasts hinzu.
Toasts hinzugefügt. Die Funktion addToast()
orchestriert die Verarbeitung
oder viele Toasts. Überprüfen Sie zunächst die Anzahl der Toasts und ob die Bewegung in Ordnung ist.
Dann können Sie mit diesen Informationen
den Toast anhängen
Animation, sodass die anderen Toasts wie „Raum schaffen“ erscheinen auf den neuen Toast.
const addToast = toast => {
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Toaster.children.length && motionOK
? flipToast(toast)
: Toaster.appendChild(toast)
}
Beim ersten Toast fügt Toaster.appendChild(toast)
einen Toast zum
Seite, die die CSS-Animationen auslöst: "animieren", "3s
" oder "animieren".
flipToast()
wird aufgerufen, wenn Toasts vorhanden sind. Dabei wird eine Technik verwendet,
namens FLIP von Paul
Lewis. Die Idee ist, die Differenz
an den Positionen des Containers, also vor und nach dem Hinzufügen des neuen Toasts.
Stellen Sie sich das vor, als würden Sie
aufzeichnen, wo der Toaster ist,
von der ursprünglichen
bis zur tatsächlichen Position.
const flipToast = toast => {
// FIRST
const first = Toaster.offsetHeight
// add new child to change container size
Toaster.appendChild(toast)
// LAST
const last = Toaster.offsetHeight
// INVERT
const invert = last - first
// PLAY
const animation = Toaster.animate([
{ transform: `translateY(${invert}px)` },
{ transform: 'translateY(0)' }
], {
duration: 150,
easing: 'ease-out',
})
}
CSS-Raster übernimmt das Heben des Layouts. Wenn ein neuer Toast hinzugefügt wird, platziert das Raster ihn am Anfang und platziert ihn an den anderen. Hinzu kommt, dass ein Web Animation ist zur Animation des Containers von der alten Position aus.
Zusammenführen des gesamten JavaScript-Codes
Beim Aufruf von Toast('my first toast')
wird ein Toast erstellt und der Seite hinzugefügt
(vielleicht ist sogar der Behälter animiert, um den neuen Toast unterzubringen), ein
versprechen
zurückgegeben und der erstellte Toast
angesehen für
Vervollständigung der CSS-Animation (die drei Keyframe-Animationen) für die Promise-Auflösung
const Toast = text => {
let toast = createToast(text)
addToast(toast)
return new Promise(async (resolve, reject) => {
await Promise.allSettled(
toast.getAnimations().map(animation =>
animation.finished
)
)
Toaster.removeChild(toast)
resolve()
})
}
Der verwirrende Teil dieses Codes ist die Funktion Promise.allSettled()
.
und toast.getAnimations()
-Zuordnung. Da ich mehrere Keyframe-Animationen
um sicher zu wissen, dass alle fertig sind,
die von JavaScript angefordert werden,
finished
für die Erfüllung zu halten.
allSettled
macht das für uns funktioniert und löst sich als vollständig auf, sobald all seine Versprechen verfügbar sind.
erfüllt wurden. Bei Verwendung von await Promise.allSettled()
wird die nächste Zeile
das Element problemlos entfernen und davon ausgehen kann, dass der Toast
Lebenszyklus. Schließlich erfüllt der Anruf von resolve()
das übergeordnete Toast-Versprechen.
können Entwickler den Inhalt bereinigen oder andere Dinge erledigen, sobald der Toast angezeigt wurde.
export default Toast
Schließlich wird die Funktion Toast
aus dem Modul exportiert, damit andere Skripts
Daten importieren und verwenden.
Toast-Komponente verwenden
Um den Toast oder die Entwicklererfahrung des Toasts zu verwenden, importieren Sie den
Toast
und ruft sie mit einem Nachrichtenstring auf.
import Toast from './toast.js'
Toast('Wizard Rose added to cart')
Wenn die Entwicklerin oder der Entwickler etwas sauberer machen möchte, nachdem angezeigt wird, können sie asynchrone Warten.
import Toast from './toast.js'
async function example() {
await Toast('Wizard Rose added to cart')
console.log('toast finished')
}
Fazit
Jetzt, wo du weißt, wie ich es gemacht habe, wie würdest du... ‽ 🙂
Lassen Sie uns unsere Herangehensweisen diversifizieren und alle Möglichkeiten kennenlernen, wie wir das Web entwickeln können. Erstelle eine Demo, twittere mir Links und ich füge sie hinzu im Abschnitt „Community-Remixe“ weiter unten.
Community-Remixe
- @_developit mit HTML/CSS/JS: Demo und Code
- Joost van der Schee mit HTML/CSS/JS: Demo und Code