Komponente für unverankerte Aktionsschaltflächen erstellen

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.

Zwei FAB-Schaltflächen werden angezeigt, wobei das Rasterlayout von den DevTools überlagert wird. Die Lücke zwischen ihnen wird mit einem Streifenmuster dargestellt. Außerdem werden die berechnete Höhe und Breite angezeigt.

.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;
}

Ein Screenshot der beiden gestapelten FAB-Schaltflächen, wobei die obere Schaltfläche kleiner als die untere ist.

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.

Demonstration der Tastaturinteraktion

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