Eine grundlegende Übersicht darüber, wie Sie farbadaptive, responsive und barrierefreie FAB-Komponenten erstellen.
In diesem Beitrag möchte ich meine Gedanken dazu teilen, wie man farbadaptive, responsive und barrierefreie FAB-Komponenten erstellt. Demo ansehen und Quellcode ansehen.
Wenn du lieber ein Video ansehen möchtest, 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 primäre Aktionen im Blick und machen sie bequem und omnipräsent. Dieser Stil wurde durch Material UI bekannt. Hier finden Sie Vorschläge zur Verwendung und Platzierung.
Elemente und Stile
Der HTML-Code für diese Steuerelemente umfasst ein Containerelement und eine Reihe von einem oder mehreren Schaltflächen. Der Container positioniert die FABs im Darstellungsbereich und verwaltet einen Abstand zwischen den Schaltflächen. Die Schaltflächen können klein oder standardmäßig sein, was für eine gute Abwechslung zwischen primären und sekundären Aktionen sorgt.
UAS-Container
Dieses Element kann ein reguläres <div> sein. Wir möchten aber sehbehinderten Nutzern einen Gefallen tun und es mit einigen hilfreichen Attributen versehen, um den Zweck und den Inhalt dieses Containers zu erklären.
Markup für Floating Action Buttons
Beginnen Sie mit der Klasse .fabs für CSS, um den Stil festzulegen. Fügen Sie dann role="group" und aria-label hinzu, damit es sich nicht nur um einen generischen Container handelt, sondern um einen benannten Container mit einem bestimmten Zweck.
<div class="fabs" role="group" aria-label="Floating action buttons">
<!-- buttons will go here -->
</div>
Stil von UAS
Damit FABs praktisch sind, bleiben sie immer im Darstellungsbereich.
Dies ist ein hervorragender Anwendungsfall für die Position fixed. Für diese Viewport-Position habe ich inset-block und inset-inline verwendet, damit die Position zum Dokumentmodus des Nutzers passt, z. B. von rechts nach links oder von links nach rechts. Benutzerdefinierte Eigenschaften werden auch verwendet, um Wiederholungen zu vermeiden und einen gleichen Abstand von den unteren und seitlichen Rändern des Viewports zu gewährleisten:
.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 die Anzeige flex und ändere die Layoutrichtung in column-reverse.
Dadurch werden die untergeordneten Elemente übereinander (Spalte) gestapelt und ihre visuelle Reihenfolge wird umgekehrt. Dadurch wird das erste fokussierbare Element zum unteren Element anstelle des oberen, auf das der Fokus normalerweise gemäß dem HTML-Dokument springen würde. Durch die Umkehrung der visuellen Reihenfolge wird die Nutzerfreundlichkeit für Nutzer mit Sehbehinderung und Tastaturnutzer verbessert. Die primäre Aktion wird größer als die Minischaltflächen dargestellt, sodass Nutzer mit Sehbehinderung erkennen, dass es sich um eine primäre Aktion handelt. Tastaturnutzer können sie als erstes Element in der Quelle fokussieren.

.fabs {
…
display: flex;
flex-direction: column-reverse;
place-items: center;
gap: var(--_viewport-margin);
}
Die Zentrierung erfolgt mit place-items und gap fügt Leerraum zwischen den FAB-Schaltflächen im Container ein.
UAS-Schaltflächen
Jetzt ist es an der Zeit, einige Schaltflächen so zu gestalten, dass sie über allem zu schweben scheinen.
Standard-FAB
Die erste Schaltfläche, die Sie gestalten, ist die Standardschaltfläche. Dies dient als Grundlage für alle FAB-Schaltflächen. Später erstellen wir eine Variante, die ein alternatives Erscheinungsbild bietet, wobei wir so wenig wie möglich von diesen Basisstilen ändern.
UAS-Markup
Das <button>-Element ist die richtige Wahl. Wir beginnen damit, da es eine hervorragende Nutzerfreundlichkeit für Maus, Touch und Tastatur bietet. Der wichtigste Aspekt dieses Markups ist, das Symbol mit aria-hidden="true" vor Screenreader-Nutzern zu verbergen und den erforderlichen Labeltext dem <button>-Markup hinzuzufügen. Wenn ich in diesen Fällen Labels hinzufüge, füge ich auch gerne ein title hinzu, damit Mausnutzer Informationen dazu erhalten, was das Symbol vermitteln 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 machen wir aus der Schaltfläche eine gepolsterte runde Schaltfläche mit einem starken Schatten, 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 schon bei früheren GUI-Herausforderungen eingesetzt haben. Erstellen Sie einen Satz benutzerdefinierter Eigenschaften mit eindeutigen Namen, die statisch die hellen und dunklen Farben enthalten, sowie 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 Tippmarkierung von der Schaltfläche, da wir ein eigenes visuelles Feedback für die Interaktion hinzugefügt haben:
.fab {
-webkit-tap-highlight-color: transparent;
}
Mini-FAB
In diesem Abschnitt erstellen Sie eine Variante für die FAB-Schaltfläche. Wenn wir einige der schwebenden Aktionsschaltflächen kleiner als die Standardaktion gestalten, können wir die Aktion hervorheben, die der Nutzer am häufigsten ausführt.
Markup für Mini-FABs
Der HTML-Code ist derselbe wie bei einem schwebenden Aktionsschaltfläche, aber wir fügen 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-UAS-Stil
Da benutzerdefinierte Eigenschaften verwendet werden, muss nur die Variable --_size angepasst werden.
.fab.mini {
--_size: 1.25rem;
}

Bedienungshilfen
Für die Barrierefreiheit von FABs ist vor allem die Platzierung im Tastaturfluss der Seite wichtig. In dieser Demo gibt es nur die schwebenden Aktionsschaltflächen. Es gibt nichts, was in Bezug auf die Tastaturreihenfolge und den Tastaturfluss konkurrieren könnte. Daher kann kein sinnvoller Tastaturfluss demonstriert werden. Wenn es konkurrierende Elemente für den Fokus gibt, sollten Sie sich genau überlegen, an welcher Stelle im Ablauf ein Nutzer in den FAB-Button-Ablauf eintreten sollte.
Sobald der Nutzer den FAB-Container fokussiert hat, haben wir bereits role="group" und aria-label="floating action buttons" hinzugefügt, die Screenreader-Nutzer über den Inhalt des fokussierten Elements informieren. Strategisch habe ich die Standard-Schaltfläche „Aktion“ zuerst platziert, damit Nutzer die primäre Aktion zuerst finden. Ich verwende dann flex-direction: column-reverse;, um die primäre Schaltfläche unten zu platzieren, damit sie für Nutzer leicht erreichbar ist. Das ist ein großer Vorteil, da die Standardschaltfläche visuell auffällig und auch für Tastaturnutzer die erste Option ist.
Vergessen Sie nicht, Ihre Symbole für Screenreader-Nutzer auszublenden und der Schaltfläche ein Label hinzuzufügen, damit sie nicht rätselhaft ist. Das wurde bereits im HTML-Code mit aria-hidden="true" für die <svg> und aria-label="Some action" für die <button>s erledigt.
Animation
Es gibt verschiedene Arten von Animationen, die die Nutzerfreundlichkeit verbessern können. Wie bei anderen GUI-Challenges richten wir einige benutzerdefinierte Eigenschaften ein, um die Intention einer reduzierten und einer vollständigen Bewegung zu erfassen. Standardmäßig wird davon ausgegangen, dass der Nutzer reduzierte Bewegung wünscht. Mit der Media-Anfrage prefers-reduced-motion wird der Übergangswert dann in „Full Motion“ geändert.
Strategie für weniger Bewegung mit benutzerdefinierten Eigenschaften
Im folgenden CSS werden drei benutzerdefinierte Eigenschaften erstellt: --_motion-reduced, --_motion-ok und --_transition. Die ersten beiden enthalten geeignete Übergänge entsprechend der Nutzerpräferenz und die letzte Variable --_transition wird 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 die oben genannten Voraussetzungen erfüllt sind, können Änderungen an box-shadow, background-color, transform und outline-offset übernommen werden. Der Nutzer erhält dann eine entsprechende UI-Rückmeldung, dass seine Interaktion empfangen wurde.
Fügen Sie dem Status :active als Nächstes etwas mehr Flair hinzu, indem Sie translateYanpassen. Dadurch erhält die Schaltfläche einen schönen gedrückten Effekt:
.fab {
…
&:active {
@media (prefers-reduced-motion: no-preference) {
transform: translateY(2%);
}
}
}
Übertragen Sie schließlich alle Änderungen an den SVG-Symbolen in den Schaltflächen:
.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 wissen Sie, wie ich es gemacht habe. Wie würden Sie vorgehen? 🙂
Wir möchten unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, die das Web bietet.
Erstelle eine Demo, schick mir einen Tweet mit den Links und ich füge sie unten im Bereich „Community-Remixe“ hinzu.
Community-Remixe
Hier gibt es noch nichts zu sehen.
Ressourcen
- Quellcode auf GitHub