Generator kart (tabs) CSS

Dalej

Karty są wszędzie – w oknach ustawień, na stronach dokumentacji i w galeriach produktów. Standardowy HTML nie ma dedykowanego elementu karty, więc programiści budują własne rozwiązania. Ten generator tworzy prosty pasek kart w HTML + CSS: kolor akcentu aktywnej karty, zaokrąglenie rogów przycisków i stan po najechaniu. Wklej znaczniki do swojego projektu i podłącz przełączanie kart za pomocą własnego JavaScriptu.

Jak zbudować karty

  1. 1

    Wybierz kolor akcentu

    Kolor tła i tekstu aktywnej karty. Wybierz kolor pasujący do Twojej marki.

  2. 2

    Ustaw zaokrąglenie rogów

    Zaokrągla górne rogi przycisków kart. Wyższe wartości dają łagodniejszy wygląd.

  3. 3

    Zmień etykiety

    Wynik zawiera trzy przyciski, „Overview", „Details" i „Settings": zmień ich nazwy, aby pasowały do treści.

  4. 4

    Skopiuj kod

    Znaczniki kart mają własny blok <style>. Wklej oba elementy na swoją stronę.

  5. 5

    Dodaj przełączanie kart

    Generator tworzy tylko część wizualną. Podłącz przyciski do własnego JavaScriptu lub biblioteki UI, aby pokazywać i ukrywać panele.

Poprawny, dostępny markup

<div class="tabs">
  <div role="tablist" aria-label="Product info">
    <button role="tab" id="tab-1" aria-selected="true"  aria-controls="panel-1" tabindex="0">Overview</button>
    <button role="tab" id="tab-2" aria-selected="false" aria-controls="panel-2" tabindex="-1">Specs</button>
    <button role="tab" id="tab-3" aria-selected="false" aria-controls="panel-3" tabindex="-1">Reviews</button>
  </div>
  <section role="tabpanel" id="panel-1" aria-labelledby="tab-1">...</section>
  <section role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>...</section>
  <section role="tabpanel" id="panel-3" aria-labelledby="tab-3" hidden>...</section>
</div>

Kluczowe atrybuty:

  • role="tablist" otacza przyciski.
  • role="tab" na każdym przycisku, wraz z aria-selected i aria-controls.
  • tabindex wykorzystuje wzorzec roving tabindex: tylko aktywna karta ma 0, pozostałe mają -1. Klawisze strzałek przenoszą fokus między nimi.
  • role="tabpanel" na każdym panelu, a aria-labelledby wskazuje jego kartę.
  • hidden na nieaktywnych panelach (nie tylko display: none – to właśnie tego atrybutu używają technologie wspomagające).

Zasady obsługi klawiatury

Klawisz Działanie
Tab Wejście do / wyjście z listy kart
ArrowLeft Poprzednia karta (zawija do ostatniej)
ArrowRight Następna karta (zawija do pierwszej)
Home Pierwsza karta
End Ostatnia karta
Enter / Space Aktywuj kartę z fokusem (przy aktywacji ręcznej)

Aktywacja automatyczna (karta zmienia się wraz z przesuwaniem fokusu) w porównaniu z ręczną (fokus się przesuwa, a karta aktywuje się po naciśnięciu Enter) – WAI-ARIA dopuszcza obie. Automatyczna jest łatwiejsza dla użytkowników widzących; ręczna jest lepsza, gdy zawartość karty jest kosztowna w renderowaniu.

Styl podkreślony

[role="tablist"] {
  display: flex;
  border-bottom: 1px solid #e5e7eb;
}
[role="tab"] {
  padding: 0.75rem 1rem;
  background: transparent;
  border: 0;
  color: #6b7280;
  position: relative;
  cursor: pointer;
}
[role="tab"][aria-selected="true"] {
  color: #111827;
}
[role="tab"][aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: 1rem; right: 1rem; bottom: -1px;
  height: 2px;
  background: #2563eb;
}

Styl pigułkowy

[role="tab"] {
  padding: 0.5rem 0.9rem;
  border-radius: 9999px;
  border: 0;
  background: transparent;
}
[role="tab"][aria-selected="true"] {
  background: #2563eb;
  color: #fff;
}

Widoczny fokus

Zawsze rysuj pierścień fokusu, gdy fokus przychodzi z klawiatury:

[role="tab"]:focus-visible {
  outline: 2px solid #60a5fa;
  outline-offset: 2px;
}

JavaScript

Mniej więcej:

const tabs = document.querySelectorAll('[role="tab"]');
tabs.forEach(tab => {
  tab.addEventListener('click', () => activate(tab));
  tab.addEventListener('keydown', e => {
    const i = [...tabs].indexOf(tab);
    if (e.key === 'ArrowRight') tabs[(i + 1) % tabs.length].focus();
    if (e.key === 'ArrowLeft')  tabs[(i - 1 + tabs.length) % tabs.length].focus();
    if (e.key === 'Home') tabs[0].focus();
    if (e.key === 'End')  tabs[tabs.length - 1].focus();
  });
});

function activate(tab) {
  tabs.forEach(t => {
    const panel = document.getElementById(t.getAttribute('aria-controls'));
    const active = t === tab;
    t.setAttribute('aria-selected', active);
    t.setAttribute('tabindex', active ? '0' : '-1');
    panel.hidden = !active;
  });
  tab.focus();
}

W sumie trzydzieści linii, bez żadnych zależności.

Karty a akordeony

Na wąskich ekranach rzędy kart robią się ciasne. Typowy wzorzec: karty na komputerze, akordeon na urządzeniu mobilnym. Aby zmienić prezentację wizualną bez zmiany ról ARIA, użyj zapytania kontenerowego (container query) lub zapytania medialnego (media query).

Najczęściej zadawane pytania

W przypadku dostępnych kart – tak. Bez role="tablist" i role="tab" czytniki ekranu traktują przyciski jak zwykłe przyciski, a użytkownicy tracą przyjętą konwencję nawigacji po kartach. Alternatywą jest prosty akordeon <details> / <summary>, który ma wbudowaną semantykę.

Tryb automatyczny (karta aktywuje się przy przesuwaniu fokusu) jest odpowiedni, gdy zawartość każdej karty łatwo się renderuje. Tryb ręczny (fokus się przesuwa, a aktywuje naciśnięcie Enter) jest lepszy, gdy zmiana kart uruchamia ciężkie operacje, takie jak pobieranie danych lub renderowanie dużego formularza.

W przypadku kart z treścią (dokumentacja, karty produktów) – tak: użyj hasha (#specs) lub parametru zapytania, aby linki mogły prowadzić bezpośrednio do konkretnej karty, a aktywna karta była zachowywana po ponownym wczytaniu strony. W przypadku kart interfejsu (okna ustawień) adres URL jest opcjonalny.

Tylko z pomocą sztuczki na polach wyboru/przyciskach radiowych, która nie oferuje nawigacji klawiszami strzałek ani stanów ARIA. Dla naprawdę dostępnej implementacji ten niewielki fragment kodu JS jest tego wart. Jeśli potrzebujesz rozwiązań zapasowych renderowanych po stronie serwera, powiąż każdą kartę z unikalnym adresem URL i renderuj odpowiedni panel po stronie serwera.

Powiązane narzędzia

Narzędzie jest dostępne w innych językach