Interfejs karty i bloki wizualne
1) Dlaczego karty
Karty pakują podmiot (gra, mecz, akcja, artykuł) z kluczowymi atrybutami i akcjami. Dobra karta:- szybko zeskanowany,
- daje jeden mistrz CTA,
- przystosowuje się do różnych pojemników/kolumn,
- przewidywalne w zachowaniu (zawisanie, naciśnięcie, ostrość, menu kontekstowe).
2) Anatomia karty
Minimalny skład:1. Strefa mediów (okładka/logo/podgląd, 16: 9/4: 3/1: 1).
2. Nagłówek (1-2 okrojone linie).
3. Metadane (napisy, znacznik/kategoria, dostawca, czas).
4. Odznaki statusu (nowe, na żywo, promocja, ocena).
5. CTA/szybkie akcje (przycisk lub ikony).
6. Tekst drugorzędny (krótki, 2-3 maksymalne linie).
7. Sterowanie (ulubione,... kontekst).
Hierarchia: media → nagłówek → CTA → meta → wtórny. Działania destrukcyjne są ukryte lub wyświetlane w menu.
3) Siatki i układy
Siatka (kolumna stacjonarna): 2-6 kolumn;
Płytki reagujące: 'minmax (240px, 1fr)' - karty rosną dokładnie do granic.
Murowana/różna wysokość: ostrożna; zapewnić porządek skupienia i czytelność.
Lista (z rzędu): gdy gospodarka horyzontalna i sortowanie są ważne.
css
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px,1fr));
gap: 16px;
}
.card {
border-radius: 12px;
background: var(--bg-elevated);
box-shadow: var(--elev-2);
display: grid;
grid-template-rows: auto 1fr auto;
overflow: hidden;
}
.card__media { aspect-ratio: 16/9; object-fit: cover; }
4) Gęstość i rytm
Marginesy/tiret: wewnątrz 12-16 px; między jednostkami 8-12 px.
Wysokość wiersza: 1. 3–1. 5; czcionki: tytuł 16-18 px, meta 12-14 px.
Przycinanie tekstu: „zacisk liniowy: 2-3”; obowiązkowy pełny tekst w podpowiedzi/szczegółach.
5) Państwa i interaktywność
Hover/Focus/Active: shadow/highlight, ale bez układu „skoki”; „: zawsze widoczne w ostrości”.
Możliwość wyboru: pole wyboru/ramka; nie mylić z kartą referencyjną.
Naciśnięty: zmniejszyć do 98% + cień w dół (≤ 120 ms).
Busy/Loading: szkielet, nie „pusty”.
css
.card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.card:hover { box-shadow: var(--elev-3); transform: translateY(-1px); transition: box-shadow. 16s, transform. 16s; }
6) Obrazy i media
Proporcje są stałe; na listach gier - 16:9 lub 4:3.
Obciążenie leniwe: 'obciążenie =' leniwe '+' dekodowanie = 'async''.
Łożysko/szkielet z dominującym kolorem plakatu.
Błąd ładowania: obojętne zdjęcie + ikona zdjęcia-off.
html
<img class = "card __ media" src ="..." alt = "Game name" loading =" lazy" onerror =" this. src='/fallback. png'">
7) Odznaki i tagi
Krótkie (1-2 słowa): New, Live, -20%, Top 10.
Nie można polegać tylko na kolorze - dodaj ikonę/tekst.
Lokalizacja: lewe górne media; kilka - w stosie o szczelinie 4-6 px.
css
.badge { display:inline-flex; gap:6px; align-items:center; padding:4px 8px; border-radius:8px; font-size:.75rem; }
.badge--live { background: var(--bg-danger); color: var(--on-danger); }
8) CTA i szybkie działanie
Jeden podstawowy na kartę (na przykład "Play", "Bet').
Ikony pomocnicze (ulubione, udostępnianie,...) - przez hover/focus.
Destrukcyjna - poprzez potwierdzenie lub cofnięcie panelu.
html
<div class="card__actions">
<button class="btn btn--primary">Играть</button>
<button class =" icon" aria-label = "Add to Favorites" title =" B Favorites "> </button>
<button class="icon" aria-haspopup="menu" aria-expanded="false">⋯</button>
</div>
9) Dostępność (A11y)
Cała karta linków jest '<a>' z wyraźnym 'aria-label', inaczej: tytuł jest jak link, reszta jest statyczna.
Kolejność Tab odpowiada funkcji wizualnej; pierścień ostrości jest widoczny.
Obrazy z 'alt'; dekoracyjne - 'aria-hidden =' true ''.
W przypadku statusów należy użyć 'role =' status '/' aria-live = 'polite' '.
Kontrast tekstu i odznaki ≥ AA; znaczenie to nie tylko kolor.
10) Wydajność
Leniwe ładowanie mediów i list; paginacja lub nieskończoność przewijania z wartownikiem.
Wirtualizacja taśmy/nieskończonych wyjść (± 10k elementów).
Zminimalizuj przepływ: Animuj tylko 'przekształcenie/nieprzezroczystość'.
Render karty ze szkieletami i zastąpić z zawartości po załadowaniu danych.
11) Szkielety, błędy, puste
Szkielet powtarza strukturę karty (nośnik/tekst/przycisk), bez agresywnego migotania; weźmy pod uwagę „ruch zredukowany prefers”.
Stan błędu: ikona + krótki tekst („Nie udało się załadować gry”) + przycisk Retry.
Stan pusty: ikona/ilustracja, wyjaśnienie, „Co dalej” (filtr/wyszukiwanie/subskrypcje).
12) Zarządzanie treścią
Okrawanie: 'line-clamp' + explicit tooltip.
Długie numery/sumy: cyfry tabeli: "font-variant-numeric: tabular-nums; '.
Lokalizacja: rezerwa + 20-30% szerokości dla długich etykiet.
Obsługa RTL: odznaki flip/ikony i wyrównania.
13) Ciemny motyw i kontrast
Cienie są słabsze, wykorzystują granice („1px”) z przejrzystością.
Wsparcie AAA dla małych czcionek; unikać migotania.
Nośniki są przyciemniane przez cienką welon (nakładka 8-12%), aby tekst był czytelny.
css
.theme-dark. card { background: var(--bg-elevated-dark); box-shadow: var(--elev-1-dark); }
.theme-dark. card__media::after { content:""; position:absolute; inset:0; background: rgba(0,0,0,.12); }
14) Sortowanie, filtry, paginacja
Górny/boczny panel filtracyjny; rezultatem jest siatka kart.
Paginacja jest widoczna; niekończące się przewijanie - tylko z „Powrót do góry” i utrzymanie pozycji.
Filtry nie „zresetować” przewijania; zastosowane szybko (≤ 100 ms) lub ze wskaźnikiem.
15) Specyfika iGaming
15. 1 Karta gry (slot/table)
Media: 16:9 plakat, logo dostawcy.
Metadane: dostawca, RTP, zmienność, kategorie (- tylko informacyjne, bez obietnic wygranej).
Odznaki: Nowy, Popularny, Turniej, Jackpot.
CTA: "Play" + "Demo. "Kontekst "18 +" i odpowiedzialna gra są widoczne.
15. 2 Karta dopasowania/współczynnika
Żywa odznaka Live; timer/okres.
Współczynniki klucza (2-3) z natychmiastowym zawisem/prasą i bezpiecznym cofnięciem (jeśli jest to dozwolone).
Aktualizacje bez migotania; przy zmianie kursu - schludne oświetlenie.
15. 3 Karta turnieju/wydarzenia
Daty, pula nagród, zasady (link).
Status (rejestracja otwarta/zamknięta, w toku).
CTA „Dołącz”, „Zasady”; postępy w uczestnictwie (punkty/miejsce).
16) Antypattery
Cała karta jest klikalna + wewnątrz wtórnych linków (ostrość/kliknij pułapki).
Dwa podstawowe-CTA w pobliżu („Play” i „Kup Bonus”) - konkurencja uwagi.
Brak znaczników/szkieletów → siatka skoków (CLS).
Niekończące się efekty lśnienia; animacja/rozmycie cieni (drogie).
Metadane kolumn w małej szarości na szarości (bez kontrastu).
Odznaki, które przekazują znaczenie tylko w kolorze.
17) Żetony systemu projektowania (przykład)
json
{
"card": {
"radius": 12,
"gap": 12,
"mediaRatio": "16/9",
"px": "12 12 12 12",
"shadow": { "rest": "var(--elev-2)", "hover": "var(--elev-3)" }
},
"badge": { "radius": 8, "px": "4 8", "icon": 14 },
"grid": { "gap": 16, "min": 240, "max": 1 },
"motion": { "hoverMs": 160, "pressMs": 100, "fadeMs": 160 },
"a11y": { "contrastAA": true, "focusRingWidth": 2, "focusRingOffset": 2 }
}
18) Snippety
Reakcja: karta uniwersalna
tsx type CardProps = {
title: string;
subtitle?: string;
mediaUrl?: string;
badges?: string[];
onPrimary?: () => void;
primaryLabel?: string;
onFav?: () => void;
children?: React. ReactNode;
};
export default function Card({
title, subtitle, mediaUrl, badges=[], onPrimary, primaryLabel='Открыть', onFav, children
}: CardProps){
return (
<article className="card group focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2">
<div className="relative">
{mediaUrl? <img className="w-full aspect-[16/9] object-cover" src={mediaUrl} alt={title}/>: <div className="aspect-[16/9] bg-neutral-200"/>}
<div className="absolute top-2 left-2 flex gap-1">
{badges. map(b => <span key={b} className="badge">{b}</span>)}
</div>
</div>
<div className="p-3 grid gap-2">
<h3 className="text-sm font-semibold line-clamp-2" title={title}>{title}</h3>
{subtitle && <p className="text-xs text-neutral-500 line-clamp-2">{subtitle}</p>}
{children}
<div className="flex items-center gap-8">
{onPrimary && <button className="btn btn--primary" onClick={onPrimary}>{primaryLabel}</button>}
{onFav && <button className="icon opacity-0 group-hover:opacity-100" aria-label="В избранное" onClick={onFav}></button>}
</div>
</div>
</article>
);
}
Nieskończona wartownia przewijania
js const sentry = document. querySelector('#sentry');
const io = new IntersectionObserver(entries=>{
if(entries. some(e=>e. isIntersecting)) loadMore();
}, { rootMargin: '200px' });
io. observe(sentry);
19) Metryki i eksperymenty
CTR primary-CTA Н Time-to-Click.
Przewiń-głębokość → kliknij: kliknij' nad zakrętem "/" pod zakrętem ".
Karta → zobacz szczegóły → konwersja.
Widoczność odznak i ich wpływ na CTR.
Szkielet czas widoczny przez CLS.
A/B: wielkość kart, ilość metadanych, widoczność szybkich działań, rodzaj siatki (lista/siatka).
20) Lista kontrolna QA
Dostępność
- Pierścienie ostrości są widoczne; Kolejność kart jest logiczna.
- Teksty Alt i „aria-label” są poprawne; odznaki stanu z tekstem.
- Kontrast tekst/tło ≥ AA.
Zachowanie
- Jeden pierwotny - CTA; szybkie działania nie pokrywają się z głównym scenariuszem.
- Hover/press/selected distinguishable; menu kontekstowe działa.
- Puste/błędy/szkielety są poprawne; Jest Retry.
Wydajność
- Leniwe ładowanie nośników; nie ma ostrych skoków w układzie.
- Wirtualizacja dużych list; animacje "transform/dymorfizm'.
Siatka
- „minmax (240px, 1fr)” i „luka” są adaptacyjne; Masoneria nie łamie ostrości/porządku czytania.
- RTL/lokalizacja nie „łamie” upraw i odznaki.
21) Dokumentacja w systemie projektowym
Кобонента: „Karta”, „GameCard”, „MatchCard”, „TournamentCard”, „Badge”, „SkeletonCard”.
Żetony: promień/cienie/tiret/warstwy, kolory odznaki, animacje.
Wzory: „Jeden CTA”, „Szkielet zamiast spinner”, „Nieskończony przewijanie + utrzymanie pozycji”.
Do/Don gallery: overloaded card vs minimal, „clickable whole card” vs explicit elements.
Krótkie podsumowanie
Karty działają, gdy mają wyraźną hierarchię, jeden master CTA, przewidywalne stany, stabilne sieci, a także szacunek dla wydajności i dostępności. Przechwytuj żetony i wzory, używaj szkieletów i leniwego ładowania, zachowuj zwięzłość treści - a interfejsy kart staną się szybkie, czytelne i gotowe do konwersji, zwłaszcza w skryptach iGaming.