Modalități și panouri de ieșire
1) Când să utilizați ce
Modal (dialog cu fundalul) - pentru soluții critice și sarcini scurte care necesită o atenție deplină: confirmarea acțiunii, consimțământul juridic, operațiuni periculoase, forme scurte ≤ 1-2 domenii. Încuie fundalul.
Sertar/foaie (panou de extragere) - pentru extensie în loc: detalii obiect, editare atribut, selecție din listă, navigare auxiliară. Fundalul este vizibil → contextul este păstrat.
- Dacă acțiunea are nevoie de concentrare și confirmare → Modal.
- Când să salvați contextul și să oferiți o imagine de ansamblu „paralelă” a sertarului →.
2) Structura și dimensiunile
Modal
Titlul (necesar) organismului → → CTA (primar/secundar/distructiv).
Dimensiuni: S (480-560 px), M (640-720 px), L (≤ 840 px). Pe mobil - foaie full-screen.
Sertar/foaie
Direcţie: marginea dreaptă (desktop, editare), partea de jos (mobil, acţiuni), uneori stânga (navigare).
Lățime: 360-480 (S), 480-640 (M), 640-800 (L) Pe mobil: 90-100% lățime/înălțime.
Înălțimea conținutului este întotdeauna limitată, derulând în interior; antet/STA sunt fixe.
3) Copywriting și CTA
Titlu = Acțiune/Înțeles: Confirmați rata, Selectați metoda de plată, KYC necesar.
Text scurt, 1-2 propoziții. Evitaţi formulele vagi.
CTA: un primar, următorul secundar („Anulare”) și, dacă este necesar, distructiv.
Pentru acțiuni riscante, adăugați o explicație 1-line: "Acțiunea este ireversibilă. Veți putea anula în termen de 10 secunde (dacă este disponibil) "
4) Comportament și stări
Deschidere: răspuns instantaneu ≤ 100 ms, apoi animație 120-180 ms.
Închidere: mai rapid decât deschiderea (80-140 ms), se întoarce focalizarea la declanșator.
Ocupat: 'aria-ocupat = „adevărat”' pe container, buton cu blocare din nou.
Nesalvat (formă murdară): la închidere - dialog-avertizare („Există modificări nesalvate”).
Evadare/click pe fundal: acceptabil pentru dialoguri non-periculoase; pentru critică - numai butoane explicite.
5) Disponibilitate (A11y)
Container: 'rol =' dialog '' şi 'aria-modal =' adevărat '(pentru un modal real).
Titlul este legat prin „aria-etichetată”; descriere - „aria-descripedby”.
Focalizați capcana în interior; accentul principal este pus pe antet sau pe primul element interactiv.
Returnează focalizarea la declanșatorul original după închidere.
Nu există fundal de derulare: "document. corp {overflow: ascuns;} 'sau' inert 'pe restul DOM.
Suport pentru tastatură: Tab/Shift + Tab sunt ciclice; Esc se închide (cu excepția cazului în scripturi interzise).
Luați în considerare „prefers-redused-motion”: dezactivarea/simplificarea animațiilor.
html
<div class="backdrop" data-open hidden></div>
<div class="dialog" role="dialog" aria-modal="true" aria-labelledby="d-title" aria-describedby="d-desc" hidden>
<h2 id =" d-title "> Confirm Bid </h2>
<p id =" d-desc "> Sum of 200 ₴ by factor 1. 85</p>
<div class="actions">
<button class =" btn btn--primary "> Confirm </button>
<button class =" btn btn--ghost "> Cancel </button>
</div>
</div>
6) Performanță și arhitectură
Redarea printr-un portal (strat deasupra unei aplicații) → mai puține probleme z-index.
Montați conținut leneș la prima deschidere, demontați după închiderea animației (sau traduceți offscreen).
Animați numai „transformare/opacitate”; evitați umbrele scumpe/supradimensionate.
Blocați derularea de fundal (scroll-lock), păstrați poziția curentă, astfel încât să nu „sară” după închidere.
Pentru liste mari în sertar - utilizați virtualizarea.
7) Modele mobile
Foaie de jos pentru acțiuni/confirmări rapide: glisați în jos gesturi pentru a închide (cu prag).
Sticky-CTA în partea de jos; închide butonul - din stânga sus.
Liniuțe de siguranță (crestături/zone de gesturi).
Tastatura de pe ecran nu trebuie să se suprapună CTA; aspect - „ridicare” conținut sau un panou fix deasupra tastaturii.
8) Proiectarea mișcării
Intrare: se estompează + schimbare de lumină (modal: de-a lungul Y, sertar: de-a lungul axei de aspect). 120-180 ms.
Ieșire: mai scurtă (80-140 ms), easing 'cubic-bezier (0. 2,0,0. 2,1)`.
Opacitatea de fundal este 0 → 0. 4–0. 6. Fără pulsații și strălucire nesfârșită.
Pentru „preferă mișcarea redusă”: fără schimbare, doar se estompează.
9) Managementul închiderii
Închidere imediată doar pentru operaţiuni sigure.
Dacă există o eroare, rămânem în dialog, arătăm motivul și încercăm din nou.
În execuția de fundal - închideți dialogul și arătați toastul „Executăm în fundal”..., plus secțiunea „Istorie”.
10) Scenarii tipice pentru iGaming
10. 1 Confirmarea ofertei (Modal)
Conținut: eveniment, coeficient, sumă, câștig potențial, perioada de valabilitate a coeficientului.
Butoane: „Confirmă” (primar), „Anulează”.
Model de întârziere> 3 s: text „În așteptare pentru confirmare”...; dacă coeficientul se schimbă, o actualizare onestă.
10. 2 Cashout (Modal/Sheet)
Afișează suma curentă de cashout și temporizatorul ferestrei.
Confirmare + posibilitate Anulare (dacă regulamentul permite).
10. 3 Alegerea unei metode de plată (sertar)
Lista metodelor cu comisioane/ETA; Selectează → formei mini.
Salvarea metodei implicite; Return fără pierderi de intrare
10. 4 KYC (sertar → modal)
Sertar pentru încărcarea documentelor/solicitărilor.
Modal atunci când încercați să închideți cu sarcină incompletă: avertizare despre nesalvat.
10. 5 Limite de joc responsabil (Modal)
Radio „Zi/Săptămână/Lună”, câmp suma, linia „Va avea efect în”....
11) Anti-modele
Modale imbricate (modale peste modale). Utilizați o singură secvență de dialog sau de pas.
Modalka pentru vizualizarea regulată a conținutului (sertar/pagină mai bună).
Cruce ascunsă sau închidere numai prin „microzonă”.
Acțiune riscantă → permisiunea de a închide „de fundal”.
Formă lungă într-un modal (mutați → într-un ecran/panou separat).
Nu focalizare reveni la declanșare.
12) Proiectarea tokenurilor sistemului (exemplu)
json
{
"dialog": {
"radius": 12,
"shadow": "var(--elev-4)",
"sizes": { "s": 520, "m": 680, "l": 840 },
"backdropOpacity": 0. 5,
"padding": "20 24",
"gap": 16
},
"drawer": {
"width": { "s": 360, "m": 480, "l": 640 },
"edge": "right",
"radius": 12,
"shadow": "var(--elev-4)"
},
"motion": {
"inMs": 160,
"outMs": 120,
"ease": "cubic-bezier(0. 2,0,0. 2,1)",
"reduce": true
},
"a11y": {
"useAriaModal": true,
"focusTrap": true,
"returnFocus": true
}
}
Presetări CSS (concept):
css
.backdrop[data-open]{position:fixed; inset:0; background:rgba(0,0,0,.5); backdrop-filter:saturate(80%); opacity:1; transition:opacity. 16s}
.dialog,[data-drawer]{position:fixed; background:var(--bg-elevated); border-radius:12px; box-shadow:var(--elev-4);}
.dialog{inset:auto; left:50%;top:50%;transform:translate(-50%,-50%); max-width:840px; width:min(100% - 32px, var(--dialog-w,680px));}
[data-drawer="right"]{top:0; right:0; height:100%;width:var(--drawer-w,480px); transform:translateX(0)}
.dialog[hidden],.backdrop[hidden]{display:none}
13) Fragmente de comportament
Focus capcană + focus retur:js const openBtn = document. getElementById('open');
const dlg = document. querySelector('.dialog');
let prevFocus;
function openDialog() {
prevFocus = document. activeElement;
dlg. hidden = false; document. body. style. overflow = 'hidden';
const focusable = dlg. querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
(focusable[0] dlg). focus();
function onKey(e){
if(e. key==='Escape') return closeDialog();
if(e. key!=='Tab') return;
const first = focusable[0], last = focusable[focusable. length-1];
if(e. shiftKey && document. activeElement===first){ e. preventDefault(); last. focus(); }
else if(!e.shiftKey && document. activeElement===last){ e. preventDefault(); first. focus(); }
}
dlg. addEventListener('keydown', onKey);
dlg. dataset. off = ()=> dlg. removeEventListener('keydown', onKey);
}
function closeDialog() {
dlg. dataset. off && dlg. dataset. off();
dlg. hidden = true; document. body. style. overflow = '';
prevFocus && prevFocus. focus();
}
Foaie cu gest de închidere (mobil, simplificat):
js let startY=0, delta=0;
const sheet = document. querySelector('.sheet');
sheet. addEventListener('touchstart', e => startY = e. touches[0].clientY);
sheet. addEventListener('touchmove', e => {
delta = Math. max(0, e. touches[0].clientY - startY);
sheet. style. transform = `translateY(${delta}px)`;
});
sheet. addEventListener('touchend', () => {
if (delta > 120) sheet. classList. remove('open'); else sheet. style. transform = '';
delta = 0;
});
14) Măsurători și experimente
Rata de deschidere/rata de finalizare prin modal: câte au deschis și finalizat acțiunea.
Time-to-Decision: De la deschidere la clic pe Primar.
Respingeți rata și motivele (Esc/fundal închide vs „Anula”).
Eroare/Retry Rata în scripturi ocupat.
A/B: sertar modal vs, text CTA, comandă câmp, „confirma” vs „anula”.
15) Lista de verificare QA
Disponibilitate
- 'rol = „dialog”', 'aria-modal = „adevărat”', corect 'aria-etichetat/-describedby'.
- Focus capcană funcționează; focalizarea revine pe trăgaci.
- Esc se închide (dacă este permis); Fila este ciclică.
- Contrast ≥ AA; nu doar culoarea transmite sens.
Comportament
- TTFF ≤ 100 ms; animație în 120-180 ms/out 80-140 ms.
- Derulați-blocați fundalul fără a „sări” pagina.
- Garda nesalvată în formă murdară.
- Stare ocupată, Retry corectă/erori.
Interfață
- Clear header și un primar-CTA.
- Este disponibil un buton cross/close.
Dimensiunile sunt adaptive; pe foaia mobilă cu un gest.
Performanță
- Portalurile/z-index sunt corecte; fără „transmisie”.
- Inițializare leneșă; numai transformarea/opacitatea sunt animate.
16) Documentația în sistemul de proiectare
Componente: 'Modal', 'Drawer/Sheet', 'ConfirmDialog', 'UnsavedGuard'.
Jetoane: dimensiuni, liniuțe, umbre, animații, fundal, focus-ring.
Ghiduri: „Când modal vs sertar”, modele de copywriting, acțiuni riscante (confirma/anula), scroll-lock și portaluri, reduce-mișcare.
Do/Don' t galerie: modale imbricate (don' t), forme lungi în modal (don' t), foaie pentru extinderea contextului (do).
Scurt rezumat
Modalka - pentru decizii sub atenție deplină, sertar - pentru a extinde contextul fără a rupe fluxul. Păstrați structura simplă, CTA lipsită de ambiguitate, și interacțiuni previzibile și accesibile. Respectați performanța, blocați fundalul și returnați focalizarea. În scenariile iGaming, acest lucru afectează în mod direct încrederea: confirmările de pariuri, cashout, selecția metodei de plată și KYC trebuie să fie corecte, rapide și sigure.