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

  1. 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”)
  2. Ú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
  3. 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
  4. 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
  5. 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ó

&lt;!-- ROSSZ GYAKORLAT - Nincs jelszó megjelenítés opció --&gt;
&lt;label for="password"&gt;Jelszó:&lt;/label&gt;
&lt;input type="password" id="password" name="password"&gt;
&lt;label for="password-confirm"&gt;Jelszó újra:&lt;/label&gt;
&lt;input type="password" id="password-confirm" name="password_confirm"&gt;
&lt;!-- Nincs mód a jelszavak megtekintésére --&gt;
</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>
&lt;div class="password-toggle" onclick="togglePassword()"&gt;
  &lt;img src="eye-icon.png" alt=""&gt; &lt;!-- Üres alt, nem billentyűzet hozzáférhető --&gt;
&lt;/div&gt;
&lt;!-- ROSSZ GYAKORLAT - Hiányzó vagy rossz hibaüzenetek --&gt;
&lt;form onsubmit="validateForm()"&gt;
  &lt;input type="password" id="pwd1"&gt;
  &lt;input type="password" id="pwd2"&gt;
  &lt;button type="submit"&gt;Küldés&lt;/button&gt;
&lt;/form&gt;
&lt;script&gt;
  function validateForm() {
    if (document.getElementById('pwd1').value !== document.getElementById('pwd2').value) {
      alert('Hiba!'); // Nem specifikus, nem hozzáférhető
      return false;
    }
  }
&lt;/script&gt;</code></pre>
<!-- /wp:code -->

Források

https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry.html”

https://www.w3.org/WAI/WCAG22/quickref/#redundant-entry”

Iratkozz fel hírlevelünkre!

Amennyiben szeretnél első kézből értesülni az új bejegyzésekről, iratkozz fel hírlevelünkre!

Ez a weboldal sütiket használ a böngészési élmény javítása és a webhely megfelelő működésének biztosítása érdekében. A webhely használatának folytatásával elismeri és elfogadja a sütik használatát.

Összes elfogadása Csak a szükségesek elfogadása