Tworzenie komponentu pływającego przycisku polecenia (FAB)

Podstawowy przegląd sposobów tworzenia komponentów FAB dostosowanych do kolorów, dostosowanych do urządzeń mobilnych i dostępnych.

W tym poście chcę podzielić się z Wami swoimi przemyśleniami na temat tworzenia komponentów FAB, które dostosowują się do kolorów, są elastyczne i dostępne. Wypróbuj wersję demonstracyjnąwyświetl kod źródłowy.

Jeśli wolisz film, oto wersja tego posta w YouTube:

Omówienie

FAB są częściej używane na urządzeniach mobilnych niż na komputerach, ale występują bardzo często w obu sytuacjach. Ułatwiają one dostęp do głównych działań, dzięki czemu są one wygodne i wszechobecne. Ten styl został spopularyzowany przez Material UI, a zalecenia dotyczące jego użycia i rozmieszczenia znajdziesz tutaj.

Elementy i style

Kod HTML tych elementów sterujących zawiera element kontenera i co najmniej 1 przycisk. Kontener umieszcza przyciski PPP w widocznym obszarze i zarządza lukami między przyciskami. Przyciski mogą być małe lub domyślne, co zapewnia większą różnorodność między działaniami głównymi i dodatkowymi.

Kontener przycisku typu FAB

Ten element może być zwykłym elementem <div>, ale zróbmy przysługę naszym niewidzącym użytkownikom i oznaczmy go atrybutami, które pomogą wyjaśnić jego przeznaczenie i zawartość.

Markup przycisków typu FAB

Zacznij od klasy .fabs, z którą kod CSS będzie się łączył, aby utworzyć styl, a potem dodaj role="group" i aria-label, aby nie był to tylko ogólny kontener, ale miał nazwę i cel.

<div class="fabs" role="group" aria-label="Floating action buttons">
  <!-- buttons will go here -->
</div>

Styl przycisku typu FAB

Aby przyciski szybkiego dostępu były wygodne w użyciu, zawsze pozostają w widocznym obszarze. To świetny przypadek użycia pozycji fixed. W tej pozycji w wyświetlaczu wybrałem użycie pozycji inset-blockinset-inline, aby pozycja pasowała do trybu dokumentu użytkownika, np. od prawej do lewej lub od lewej do prawej. Właściwości niestandardowe służą też do zapobiegania powtórzeniom i zapewnienia jednakowej odległości od dolnej krawędzi i krawędzi bocznych widoku:

.fabs {
  --_viewport-margin: 2.5vmin;

  position: fixed;
  z-index: var(--layer-1);

  inset-block: auto var(--_viewport-margin);
  inset-inline: auto var(--_viewport-margin);
}

Ustawiam widok kontenera flex i zmieniam kierunek jego układu na column-reverse. Spowoduje to ułożenie elementów podrzędnych jeden na drugim (w kolumnie) oraz odwrócenie ich kolejności wizualnej. W efekcie pierwszy element, który można zaznaczyć, jest elementem dolnym, a nie górnym, co jest zgodne z normalnym zachowaniem dokumentu HTML. Odwrócenie kolejności wizualnej powoduje ujednolicenie wrażeń użytkowników widzących i korzystających z klawiatury, ponieważ styl działania głównego na większy niż miniprzyciski sugeruje użytkownikom, że jest to działanie główne. Użytkownicy klawiatury ustawiają je jako pierwszy element w źródle.

Widok 2 przycisków FAB z przesłonięciem ich układu siatki w DevTools Wyświetla odstęp między nimi za pomocą pasków, a także oblicza ich wysokość i szerokość.

.fabs {
  

  display: flex;
  flex-direction: column-reverse;
  place-items: center;
  gap: var(--_viewport-margin);
}

Wyśrodkowanie jest obsługiwane za pomocą funkcji place-items, a gap dodaje odstęp między wszystkimi przyciskami FAB umieszczonymi w kontenerze.

Przyciski typu FAB

Czas nadać niektórym przyciskom styl, który sprawi, że będą wyglądać jak pływające nad wszystkim.

Domyślny przycisk FAB

Pierwszym przyciskiem, który należy sformatować, jest przycisk domyślny. Będzie ona służyć jako podstawa dla wszystkich przycisków typu FAB. Później utworzymy wariant, który będzie miał alternatywny wygląd, przy jak najmniejszej możliwej modyfikacji tych stylów bazowych.

Markup przycisku typu FAB

Odpowiedni będzie element <button>. Zaczniemy od tego, ponieważ zapewnia ona świetne wrażenia podczas korzystania z myszy, ekranu dotykowego i klawiatury. Najważniejszym aspektem tego znacznika jest ukrycie ikony przed użytkownikami korzystającymi z czytnika ekranu za pomocą atrybutu aria-hidden="true" oraz dodanie niezbędnego tekstu etykiety do samego znacznika <button>. Dodając w takich przypadkach etykiety, lubię też dodać element title, aby użytkownicy myszy mogli dowiedzieć się, co chcą przekazać ikona.

<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>

Styl przycisku typu FAB

Najpierw przekształcimy przycisk w okrągły przycisk z wypełnieniem i silnym cieniem, ponieważ są to pierwsze cechy definiujące przycisk:

.fab {
  --_size: 2rem;

  padding: calc(var(--_size) / 2);
  border-radius: var(--radius-round);
  aspect-ratio: 1;
  box-shadow: var(--shadow-4);
}

Teraz dodajmy kolor. Użyjemy strategii, której używaliśmy już wcześniej w wyzwaniach dotyczących interfejsu graficznego. Utwórz wyraźnie nazwany zestaw właściwości niestandardowych, które będą zawierać statycznie jasne i ciemne kolory, a następnie właściwości niestandardowe z dopasowaniem, które będą ustawione na jasne lub ciemne zmienne w zależności od preferencji użytkownika dotyczących kolorów:

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

Następnie dodaj style, aby ikony SVG pasowały do przestrzeni.

.fab {
  

  & > svg {
    inline-size: var(--_size);
    block-size: var(--_size);
    stroke-width: 3px;
  }
}

Na koniec usuń podświetlenie przycisku po kliknięciu, ponieważ dodaliśmy własną wizualną informację zwrotną dotyczącą interakcji:

.fab {
  -webkit-tap-highlight-color: transparent;
}

Miniprzycisk typu FAB

Celem tej sekcji jest utworzenie wariantu przycisku FAB. Dzięki temu, że niektóre przyciski FAB są mniejsze niż domyślne działanie, możemy promować działanie, które użytkownik wykonuje najczęściej.

Znaczniki miniprzycisku typu FAB

Kod HTML jest taki sam jak w przypadku przycisku FAB, ale dodajemy klasę „.mini”, aby umożliwić użyciu kodu CSS tej opcji.

<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>
Styl miniprzycisku typu FAB

Dzięki zastosowaniu właściwości niestandardowych jedyną wymaganą zmianą jest dostosowanie zmiennej --_size.

.fab.mini {
  --_size: 1.25rem;
}

Zrzut ekranu z 2 ułożonymi w wielokrotnym użyciu przyciskami FAB. Górny przycisk jest mniejszy niż dolny.

Ułatwienia dostępu

Najważniejszą częścią, o której należy pamiętać w przypadku ułatwień dostępu w przypadku przycisku PPP, jest umiejscowienie w obrębie klawiatury na stronie. W tym demie są tylko przyciski FAB. Nie ma więc nic, z czym można by porównać kolejność i przepływ klawiatury. Oznacza to, że nie można zaprezentować prawidłowego przepływu klawiatury. W sytuacji, gdy elementy konkurują o uwagę użytkownika, warto dokładnie przemyśleć, w jakim momencie użytkownik powinien zobaczyć przycisk FAB.

Przykład interakcji z klawiaturą

Gdy użytkownik skupi się na kontenerze przycisku szybkiego dostępu, dodaliśmy już elementy role="group"aria-label="floating action buttons", które informują użytkowników czytnika ekranu o tym, na czym się skupiają. Strategicznie umieściłem domyślny przycisk PPP, aby użytkownicy jako pierwsze znajdowali główne działanie. Następnie użyj flex-direction: column-reverse;, aby wizualnie uporządkować przycisk główny na dole, w pobliżu palców użytkownika, aby był łatwo dostępny. To świetne rozwiązanie, bo przycisk domyślny jest widoczny dla użytkowników klawiatury i jest pierwszy, co sprawia, że interfejs jest bardzo podobny.

Na koniec pamiętaj, aby ukryć ikony przed użytkownikami korzystającymi z czytników ekranu, i zapewnij im etykietę przycisku, aby nie było to zagadką. Zrobiliśmy to już w kodzie HTML z aria-hidden="true" na <svg> i aria-label="Some action" dnia <button>s.

Animacja

Aby zwiększyć wygodę użytkowników, możesz dodać różne rodzaje animacji. Podobnie jak w przypadku innych wyzwań dotyczących interfejsu użytkownika, skonfigurujemy kilka właściwości niestandardowych, aby przechowywać intencję ograniczonego i pełnego ruchu. Domyślnie stylizacja zakłada, że użytkownik chce ograniczyć ruch, a następnie za pomocą zapytania o multimedia prefers-reduced-motion zmienia wartość przejścia na pełny ruch.

Strategia ograniczonego ruchu z właściwościami niestandardowymi

W tym kodzie CSS są tworzone 3 właściwości niestandardowe: --_motion-reduced, --_motion-ok i --_transition. Pierwsze 2 zmiennych zawierają odpowiednie przejścia w zależności od preferencji użytkownika, a ostatnia zmienna --_transition zostanie ustawiona odpowiednio na --_motion-reduced lub --_motion-ok.

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

Po wprowadzeniu tych zmian można wprowadzić zmiany w elementach box-shadow, background-color, transformoutline-offset, aby użytkownik otrzymał odpowiedni komunikat w interfejsie.

Teraz możesz trochę uatrakcyjnić stan :active, translateYzmieniając go w celu uzyskania przyjemnego efektu naciśnięcia przycisku:

.fab {
  

  &:active {
    @media (prefers-reduced-motion: no-preference) {
      transform: translateY(2%);
    }
  }
}

Na koniec wprowadź zmiany w ikonach SVG w przyciskach:

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

Podsumowanie

Teraz, gdy już wiesz, jak to zrobić, jak Ty to zrobisz? 🙂

Stosujmy różne podejścia i poznajmy sposoby budowania obecności w internecie.

Utwórz wersję demonstracyjną, wyślij mi linki, a ja dodam je do sekcji z remiksami społeczności.

Remiksy społeczności

Na razie jest tu pusto.

Zasoby