3.3.7 - Redundáns adatbevitel
Röviden a szabványpontról
A WCAG 2.2 Success Criterion 3.3.7 (Redundant Entry) megköveteli, hogy amikor a felhasználóknak ugyanazt az információt többször kell megadniuk – például egy jelszó megadása és megerősítése esetén – a folyamatnak biztosítania kell egy módot a redundáns bevitel elkerülésére. Ez azt jelenti, hogy a felhasználóknak lehetőséget kell adni a korábban megadott adatok újrafelhasználására, vagy olyan mechanizmust kell biztosítani, amely lehetővé teszi a bevitel megjelenítését/elrejtését (mint a jelszavak esetében) a hibák és az erőfeszítés csökkentése érdekében.
Cél: Csökkenteni a kognitív terhelést és a potenciális frusztrációt azoknál a felhasználóknál, akiknek memória-, kézügyességi vagy figyelmi korlátaik vannak. A redundáns adatbevitel elkerülése javítja a használhatóságot és csökkenti a hibalehetőségeket.
Mire vonatkozik: Elsősorban űrlapokra és interaktív tartalmakra, ahol gyakoriak az ismétlődő adatbevitelek, mint például regisztrációs űrlapok, jelszó-visszaállítások vagy pénzügyi tranzakciók.
Kiket érint
Elsődleges felhasználók: Kognitív fogyatékossággal, memóriaproblémákkal vagy mozgásszervi nehézségekkel élő emberek, akik számára kihívást jelent az információk pontos megjegyzése vagy újragépelése.
Másodlagos előnyök: Minden felhasználó számára előnyös a csökkentett súrlódás az űrlapok kitöltése során, kevesebb hiba és jobb használhatóság, különösen mobileszközökön vagy kis képernyőkön.
Tesztelés
- Redundáns mezők azonosítása: Keress olyan űrlapmezőket, amelyek ugyanannak az információnak az ismételt bevitelét igénylik (pl. „Jelszó” és „Jelszó megerősítése”)
- Újrafelhasználási opciók ellenőrzése: Ellenőrizd, hogy az űrlap biztosít-e módot az újragépelés elkerülésére, például „Jelszó megjelenítése” kapcsoló vagy másolási mechanizmus
- Megjelenítés/elrejtés funkció tesztelése: Biztosítsd, hogy a „Jelszó megjelenítése” vezérlő billentyűzettel elérhető és megfelelően címkézett a kisegítő technológiák számára
- Másolás-beillesztés tesztelése: Erősítsd meg, hogy a felhasználók korlátozás nélkül beilleszthetik az eredeti bejegyzést a megerősítő mezőbe
- Hibamegelőzés validálása: Küld be az űrlapot nem egyező bejegyzésekkel és ellenőrizd, hogy világos hibaüzenetek vezetik-e a felhasználókat a probléma kijavításában
Jó gyakorlatok
1. Jelszó megjelenítése/elrejtése kapcsoló
<!-- REGISZTRÁCIÓS ŰRLAP - Jelszó megjelenítési opcióval -->
<form id="regisztracio-form" class="user-form" novalidate>
<div class="form-section">
<h2>Új fiók létrehozása</h2>
<div class="form-group">
<label for="felhasznalonev">Felhasználónév *</label>
<input
type="text"
id="felhasznalonev"
name="felhasznalonev"
required
aria-describedby="felhasznalonev-help"
autocomplete="username"
>
<div id="felhasznalonev-help" class="field-help">
3-20 karakter, csak betűk és számok
</div>
</div>
<div class="form-group jelszо-csoport">
<label for="jelszo">Jelszó *</label>
<div class="jelszо-mezo-wrapper">
<input
type="password"
id="jelszo"
name="jelszo"
required
minlength="8"
aria-describedby="jelszo-help jelszo-error"
autocomplete="new-password"
class="jelszо-mezo"
>
</div>
<div id="jelszo-help" class="field-help">
Legalább 8 karakter, tartalmaz számot és nagybetűt
</div>
<div id="jelszo-error" class="error-message" role="alert" style="display: none;"></div>
</div>
<div class="form-group jelszо-csoport">
<label for="jelszo-megersites">Jelszó megerősítése *</label>
<div class="jelszо-mezo-wrapper">
<input
type="password"
id="jelszo-megersites"
name="jelszo_megersites"
required
aria-describedby="jelszo-megersites-help jelszo-megersites-error"
autocomplete="new-password"
class="jelszо-mezo"
>
</div>
<div id="jelszo-megersites-help" class="field-help">
Írja be újra a jelszót a megerősítéshez
</div>
<div id="jelszo-megersites-error" class="error-message" role="alert" style="display: none;"></div>
</div>
<!-- Jelszavak megjelenítése/elrejtése gomb -->
<div class="form-control">
<button
type="button"
id="jelszavak-mutatasa"
class="toggle-button"
aria-pressed="false"
aria-controls="jelszo jelszo-megersites"
>
<svg aria-hidden="true" class="icon-eye" width="20" height="20">
<path d="M10 5C5 5 1.73 8.11 1 12c.73 3.89 4 7 9 7s8.27-3.11 9-7c-.73-3.89-4-7-9-7zm0 11.5c-2.48 0-4.5-2.02-4.5-4.5s2.02-4.5 4.5-4.5 4.5 2.02 4.5 4.5-2.02 4.5-4.5 4.5zm0-7.2c-1.49 0-2.7 1.21-2.7 2.7s1.21 2.7 2.7 2.7 2.7-1.21 2.7-2.7-1.21-2.7-2.7-2.7z"/>
</svg>
<span class="toggle-text">Jelszavak megjelenítése</span>
</button>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">Regisztráció</button>
</div>
</form>
<!-- JAVASCRIPT A JELSZÓ MEGJELENÍTÉSHEZ -->
<script>
const toggleGomb = document.getElementById('jelszavak-mutatasa');
const jelszоMezok = [
document.getElementById('jelszo'),
document.getElementById('jelszo-megersites')
];
const toggleText = toggleGomb.querySelector('.toggle-text');
toggleGomb.addEventListener('click', function() {
const jelenlegMutat = toggleGomb.getAttribute('aria-pressed') === 'true';
const ujAllapot = !jelenlegMutat;
// ARIA attribútum frissítése
toggleGomb.setAttribute('aria-pressed', ujAllapot);
// Jelszó mezők típusának változtatása
jelszоMezok.forEach(mezo => {
mezo.type = ujAllapot ? 'text' : 'password';
});
// Gomb szövegének frissítése
toggleText.textContent = ujAllapot ? 'Jelszavak elrejtése' : 'Jelszavak megjelenítése';
// Képernyőolvasó értesítése
const ertesites = document.createElement('span');
ertesites.setAttribute('role', 'status');
ertesites.setAttribute('aria-live', 'polite');
ertesites.classList.add('sr-only');
ertesites.textContent = ujAllapot ?
'Jelszavak láthatóvá váltak' :
'Jelszavak elrejtve';
document.body.appendChild(ertesites);
setTimeout(() => {
document.body.removeChild(ertesites);
}, 1000);
});
// Űrlap validálás
const regForm = document.getElementById('regisztracio-form');
regForm.addEventListener('submit', function(esemeny) {
esemeny.preventDefault();
const jelszo = document.getElementById('jelszo').value;
const jelszoMeg = document.getElementById('jelszo-megersites').value;
// Jelszavak egyezésének ellenőrzése
if (jelszo !== jelszoMeg) {
const hibaElem = document.getElementById('jelszo-megersites-error');
hibaElem.textContent = 'A két jelszó nem egyezik. Kérjük, ellenőrizze őket.';
hibaElem.style.display = 'block';
document.getElementById('jelszo-megersites').focus();
return;
}
// Sikeres regisztráció
alert('Regisztráció sikeres!');
});
</script>
<!-- CSS A JOBB MEGJELENÉSÉRT -->
<style>
.jelszо-csoport {
position: relative;
}
.jelszо-mezo-wrapper {
position: relative;
display: flex;
align-items: center;
}
.jelszо-mezo {
width: 100%;
padding-right: 40px;
}
.toggle-button {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: #f0f0f0;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
margin-top: 16px;
}
.toggle-button:hover {
background: #e0e0e0;
}
.toggle-button[aria-pressed="true"] {
background: #007bff;
color: white;
}
.toggle-button[aria-pressed="true"] svg {
fill: white;
}
.sr-only {
position: absolute;
left: -10000px;
width: 1px;
height: 1px;
overflow: hidden;
}
</style>
2. Másolás-beillesztés engedélyezése a mezők között
<!-- E-MAIL MEGERŐSÍTÉS - Másolás-beillesztés támogatással -->
<form id="email-valtoztatas" class="settings-form">
<div class="form-section">
<h2>E-mail cím megváltoztatása</h2>
<p>Biztonsági okokból kétszer kell megadnia az új e-mail címet.</p>
<div class="form-group">
<label for="uj-email">Új e-mail cím *</label>
<input
type="email"
id="uj-email"
name="uj_email"
required
aria-describedby="uj-email-help"
autocomplete="email"
>
<div id="uj-email-help" class="field-help">
Adja meg az új e-mail címét
</div>
</div>
<div class="form-group">
<label for="email-megersites">E-mail cím megerősítése *</label>
<input
type="email"
id="email-megersites"
name="email_megersites"
required
aria-describedby="email-megersites-help email-megersites-error"
autocomplete="email"
>
<!-- FONTOS: Nincs onpaste="return false;" vagy hasonló korlátozás! -->
<div id="email-megersites-help" class="field-help">
Írja be újra az e-mail címet vagy másolja be a fenti mezőből
</div>
<div id="email-megersites-error" class="error-message" role="alert" style="display: none;"></div>
</div>
<!-- Segítő információ a másolásról -->
<div class="info-box" role="region" aria-label="Hasznos tipp">
<svg aria-hidden="true" class="info-icon" width="20" height="20">
<circle cx="10" cy="10" r="9" fill="#007bff" opacity="0.1"/>
<text x="10" y="15" text-anchor="middle" fill="#007bff" font-weight="bold">i</text>
</svg>
<p>Tipp: Használhatja a Ctrl+C (másolás) és Ctrl+V (beillesztés) billentyűkombinációkat az e-mail cím gyors megadásához a második mezőben.</p>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">E-mail cím megváltoztatása</button>
<button type="button" class="btn-secondary" onclick="history.back()">Mégse</button>
</div>
</form>
<script>
const emailForm = document.getElementById('email-valtoztatas');
const ujEmail = document.getElementById('uj-email');
const emailMegersites = document.getElementById('email-megersites');
const emailError = document.getElementById('email-megersites-error');
// Valós idejű ellenőrzés
emailMegersites.addEventListener('input', function() {
if (this.value && ujEmail.value && this.value !== ujEmail.value) {
emailError.textContent = 'Az e-mail címek nem egyeznek meg.';
emailError.style.display = 'block';
} else {
emailError.style.display = 'none';
}
});
// Űrlap beküldés
emailForm.addEventListener('submit', function(esemeny) {
esemeny.preventDefault();
if (ujEmail.value !== emailMegersites.value) {
emailError.textContent = 'Az e-mail címek nem egyeznek meg. Kérjük, ellenőrizze őket.';
emailError.style.display = 'block';
emailMegersites.focus();
return;
}
// Sikeres változtatás
alert('E-mail cím sikeresen megváltoztatva!');
});
// Másolás esemény figyelése (opcionális - statisztikához)
ujEmail.addEventListener('copy', function() {
console.log('E-mail cím másolva');
});
emailMegersites.addEventListener('paste', function() {
console.log('E-mail cím beillesztve');
// Kis késleltetés után ellenőrizzük az egyezést
setTimeout(() => {
if (this.value === ujEmail.value) {
emailError.style.display = 'none';
}
}, 10);
});
</script>
3. Világos hibaüzenetek nem egyező bejegyzések esetén
<!-- JELSZÓ VÁLTOZTATÁS - Részletes hibaüzenetekkel -->
<form id="jelszo-valtoztatas-form" class="secure-form" novalidate>
<div class="form-section">
<h2>Jelszó megváltoztatása</h2>
<!-- Összefoglaló hibaüzenetek -->
<div id="osszefoglalo-hibak" class="error-summary" role="alert" aria-live="assertive" style="display: none;">
<h3>A következő hibákat találtuk:</h3>
<ul id="hiba-lista"></ul>
</div>
<div class="form-group">
<label for="regi-jelszo">Jelenlegi jelszó *</label>
<input
type="password"
id="regi-jelszo"
name="regi_jelszo"
required
aria-describedby="regi-jelszo-error"
autocomplete="current-password"
>
<div id="regi-jelszo-error" class="error-message" role="alert" style="display: none;"></div>
</div>
<div class="form-group">
<label for="uj-jelszo">Új jelszó *</label>
<input
type="password"
id="uj-jelszo"
name="uj_jelszo"
required
minlength="8"
aria-describedby="uj-jelszo-help uj-jelszo-error uj-jelszo-strength"
autocomplete="new-password"
>
<div id="uj-jelszo-help" class="field-help">
Legalább 8 karakter, tartalmaz számot, kis- és nagybetűt
</div>
<div id="uj-jelszo-strength" class="password-strength" aria-live="polite"></div>
<div id="uj-jelszo-error" class="error-message" role="alert" style="display: none;"></div>
</div>
<div class="form-group">
<label for="uj-jelszo-megersites">Új jelszó megerősítése *</label>
<input
type="password"
id="uj-jelszo-megersites"
name="uj_jelszo_megersites"
required
aria-describedby="uj-jelszo-megersites-help uj-jelszo-megersites-error"
autocomplete="new-password"
>
<div id="uj-jelszo-megersites-help" class="field-help">
Írja be újra az új jelszót a megerősítéshez
</div>
<div id="uj-jelszo-megersites-error" class="error-message" role="alert" style="display: none;"></div>
</div>
<!-- Jelszó megjelenítés opció -->
<div class="form-control">
<label>
<input type="checkbox" id="jelszo-lathato" aria-controls="uj-jelszo uj-jelszo-megersites">
Új jelszavak megjelenítése
</label>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">Jelszó megváltoztatása</button>
<button type="button" class="btn-secondary" onclick="history.back()">Mégse</button>
</div>
</form>
<script>
const jelszoForm = document.getElementById('jelszo-valtoztatas-form');
const regiJelszo = document.getElementById('regi-jelszo');
const ujJelszo = document.getElementById('uj-jelszo');
const ujJelszoMeg = document.getElementById('uj-jelszo-megersites');
const jelszoLathato = document.getElementById('jelszo-lathato');
const osszefoglaloHibak = document.getElementById('osszefoglalo-hibak');
const hibaLista = document.getElementById('hiba-lista');
// Jelszó megjelenítés kapcsoló
jelszoLathato.addEventListener('change', function() {
const tipus = this.checked ? 'text' : 'password';
ujJelszo.type = tipus;
ujJelszoMeg.type = tipus;
});
// Jelszó erősség ellenőrzés
ujJelszo.addEventListener('input', function() {
const jelszo = this.value;
const erosssegElem = document.getElementById('uj-jelszo-strength');
let erosseg = 0;
let uzenet = '';
if (jelszo.length >= 8) erosseg++;
if (/[a-z]/.test(jelszo)) erosseg++;
if (/[A-Z]/.test(jelszo)) erosseg++;
if (/[0-9]/.test(jelszo)) erosseg++;
if (/[^a-zA-Z0-9]/.test(jelszo)) erosseg++;
switch(erosseg) {
case 0:
case 1:
uzenet = 'Gyenge jelszó';
erosssegElem.className = 'password-strength weak';
break;
case 2:
case 3:
uzenet = 'Közepes erősségű jelszó';
erosssegElem.className = 'password-strength medium';
break;
case 4:
case 5:
uzenet = 'Erős jelszó';
erosssegElem.className = 'password-strength strong';
break;
}
erosssegElem.textContent = jelszo.length > 0 ? uzenet : '';
});
// Valós idejű megerősítés ellenőrzés
ujJelszoMeg.addEventListener('input', function() {
const megError = document.getElementById('uj-jelszo-megersites-error');
if (this.value && ujJelszo.value && this.value !== ujJelszo.value) {
megError.textContent = 'Az új jelszavak nem egyeznek. Kérjük, ellenőrizze a gépelést.';
megError.style.display = 'block';
this.setAttribute('aria-invalid', 'true');
} else {
megError.style.display = 'none';
this.removeAttribute('aria-invalid');
}
});
// Űrlap beküldés
jelszoForm.addEventListener('submit', function(esemeny) {
esemeny.preventDefault();
const hibak = [];
hibaLista.innerHTML = '';
// Régi jelszó ellenőrzés
if (!regiJelszo.value) {
hibak.push({
mezo: 'regi-jelszo',
uzenet: 'A jelenlegi jelszó megadása kötelező.'
});
}
// Új jelszó ellenőrzés
if (ujJelszo.value.length < 8) {
hibak.push({
mezo: 'uj-jelszo',
uzenet: 'Az új jelszó legalább 8 karakter hosszú legyen.'
});
}
// Jelszavak egyezése
if (ujJelszo.value !== ujJelszoMeg.value) {
hibak.push({
mezo: 'uj-jelszo-megersites',
uzenet: 'Az új jelszavak nem egyeznek meg. Kérjük, írja be mindkét mezőbe ugyanazt a jelszót.'
});
}
// Hibák megjelenítése
if (hibak.length > 0) {
hibak.forEach(hiba => {
// Egyedi hibaüzenet
const hibaElem = document.getElementById(hiba.mezo + '-error');
hibaElem.textContent = hiba.uzenet;
hibaElem.style.display = 'block';
// Összefoglaló lista
const li = document.createElement('li');
const link = document.createElement('a');
link.href = '#' + hiba.mezo;
link.textContent = hiba.uzenet;
link.addEventListener('click', function(e) {
e.preventDefault();
document.getElementById(hiba.mezo).focus();
});
li.appendChild(link);
hibaLista.appendChild(li);
});
osszefoglaloHibak.style.display = 'block';
osszefoglaloHibak.focus();
} else {
// Sikeres változtatás
alert('Jelszó sikeresen megváltoztatva!');
}
});
</script>
<!-- CSS A JELSZÓ ERŐSSÉG MEGJELENÍTÉSHEZ -->
<style>
.password-strength {
font-size: 14px;
margin-top: 4px;
padding: 4px 8px;
border-radius: 4px;
display: inline-block;
}
.password-strength.weak {
background-color: #ffcccb;
color: #d8000c;
}
.password-strength.medium {
background-color: #ffe4b5;
color: #ff8c00;
}
.password-strength.strong {
background-color: #90ee90;
color: #006400;
}
.error-summary {
background-color: #f8d7da;
border: 1px solid #f5c6cb;
color: #721c24;
padding: 16px;
border-radius: 4px;
margin-bottom: 20px;
}
.error-summary h3 {
margin-top: 0;
margin-bottom: 12px;
}
.error-summary ul {
margin: 0;
padding-left: 20px;
}
.error-summary a {
color: #721c24;
text-decoration: underline;
}
</style>
Rossz gyakorlatok
Kerülendő megoldások:
- Másolás-beillesztés blokkolása: A felhasználók megakadályozása abban, hogy beilleszthessék az első mezőben megadott jelszavukat a megerősítő mezőkbe, ami redundáns gépelésre kényszerít a felhasználót és így növeli a hibalehetőséget
- Megjelenítés/elrejtés kapcsoló hiánya: Jelszó mezők megjelenítési opció nélkül megnehezítik a felhasználók számára a bejegyzések ellenőrzését
- Homályos vagy hiányzó hibaüzenetek: Kihagyni a felhasználók tájékozatását, amikor a bejegyzések nem egyeznek, vagy olyan helyre tenni a hibaüzeneteket, ahol nem hozzáférhetőkek számukra
- Nem hozzáférhető kapcsolók: Megjelenítés/elrejtés vezérlők, amelyek nem elérhetők billentyűzettel vagy hiányoznak belőlük az ARIA attribútumok és így összezavarják a kisegítő technológiák felhasználóit
Beillesztés blokkolása
<label for="email">E-mail:</label>
<input type="email" id="email" name="email">
<label for="email-confirm">E-mail megerősítése:</label>
<input
type="email"
id="email-confirm"
name="email_confirm"
onpaste="return false;" <!-- ROSSZ: Megakadályozza a beillesztést -->
>
Helytelen megoldás
Nincs jelszó megjelenítési opció.
ROSSZ GYAKORLAT - Nincs jelszó megjelenítés opció -->
<label for="password">Jelszó:</label>
<input type="password" id="password" name="password">
<label for="password-confirm">Jelszó újra:</label>
<input type="password" id="password-confirm" name="password_confirm">
<!-- Nincs mód a jelszavak megtekintésére -->
Nem hozzáférhető jelszó kapcsoló
<!-- ROSSZ GYAKORLAT - Nincs jelszó megjelenítés opció -->
<label for="password">Jelszó:</label>
<input type="password" id="password" name="password">
<label for="password-confirm">Jelszó újra:</label>
<input type="password" id="password-confirm" name="password_confirm">
<!-- Nincs mód a jelszavak megtekintésére -->
</code></pre>
<!-- /wp:code -->
<!-- wp:heading {"level":3} -->
<h3>Nem hozzáférhető jelszó kapcsoló</h3>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>
<div class="password-toggle" onclick="togglePassword()">
<img src="eye-icon.png" alt=""> <!-- Üres alt, nem billentyűzet hozzáférhető -->
</div>
<!-- ROSSZ GYAKORLAT - Hiányzó vagy rossz hibaüzenetek -->
<form onsubmit="validateForm()">
<input type="password" id="pwd1">
<input type="password" id="pwd2">
<button type="submit">Küldés</button>
</form>
<script>
function validateForm() {
if (document.getElementById('pwd1').value !== document.getElementById('pwd2').value) {
alert('Hiba!'); // Nem specifikus, nem hozzáférhető
return false;
}
}
</script></code></pre>
<!-- /wp:code -->
Források
https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry.html”
Iratkozz fel hírlevelünkre!
Amennyiben szeretnél első kézből értesülni az új bejegyzésekről, iratkozz fel hírlevelünkre!