Maski wejściowe i formularze UX
1) Zasady
1. Pomoc, nie karanie. Maska prowadzi wejście i zmniejsza błędy, ale nie blokuje drukowania i wstawiania.
2. Wyświetlanie danych. Przechowujemy „surowe” wartości znormalizowane, format tylko w interfejsie użytkownika.
3. Przewidywalny kursor. Każda auto-substytucja nie „skoczyć” caret lub przerwać cofnąć/redo.
4. Locale i urządzenie. Klawiatury, dzielniki, kalendarz i waluty - według regionu i platformy.
5. Dostępność i prywatność. Tekst + ikona/kolor; Maskujemy pola wrażliwe, ale nie zakłócamy menedżerów haseł/autocomplete.
2) Kiedy maska jest odpowiednia (a kiedy nie)
Zastosowanie:- Formaty o stabilnej strukturze: telefon, IBAN, PAN (karty), CVC, data, czas, indeks, OTP.
- Kwoty pieniężne z separatorami (przy drukowaniu - „czyste” wejście, gdy rozmyte - format).
- Kody (ref. kody, promo), stałe długości.
- Nazwy/adresy/Email (maska ogranicza ważne znaki/języki).
- Kompleks wolnych pól (komentarze, nazwy firm).
- Dane wejściowe o potencjalnie nieznanym formacie (numery międzynarodowe bez kraju).
3) Maska vs auto format vs walidacja
Maska - podpowiedź struktury na lotce (wsporniki, łączniki); nie wolno łamać wejścia/włożenia.
Automatyczny format - zastosowanie do rozmycia/utraty ostrości (tysiące, przestrzeń IBAN).
Walidacja - logika poprawności (długość, sumy kontrolne), pokazująca błędy po 'rozmycie' lub 'przesłanie'.
Reguła: maska nie zastępuje walidacji, a autoformat nie powinien zmieniać znaczenia wprowadzonego.
4) klawiatury HTML i atrybuty
Wybierz odpowiednie typy/tryby, aby przyspieszyć wejście i zmniejszyć błędy:5) Przewóz, pasta do kopiowania i normalizacja
Nie łamać caret: podczas automatycznego wstawiania znaków (spacje/wsporniki), ustawić pozycję kursora.
Skopiuj pastę: podczas wstawiania przezroczyste przestrzenie/łączniki → zwaliduj → wyświetlacz z formatowaniem.
Normalizacja: przycinanie, wymiana „krzywych” znaków ('O' → '0' nie może być!), tłumaczenie na górny przypadek dla IBAN, jednolity format daty przechowywania (ISO).
js const clean = s => s. replace(/[^\da-zA-Z]/g,'');
const normalizePAN = s => clean(s). slice (0.19) ;//no spaces/hyphens const normalizeIBAN = s => clean (s). toUpperCase(); // A–Z0–9
6) Numery, waluty i lokalizacje
Wejście „w formie zadrukowanej” (tolerancja „,” lub „” jako separator), przechowywanie w małych jednostkach (kopce/centy).
mapowanie lokalne (grupowanie tysięcy) na rozmycie/po złożeniu; w ostrości, pokazać „surową” wartość dla łatwości edycji.
Wyraźnie określić walutę i ustalić dokładność (na przykład 2 znaki).
js function parseMoney(input) {
//resolve both comma and period as decimal const s = input. replace(/\s/g,''). replace(',', '.');
const num = Number(s);
if (Number. isNaN(num)) return null;
return Math. round(num 100); // cents
}
function formatMoney(cents, locale='ru-RU', currency='RUB') {
return (cents/100). toLocaleString(locale, { style:'currency', currency });
}
7) Daty i czasy
Jeśli rodzime zbieracze są niewygodne/różne na platformach - użyj pola tekstowego z maską 'DD. MM. RRRR ', ale zachować ISO' RRRR-MM-DD'.
Sprawdzenie rzeczywistości daty (29. 02, zakresy), timezony - na serwerze.
Dodaj przyciski „Today”, „Now”, „Clear”.
8) Telefony i kraje
Dwa pola: kraj (+ kod) i numer lub inteligentna maska dla wybranego kraju.
Wstawiając pełny '+ CC...', autokompletuj kraj.
Przechowywać E.164 ('+ CCXXXXXXXXX'), pokazywać lokalnie za pomocą spacji.
9) Szczegóły płatności: PAN/IBAN/CVC/EXP
PAN: 4-4-4-4/4 ugrupowanie; w wartości - tylko liczby; Luhn-check; brak dzienników/analiz z PAN.
CVC: 'hasło' - styl (ukryty), 'autocomplete =' cc-csc' ', nie zapisuj do draftu.
Termin ważności: 'MM/YY', automatyczne wstawianie '/' po 2 cyfrach, zakres kontroli 01-12 i rozsądny rok.
IBAN: górny etui, przestrzenie tylko w interfejsie użytkowym; Sprawdź długość według kraju i checksum.
10) OTP/kod potwierdzający
6 (lub N) komórek z autofokusem i automatycznym przejściem, wklejanie z bufora rozpoznaje cały kod.
"autocomplete =" jednorazowy kod ", na telefonach komórkowych - automatyczna ekstrakcja z SMS.
Kopia zapasowa bez pola podzielonego (jedno pole) - dla czytników ekranu.
html
<div class="otp" role="group" aria-label="Код из SMS">
<input inputmode="numeric" maxlength="1">
<input inputmode="numeric" maxlength="1">
<!-- … -->
</div>
11) Maski i a11y
Etykieta jest wymagana („<label for>”), łożysko jest przykładem, a nie zamiennikiem.
Wytłumacz regułę obok siebie: tekst pomocnika z przykładem („Format: + CC МУЙ, БИ-Б, Δ-М,”).
Powiązać błędy za pomocą 'aria-descripedby', critical - 'role =' alert '.
Kontrast tekstu i konturów ≥ AA, ': focus-visible' nie może być ukryty.
12) Prywatność i bezpieczeństwo
Pola wrażliwe: nie loguj się, nie pisz do RUM, nie zapisuj do redakcji (PAN, CVC, paszport).
Maski i formatowanie nie powinny ujawniać ważności konta („Jeśli e-mail jest zarejestrowany”... - sformułowanie neutralne).
Idempotencja i ponowna próba dla submitów krytycznych (płatność/stawka).
13) Zachowanie formy i wydajność
Obciążenie kontrolami asynchronicznymi (250-400 ms), widoczne oznaczenie „Sprawdź”....
Nie blokuj całego ekranu dla dobra jednego pola; lokalny spinner/szkielet.
Zmiany partii DOM; animować tylko „przekształcić/nieprzezroczystość”.
Na telefonie komórkowym - unikaj „skoków”, gdy pojawia się klawiatura (bezpieczna strefa, meta portu).
14) Snippety kodowe
Miękka maska telefonu (bez uszkodzenia wkładki):js function formatPhoneVisible(value) {
const d = value. replace(/\D/g,''). slice(0,15);
if (!d) return '';
if (d. startsWith('7') d. startsWith('8')) {
return d. replace(/^([78])? (\d{3})(\d{3})(\d{2})(\d{2})./, '+7 ($2) $3-$4-$5');
}
// generic E.164 grouping: +CC XXX XXX XX XX return d. replace(/^(\d{1,3})(\d{0,3})(\d{0,3})(\d{0,2})(\d{0,2})./, (m,c1,c2,c3,c4,c5)=>
`+${c1}${c2?` ${c2}`:''}${c3?` ${c3}`:''}${c4?` ${c4}`:''}${c5?` ${c5}`:''}`.trim());
}
const input = document. querySelector('#phone');
input. addEventListener('input', e => {
const raw = e. target. value;
const pos = e. target. selectionStart;
const digitsBefore = raw. slice(0,pos). replace(/\D/g,''). length;
const cleaned = raw. replace(/[^\d+]/g,'');
const visible = formatPhoneVisible(cleaned);
e. target. value = visible;
// restore caret by counting digits let p = 0, count = 0;
while (p < e. target. value. length && count < digitsBefore) { if (/\d/.test(e. target. value[p])) count++; p++; }
e. target. setSelectionRange(p, p);
});
Ilość: „raw in focus → format with smur”:
js const amount = document. getElementById('amount');
let cents = null;
amount. addEventListener('focus', () => {
if (cents!=null) amount. value = String(cents/100). replace('.', ',');
});
amount. addEventListener('blur', () => {
const v = parseMoney(amount. value) ;//from section 6 if (v = = null) return; cents = v;
amount. value = formatMoney(cents, 'ru-RU', 'RUB');
});
IBAN: górny etap i zgrupowanie pod zacieraniem:
js const iban = document. getElementById('iban');
iban. addEventListener('input', () => iban. value = iban. value. toUpperCase());
iban. addEventListener('blur', () => {
const raw = normalizeIBAN(iban. value);
iban. dataset. raw = raw ;//for iban submission. value = raw. replace(/(.{4})/g,'$1 '). trim () ;//view only
});
15) Żetony systemu projektowania (przykład)
json
{
"input": {
"radius": 10,
"height": { "sm": 36, "md": 40, "lg": 48 },
"gap": 8,
"icon": 16
},
"mask": {
"debounceMs": 300,
"otpLength": 6,
"moneyPrecision": 2,
"phoneMaxDigits": 15
},
"a11y": {
"focusRing": { "width": 2, "offset": 2 },
"contrastAA": true
}
}
Ustawienia wstępne CSS:
css
.input { height:40px; padding:0 12px; border-radius:10px; }
.input:focus-visible { outline:2px solid var(--focus-ring); outline-offset:2px; }
.field-error { color: var(--role-danger); font-size:.875rem; margin-top:6px; }
.otp input { width:40px; text-align:center; }
16) Specyfika iGaming
Płatności/wypłaty: PAN/IBAN/kwota z miękkimi maskami; ścisłej idempotencji i braku delikatnych dzienników terenowych; wskazówki dotyczące prowizji i terminów.
KYC: maski do dat, numery paszportów (bez „twardego” filtrowania - biorąc pod uwagę różne formaty), rozmiar/typ pliku, podgląd.
Limity i odpowiedzialne zabawy: zrozumiałe ilości/okresy (dni/tygodnie/miesiące), pomocnicy w pobliżu, kontrast AAA.
Zakłady: szybkie wpisanie kwoty (ustawienia wstępne + pole), w ostrości „surowy” numer, przy zacieraniu formatu według lokalizacji; brak dopuszczenia, "...../podwójnego separatora.
17) Anty-wzory
Maski twarde, które zaprzeczają poprawnym znakom/wstawianiu.
Skacząca caret z formatem auto; utrata ekstrakcji/cofnięcie.
Odtwórca zamiast etykiety.
Automatyczne dodawanie waluty wewnątrz wartości (łamie pastę kopiującą).
Błędy „na znak” bez debunkingu.
Lokalnie zależne formaty w magazynie (przechowywać ISO/numery).
Rejestrowanie numerów PAN/paszportowych i wykazanie „zbyt uczciwych” powodów odrzucenia.
18) Metryki i eksperymenty
Błąd według pól (przed/po masce).
Formularze i resubmisje od czasu do końca.
Odsetek nieudanych wkładek (pasta do kopiowania) i wałków (cofnąć).
CTR wskazówek/przykładów, odsetek autokompletów.
Opuścić stawkę w kroku płatności/ACC.
19) Lista kontrolna QA
Wejście i caret
- Wklejanie z bufora nie pęka, miejsca/łączniki są poprawnie oczyszczone.
- Caret pozostaje przewidywalny po automatycznym formacie.
Lokalizacja i format
- Kwoty pozwalają ", "/"; przechowywanie w małych jednostkach.
- Daty są przerywane i zatwierdzane; przechowywanie w ISO.
A11y
- Etykiety i „aria-description by” są połączone; 'role = „alert” dla krytycznych.
- Pierścienie kontrastu i ostrości odpowiadają AA.
Bezpieczeństwo
- Pola wrażliwe nie są rejestrowane/buforowane.
- Idempotencja i ponowna próba na krytycznych etapach.
UX
- Pośrednik - przykład, a nie etykieta; pomocnik w pobliżu.
- Maski nie zapobiegają drukowaniu na telefonach komórkowych; poprawne klawiatury ('inputmode').
20) Dokumentacja w systemie projektowym
Кобонента: "Mas, Input", "," PhoneInput "," OtpInput "," IbanInput ".
Żetony maski (długości/wzory), zasady caret/insert, lokalizacja numeru/daty.
Przewodniki dla prywatności (czego nie zalogować), dostępności i autoformatu vs blur.
„Do/Don” z prawdziwymi przykładami i przed/po metrykach.
Krótkie podsumowanie
Maski i kształty są dobre, gdy przyspieszają wejście, zachowują czystość danych i nie przeszkadzają. Format starannie, normalizować przy wejściu, przechowywać w stabilnych formach, wziąć pod uwagę lokalizacje i dostępność. Następnie formularze stają się szybkie i proste - zwłaszcza w przypadku płatności wrażliwych, KYC i scenariuszy zakładów.