Eine grundlegende Übersicht zum Erstellen von farbadaptiven, responsiven und barrierefreien FAB-Komponenten.
In diesem Beitrag möchte ich meine Gedanken dazu teilen, wie Sie farbadaptiv, responsiv und barrierefrei nutzbare FAB-Komponenten erstellen. Demo ansehen und den Quellcode ansehen
Wenn du lieber ein Video ansiehst, findest du hier eine YouTube-Version dieses Beitrags:
Übersicht
FABs sind auf Mobilgeräten häufiger als auf Computern, aber in beiden Fällen weit verbreitet. Sie behalten die primären Aktionen im Blick und machen sie praktisch und allgegenwärtig. Dieser User-Experience-Stil wurde durch Material UI bekannt. Hier finden Sie Vorschläge zur Verwendung und Platzierung.
Elemente und Stile
Das HTML für diese Steuerelemente besteht aus einem Containerelement und einer oder mehreren Schaltflächen. Der Container platziert die FABs im Darstellungsbereich und sorgt für einen Abstand zwischen den Schaltflächen. Die Schaltflächen können klein oder standardmäßig sein, was eine Abwechslung zwischen primären und sekundären Aktionen bietet.
UAS-Container
Bei diesem Element kann es sich um ein reguläres <div>
handeln. Wir möchten unseren unbewussten Nutzern aber einen Gefallen tun und es mit einigen nützlichen Attributen kennzeichnen, die den Zweck und Inhalt dieses Containers erklären.
Markup für UAs
Beginnen Sie mit einer .fabs
-Klasse, an die CSS angehängt werden kann, um den Stil zu erreichen. Fügen Sie dann role="group"
und aria-label
hinzu, damit es nicht nur ein generischer Container ist, sondern benannt und zielgerichtet ist.
<div class="fabs" role="group" aria-label="Floating action buttons">
<!-- buttons will go here -->
</div>
Stil von UAs
Damit sie praktisch sind, bleiben sie immer im Darstellungsbereich.
Das ist ein guter Anwendungsfall für die Position fixed
. Für diese Viewport-Position habe ich inset-block
und inset-inline
verwendet, damit die Position dem Dokumentmodus des Nutzers entspricht, z. B. von rechts nach links oder von links nach rechts. Benutzerdefinierte Eigenschaften werden auch verwendet, um Wiederholungen zu verhindern und dafür zu sorgen, dass der Abstand vom unteren und seitlichen Rand des Darstellungsbereichs gleich ist:
.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 Container-Display flex
zu und ändere seine Layoutrichtung in column-reverse
.
Dadurch werden die untergeordneten Elemente übereinander gestapelt (Spalte) und auch ihre visuelle Reihenfolge wird umgekehrt. Dadurch wird das erste fokussierbare Element zum untersten Element statt zum obersten Element, wo der Fokus normalerweise gemäß dem HTML-Dokument liegt. Durch die Umkehrung der visuellen Reihenfolge wird die Nutzung für sehbehinderte Nutzer und Nutzer mit Tastatur vereinfacht. Die primäre Aktion ist größer als die Minischaltflächen, was sehenden Nutzern signalisiert, dass es sich um eine primäre Aktion handelt. Nutzer mit Tastatur sehen sie als ersten Punkt in der Quelle.
.fabs {
…
display: flex;
flex-direction: column-reverse;
place-items: center;
gap: var(--_viewport-margin);
}
Mit place-items
wird das Zentrieren gesteuert und mit gap
wird der Abstand zwischen den FAB-Schaltflächen im Container vergrößert.
UAS-Schaltflächen
Jetzt ist es an der Zeit, einige Schaltflächen so zu gestalten, dass sie über allem schweben.
Standard-FAB
Die erste Schaltfläche, die Sie stylen, ist die Standardschaltfläche. Dieser dient als Grundlage für alle FAB-Schaltflächen. Später erstellen wir eine Variante, die ein alternatives Erscheinungsbild hat, bei der aber möglichst wenig an diesen Basisstilen geändert wird.
Markup für die schwebende Ansicht
Das <button>
-Element ist die richtige Wahl. Wir beginnen mit diesem Design, da es eine hervorragende Nutzererfahrung mit Maus, Touchbedienung und Tastatur bietet. Der wichtigste Aspekt dieses Markups ist, das Symbol mit aria-hidden="true"
für Nutzer von Screenreadern auszublenden und den erforderlichen Labeltext zum <button>
-Markup selbst hinzuzufügen. Wenn ich in diesen Fällen Labels hinzufüge, füge ich auch ein title
hinzu, damit Nutzer mit Maus Informationen dazu erhalten, was das Symbol ausdrücken 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
Zuerst wandeln wir die Schaltfläche in eine abgesetzte runde Schaltfläche mit starkem Schatten um, da dies die ersten definierenden Merkmale 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 in GUI-Herausforderungen verwendet haben. Erstellen Sie einen klar benannten Satz von benutzerdefinierten Eigenschaften, die statisch die hellen und dunklen Farben enthalten, und dann eine adaptive benutzerdefinierte Eigenschaft, die je nach Systemeinstellung des Nutzers für Farben entweder auf die hellen oder die dunklen Variablen festgelegt wird:
.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);
}
}
Fügen Sie als Nächstes einige Stile hinzu, damit die SVG-Symbole in den Bereich passen.
.fab {
…
& > svg {
inline-size: var(--_size);
block-size: var(--_size);
stroke-width: 3px;
}
}
Entfernen Sie zuletzt die Markierung für das Tippen auf die Schaltfläche, da wir eigenes visuelles Feedback für die Interaktion hinzugefügt haben:
.fab {
-webkit-tap-highlight-color: transparent;
}
Mini FAB
In diesem Abschnitt soll eine Variante für die UAS-Schaltfläche erstellt werden. Indem wir einige der FABs kleiner als die Standardaktion gestalten, können wir die Aktion bewerben, die der Nutzer am häufigsten ausführt.
Mini-FAB-Markup
Der HTML-Code ist mit dem einer FAB identisch, wir fügen jedoch die Klasse „.mini“ hinzu, um CSS eine Verknüpfung mit der 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-Floating Action Button
Da benutzerdefinierte Attribute verwendet werden, ist nur eine Anpassung der Variable --_size
erforderlich.
.fab.mini {
--_size: 1.25rem;
}
Bedienungshilfen
Das Wichtigste für die Barrierefreiheit bei FABs ist die Platzierung im Tastaturfluss der Seite. Diese Demo enthält nur die FABs. Es gibt also keine Möglichkeit, die Reihenfolge und den Ablauf der Tastatur zu demonstrieren. In einem Szenario, in dem es konkurrierende Elemente gibt, die den Fokus auf sich ziehen, sollten Sie sich genau überlegen, wo sich ein Nutzer in diesem Ablauf befindet, wenn er die FAB-Schaltfläche betätigt.
Sobald der Nutzer den Fokus auf den FAB-Container gelegt hat, werden role="group"
und aria-label="floating action buttons"
angezeigt, die Screenreader-Nutzer über den Inhalt des fokussierten Elements informieren. Aus strategischen Gründen habe ich das standardmäßige FAB an erste Stelle gesetzt, damit Nutzer die primäre Aktion zuerst sehen. Anschließend verwende ich flex-direction: column-reverse;
, um die primäre Schaltfläche unten visuell anzuordnen, nah bei den Fingern des Nutzers, um den Zugriff zu erleichtern. Das ist ein großer Vorteil, da die Standardschaltfläche visuell auffällig ist und auch von Tastaturnutzern als Erstes verwendet wird, um eine sehr ähnliche Nutzererfahrung zu bieten.
Denken Sie auch daran, Ihre Symbole für Nutzer von Screenreadern auszublenden und ihnen ein Label für die Schaltfläche zur Verfügung zu stellen, damit sie nicht im Dunkeln tappen. Dies wurde im HTML-Code bereits mit aria-hidden="true"
für <svg>
und aria-label="Some action"
in den <button>
s vorgenommen.
Animation
Verschiedene Animationsarten können hinzugefügt werden, um die User Experience zu verbessern. Wie bei anderen GUI-Herausforderungen richten wir einige benutzerdefinierte Properties ein, um die Absicht einer reduzierten und einer vollständigen Bewegung zu wahren. Standardmäßig gehen die Stile davon aus, dass der Nutzer eine reduzierte Bewegung wünscht. Mit der prefers-reduced-motion
-Medienabfrage wird dann der Übergangswert in „Vollständige Bewegung“ geändert.
Eine Strategie mit reduzierter Bewegung und benutzerdefinierten Properties
Im folgenden CSS werden drei benutzerdefinierte Properties erstellt: --_motion-reduced
, --_motion-ok
und --_transition
. Die ersten beiden führen je nach Nutzereinstellung geeignete Übergänge und die letzte Variable --_transition
wird entweder auf --_motion-reduced
oder --_motion-ok
festgelegt.
.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);
}
}
Wenn Sie die oben genannten Schritte ausgeführt haben, können Sie Änderungen an box-shadow
, background-color
, transform
und outline-offset
vornehmen. So erhalten die Nutzer ein ansprechendes UI-Feedback, dass ihre Interaktion erkannt wurde.
Geben Sie dem Status :active
etwas mehr Flair, indem Sie translateY
ein wenig anpassen. Dadurch erhält die Schaltfläche einen schönen gedrückten Effekt:
.fab {
…
&:active {
@media (prefers-reduced-motion: no-preference) {
transform: translateY(2%);
}
}
}
Nehmen Sie abschließend alle Änderungen an den SVG-Symbolen in den Schaltflächen vor:
.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
Wie würden Sie es machen?
Lassen Sie uns unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, wie Sie im Web entwickeln können.
Erstelle eine Demo, tweete mir Links und ich füge sie unten in den Abschnitt „Community-Remixe“ hinzu.
Remixe der Community
Hier gibt es noch nichts zu sehen.
Ressourcen
- Quellcode auf GitHub