Ein grundlegender Überblick über die Erstellung von farbanpassungsfähigen, responsiv und barrierefrei zugänglichen FAB-Komponenten.
In diesem Beitrag möchte ich meine Gedanken zum Erstellen von farbanpassungsfähigen, reaktionsschnellen und barrierefreien FAB-Komponenten teilen. Probieren Sie die Demo aus und sehen Sie sich den Quellcode an.
Falls du lieber ein Video hast, findest du hier eine YouTube-Version dieses Beitrags:
Überblick
FABs sind auf Mobilgeräten häufiger als auf Computern zu finden, kommen aber in beiden Szenarien vor. Sie behalten die wichtigsten Aktionen im Blick und sind daher praktisch und allgegenwärtig. Dieser Stil wurde durch Material UI bekannt gemacht. Die Vorschläge zur Verwendung und Platzierung finden Sie hier.
Elemente und Stile
Der HTML-Code für diese Steuerelemente umfasst ein Containerelement und eine oder mehrere Schaltflächen. Der Container positioniert die FABs im Darstellungsbereich und verwaltet eine Lücke zwischen den Schaltflächen. Es gibt Mini- oder Standardschaltflächen, die für eine gute Abwechslung zwischen primären und sekundären Aktionen sorgen.
UAS-Container
Dieses Element kann ein reguläres <div>
-Element sein. Wir wollen unseren nicht gesehenen Nutzern aber einen Gefallen tun und es mit nützlichen Attributen kennzeichnen, um den Zweck und den Inhalt dieses Containers zu erläutern.
UAS-Markup
Beginnen Sie mit einer .fabs
-Klasse, in die CSS eingebunden werden kann, um den Stil zu verknüpfen. Fügen Sie dann role="group"
und aria-label
hinzu, damit es nicht nur ein generischer Container ist, sondern auch benannt und zielgerichtet ist.
<div class="fabs" role="group" aria-label="Floating action buttons">
<!-- buttons will go here -->
</div>
FAB-Stil
Damit FABs immer praktisch sind, bleiben sie immer im Darstellungsbereich.
Dies ist ein guter Anwendungsfall für die Position fixed
. Innerhalb dieser Position des Darstellungsbereichs habe ich inset-block
und inset-inline
verwendet, damit die Position den Dokumentmodus des Nutzers ergänzt, z. B. von rechts nach links oder von links nach rechts. Benutzerdefinierte Eigenschaften werden auch verwendet, um Wiederholungen zu vermeiden und für einen gleichmäßigen Abstand von den unteren und seitlichen Rändern des Darstellungsbereichs zu sorgen:
.fabs {
--_viewport-margin: 2.5vmin;
position: fixed;
z-index: var(--layer-1);
inset-block: auto var(--_viewport-margin);
inset-inline: auto var(--_viewport-margin);
}
Als Nächstes gebe ich dem Containerdisplay flex
an und ändere die Layoutrichtung in column-reverse
.
Dadurch werden die untergeordneten Elemente übereinander (Spalte) gestapelt und auch ihre visuelle Reihenfolge umgekehrt. Dadurch wird das erste fokussierbare Element zum unteren und nicht zum oberen Element, wo der Fokus normalerweise im HTML-Dokument liegt. Durch das Umkehren der visuellen Reihenfolge wird das Erlebnis für sehende Nutzer und Tastaturnutzer vereinigt, da sehende Nutzer erkennen können, dass es sich um eine primäre Aktion handelt.
.fabs {
…
display: flex;
flex-direction: column-reverse;
place-items: center;
gap: var(--_viewport-margin);
}
Die Zentrierung erfolgt mit place-items
und gap
fügt Platz zwischen den im Container platzierten UAS-Schaltflächen hinzu.
UAS-Schaltflächen
Zeit, einige Schaltflächen so zu gestalten, dass sie so aussehen, als würden sie über alles schwebend aussehen.
Standard-FAB
Die erste zu formatierende Schaltfläche ist die Standardschaltfläche. Diese dient als Grundlage für alle FAB-Schaltflächen. Später erstellen wir eine Variante, die eine alternative Darstellung erzielt und dabei so wenig dieser Basisstile wie möglich anpasst.
UAS-Markup
Das <button>
-Element ist die richtige Wahl. Wir beginnen damit, weil es eine hervorragende
User Experience bietet, z. B. mit Maus, Touch und Tastatur. Am wichtigsten bei diesem Markup ist es, das Symbol für Nutzer von Screenreadern mit aria-hidden="true"
auszublenden und den erforderlichen Labeltext zum <button>
-Markup selbst hinzuzufügen. Wenn ich in diesen Fällen Labels hinzufüge, füge ich auch gerne title
hinzu, damit Mausnutzer Informationen darüber erhalten können, was das Symbol kommunizieren soll.
<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
UAS-Stil
Wandeln wir die Schaltfläche zuerst in eine gepolsterte runde Schaltfläche mit einem starken Schatten um, da dies die ersten Elemente der Schaltfläche sind:
.fab {
--_size: 2rem;
padding: calc(var(--_size) / 2);
border-radius: var(--radius-round);
aspect-ratio: 1;
box-shadow: var(--shadow-4);
}
Als Nächstes fügen wir Farbe hinzu. Wir verwenden eine Strategie, die wir bereits bei GUI-Herausforderungen genutzt haben. Erstellen Sie einen klar benannten Satz benutzerdefinierter Eigenschaften, die statisch die hellen und dunklen Farben enthalten, und dann eine adaptive benutzerdefinierte Eigenschaft, für die je nach Systempräferenz des Nutzers für Farben entweder die hellen oder die dunklen Variablen festgelegt werden:
.fab {
…
/* light button and button hover */
--_light-bg: var(--pink-6);
--_light-bg-hover: var(--pink-7);
/* dark button and button hover */
--_dark-bg: var(--pink-4);
--_dark-bg-hover: var(--pink-3);
/* adaptive variables set to light by default */
--_bg: var(--_light-bg);
/* static icon colors set to the adaptive foreground variable */
--_light-fg: white;
--_dark-fg: black;
--_fg: var(--_light-fg);
/* use the adaptive properties on some styles */
background: var(--_bg);
color: var(--_fg);
&:is(:active, :hover, :focus-visible) {
--_bg: var(--_light-bg-hover);
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg-hover);
}
}
/* if users prefers dark, set adaptive props to dark */
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg);
--_fg: var(--_dark-fg);
}
}
Als Nächstes fügen Sie einige Stile hinzu, damit die SVG-Symbole in den Raum passen.
.fab {
…
& > svg {
inline-size: var(--_size);
block-size: var(--_size);
stroke-width: 3px;
}
}
Entfernen Sie zuletzt die Markierung beim Tippen aus der Schaltfläche, da wir eigenes visuelles Feedback für die Interaktion hinzugefügt haben:
.fab {
-webkit-tap-highlight-color: transparent;
}
Mini-FAB
In diesem Bereich soll eine Variante für die UAS-Schaltfläche erstellt werden. Indem wir einige der FABs kleiner als die Standardaktion machen, können wir die Aktion fördern, die der Nutzer am häufigsten ausführt.
Mini-UAS-Markup
Der HTML-Code ist mit einem FAB identisch. Wir fügen jedoch eine „.mini“-Klasse hinzu, um CSS einen Hook für die Variante zu geben.
<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
Mini-FAB-Stil
Dank benutzerdefinierter Eigenschaften muss nur die Variable --_size
angepasst werden.
.fab.mini {
--_size: 1.25rem;
}
Barrierefreiheit
Der wichtigste Aspekt für die Barrierefreiheit bei FABs ist die Platzierung im Tastaturablauf der Seite. In dieser Demo werden nur die FABs verwendet. Es gibt nichts, mit dem in Bezug auf Tastaturreihenfolge und -ablauf konkurriert wird, was bedeutet, dass keine Gelegenheit besteht, einen sinnvollen Tastaturablauf zu zeigen. In einem Szenario, in dem es konkurrierende Elemente gibt, sollte ich gründlich überlegen, an welcher Stelle in diesem Ablauf ein Nutzer in den FAB-Schaltflächenablauf eintreten sollte.
Sobald sich der Nutzer auf den FAB-Container konzentriert hat, haben wir role="group"
und aria-label="floating action buttons"
hinzugefügt, um Nutzer von Screenreadern über die Inhalte zu informieren, auf die sie sich konzentrieren. Ich habe den Standard-FAB strategisch an erster Stelle
platziert, damit Nutzende die primäre Aktion zuerst finden. Anschließend verwende ich flex-direction: column-reverse;
, um die primäre Schaltfläche unten optisch in der Nähe der Finger der Nutzer zu ordnen, um den Zugriff zu erleichtern. Das ist ein netter Vorteil, da die Standardschaltfläche optisch hervorgehoben und für Tastaturnutzer an erster Stelle steht, sodass sie sich sehr ähnlich sehen.
Vergessen Sie nicht, Ihre Symbole vor Screenreader-Nutzern zu verbergen und ihnen ein Label für die Schaltfläche zu geben, damit dies kein Geheimnis bleibt. Dies wurde im HTML-Code bereits mit aria-hidden="true"
bei den <svg>
und aria-label="Some action"
bei den <button>
-Elementen durchgeführt.
Animation
Es können verschiedene Arten von Animationen hinzugefügt werden, um die User Experience zu verbessern. Wie bei anderen GUI-Herausforderungen werden auch hier einige benutzerdefinierte Eigenschaften eingerichtet, die sowohl eine reduzierte als auch eine vollständige Bewegungserfahrung enthalten. Standardmäßig wird bei den Stilen davon ausgegangen, dass der Nutzer eine reduzierte Bewegung wünscht. Mit der prefers-reduced-motion
-Medienabfrage wird der Übergangswert dann in eine vollständige Bewegung geändert.
Strategie mit reduzierten Bewegungen mit benutzerdefinierten Eigenschaften
Im folgenden CSS werden drei benutzerdefinierte Eigenschaften erstellt: --_motion-reduced
, --_motion-ok
und --_transition
. Für die ersten beiden gelten je nach Nutzereinstellung geeignete Übergänge. Die letzte Variable --_transition
wird auf --_motion-reduced
bzw. --_motion-ok
gesetzt.
.fab {
/* box-shadow and background-color can safely be transitioned for reduced motion users */
--_motion-reduced:
box-shadow .2s var(--ease-3),
background-color .3s var(--ease-3);
/* add transform and outline-offset for users ok with motion */
--_motion-ok:
var(--_motion-reduced),
transform .2s var(--ease-3),
outline-offset 145ms var(--ease-2);
/* default the transition styles to reduced motion */
--_transition: var(--_motion-reduced);
/* set the transition to our adaptive transition custom property*/
transition: var(--_transition);
/* if motion is ok, update the adaptive prop to the respective transition prop */
@media (prefers-reduced-motion: no-preference) {
--_transition: var(--_motion-ok);
}
}
Mit den oben genannten Änderungen können Änderungen an box-shadow
, background-color
, transform
und outline-offset
umgestellt werden. So erhält der Nutzer positives Feedback auf der Benutzeroberfläche, dass die Interaktion eingegangen ist.
Als Nächstes verleihen Sie dem :active
-Status ein wenig mehr Flair. Passen Sie dafür translateY
ein wenig an. So wirkt die Schaltfläche positiv:
.fab {
…
&:active {
@media (prefers-reduced-motion: no-preference) {
transform: translateY(2%);
}
}
}
Abschließend müssen Sie alle Änderungen an den SVG-Symbolen in den Schaltflächen vornehmen:
.fab {
…
&[data-icon="plus"]:hover > svg {
transform: rotateZ(.25turn);
}
& > svg {
@media (prefers-reduced-motion: no-preference) {
will-change: transform;
transition: transform .5s var(--ease-squish-3);
}
}
}
Fazit
Jetzt weißt du, wie ich es gemacht habe. Wie würdest du es erreichen? 🙂
Diversifizieren wir unsere Ansätze und lernen Sie alle Möglichkeiten kennen, wie wir das Web nutzen können.
Erstelle eine Demo und twittere mich über Links, und ich füge sie unten zum Abschnitt über Community-Remixe hinzu.
Community-Remixe
Hier gibt es noch nichts zu sehen.
Ressourcen
- Quellcode auf GitHub