Lekcja 18

Linki, przyciski i stany: hover, focus, active, disabled

Po module responsywności zaczynamy budować realne komponenty UI. Linki i przyciski są małe, ale krytyczne: prowadzą użytkownika przez interfejs i muszą jasno komunikować, co można kliknąć, co jest aktywne, co ma fokus i co jest niedostępne.

Cele lekcji

Po ukończeniu tej lekcji będziesz umieć:

  • odróżnić semantycznie link od przycisku,
  • zbudować bazowy styl przycisku odporny na różne treści,
  • zaprojektować czytelny stan :hover,
  • zostawić wyraźny i dostępny stan :focus-visible,
  • dodać subtelny stan :active,
  • poprawnie obsłużyć :disabled i aria-disabled.

Kontekst praktyczny

Linki i przyciski pojawiają się w nawigacji, formularzach, modalach, dashboardach, kartach produktów, paskach narzędzi i CTA. Użytkownik powinien bez zastanowienia rozpoznać, który element prowadzi do innej strony, który uruchamia akcję oraz dlaczego niektóre akcje są chwilowo niedostępne.

W praktyce: dobry komponent interaktywny ma styl bazowy, warianty, stany myszy, stany klawiatury i wersję niedostępną. Nie wystarczy zmienić kolor na hover.

Bazowy styl komponentu

Bazowy przycisk powinien mieć przewidywalny rozmiar, czytelny tekst, stabilne odstępy i styl, który działa dla linku oraz elementu button.

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: .7rem 1.1rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font: inherit;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
}

font: inherit pomaga przy elementach button, które w wielu przeglądarkach mają własne domyślne style formularzy.

:hover

:hover pokazuje reakcję na wskaźnik myszy lub gładzik. Powinien być subtelny, ale zauważalny: zmiana koloru, tła, obramowania albo cienia.

.button:hover {
  background: #1d4ed8;
  transform: translateY(-1px);
}

Nie opieraj ważnej informacji wyłącznie na hover. Użytkownicy klawiatury i ekrany dotykowe nie korzystają z niego w taki sam sposób.

:focus-visible

:focus-visible pokazuje, który element jest aktualnie aktywny dla klawiatury. To jeden z najważniejszych stanów dostępności.

.button:focus-visible {
  outline: 3px solid #93c5fd;
  outline-offset: 3px;
}
Zapamiętaj: nie usuwaj outline bez zastąpienia go równie widocznym stanem fokusu. outline: none bez alternatywy to częsty błąd dostępności.

:active

:active działa w momencie naciskania elementu. Może dać wrażenie fizycznego kliknięcia, ale powinien być szybki i delikatny.

.button:active {
  transform: translateY(1px);
  box-shadow: none;
}

Jeśli używasz animacji, pamiętaj o prefers-reduced-motion. Stan aktywny nie powinien rozpraszać ani opóźniać wykonania akcji.

:disabled i aria-disabled

Dla elementu button używaj prawdziwego atrybutu disabled. Przeglądarka usunie go z interakcji i klawiatury. Dla linków nie ma natywnego disabled, więc jeśli musisz pokazać niedostępny link, użyj jasnego stylu oraz aria-disabled="true".

.button:disabled,
.button[aria-disabled='true'] {
  cursor: not-allowed;
  opacity: .55;
  transform: none;
}

Nie ukrywaj przyczyny niedostępności. Jeżeli akcja jest zablokowana, użytkownik powinien wiedzieć, co musi zrobić, aby ją odblokować.

Demo stanów

Poniższe demo pokazuje bazowy komponent, wariant linku, stan fokusu, stan aktywny oraz wersję niedostępną.

.ui-button {
  transition: background-color .18s ease, transform .18s ease;
}

.ui-button:hover {
  background: #1d4ed8;
}

.ui-button:focus-visible {
  outline: 3px solid #93c5fd;
  outline-offset: 3px;
}

.ui-button:disabled {
  opacity: .55;
  cursor: not-allowed;
}
Interaktywne
Link jako CTA

Najedź myszą lub przejdź klawiaturą przez elementy, żeby zobaczyć realne stany hover i focus-visible.

Symulacja stanów
hover focus-visible active disabled

Interpretacja: stany powinny różnić się wystarczająco mocno, ale nadal należeć do tego samego systemu wizualnego. Fokus klawiatury musi być najbardziej jednoznaczny.

Najczęstsze błędy początkujących

  • Usuwanie outline bez dodania widocznego zamiennika.
  • Używanie <a> do akcji, która powinna być przyciskiem.
  • Budowanie przycisku z <div> albo <span>.
  • Projektowanie tylko stanu :hover i ignorowanie klawiatury.
  • Disabled wyglądający jak zwykły aktywny przycisk.
  • Zbyt duże animacje na kliknięcie, które sprawiają wrażenie opóźnienia akcji.

Mini zadanie

Zbuduj mały system dwóch przycisków i jednego linku tekstowego.

  • Dodaj wariant .button--primary i .button--secondary.
  • Ustaw :hover, :focus-visible, :active i :disabled.
  • Sprawdź obsługę klawiaturą przez klawisz Tab.
  • Nie usuwaj fokusu bez widocznej alternatywy.
  • Dodaj jeden link wyglądający jak link tekstowy, nie jak przycisk.

Checklista

  • Wiem, kiedy użyć linku, a kiedy przycisku.
  • Potrafię zbudować bazowy styl przycisku na inline-flex.
  • Projektuję stan :hover jako ulepszenie, nie jedyny sygnał.
  • Zostawiam widoczny :focus-visible dla klawiatury.
  • Rozumiem różnicę między :disabled i aria-disabled.
  • Testuję komponent myszą, klawiaturą i na małym ekranie.

Podsumowanie lekcji

Linki i przyciski są podstawą interfejsu. Dobre komponenty interaktywne mają poprawną semantykę, czytelne style bazowe, przewidywalny hover, wyraźny focus, delikatny active i jednoznaczny disabled.

Kolejny krok roadmapy to formularze: inputy, labelki, błędy i stany walidacji.

Przejdź do Lekcji 19