3.2.4 - Következetes azonosítás

Röviden a szabványpontról

A WCAG 2.2 Success Criterion 3.2.4 (Consistent Identification) megköveteli, hogy azok a felhasználói felület komponensek, amelyeket több weboldal között ismételten használnak, konzisztensen legyenek azonosítva. Ez azt jelenti, hogy az ugyanazon funkciót betöltő komponensek, mint a gombok, linkek, ikonok és egyéni vezérlők, minden előfordulási helyükön ugyanazokkal a címkékkel, nevekkel vagy leírásokkal kell rendelkezniük.

Cél: Csökkenteni a felhasználók zavarát és hibáit azzal, hogy kiszámítható és egységes felhasználói élményt biztosítunk. A konzisztens azonosítás segíti a felhasználókat abban, hogy megjegyezzék és helyesen használják az ismétlődő komponenseket.

Mire vonatkozik: Minden olyan webes tartalomra, ahol felhasználói felület komponenseket újra használnak, beleértve a látható címkéket és a nem látható címkéket, mint az alt szöveg vagy aria-label attribútumok.

Kiket érint

Elsődleges felhasználók: Kognitív fogyatékossággal élő emberek, gyengénlátók, képernyőolvasó felhasználók és kizárólag billentyűzetes felhasználók támaszkodnak a konzisztens címkézésre, hogy megértsék és előre jelezzék, hogyan lépjenek kapcsolatba a webhellyel.

Másodlagos előnyök: A konzisztens azonosítás javítja a használhatóságot mindenki számára azzal, hogy intuitívabbá teszi a navigációt és csökkenti a kognitív terhelést.

Tesztelés

  1. Manuális átvizsgálás: Navigálj különböző oldalakon és ellenőrizd, hogy az azonos funkciójú felhasználói felület komponensek azonos címkékkel és hozzáférhető nevekkel rendelkeznek
  2. Képernyőolvasó tesztelés: Használj képernyőolvasót annak ellenőrzésére, hogy az ismétlődő vezérlők hozzáférhető nevei (pl. aria-label, alt attribútumok) konzisztensek
  3. Automatizált eszközök: Használj akadálymentességi tesztelő eszközöket (mint az axe DevTools) az ismétlődő komponensek inkonzisztens címkézésének azonosítására
  4. Kód áttekintés: Vizsgáld meg a forráskódot, hogy megbizonyosodj arról, hogy az ismétlődő elemek ugyanazt a címkeszöveget vagy ARIA attribútumokat használják
  5. Felhasználói tesztelés: Figyelj meg fogyatékossággal élő felhasználókat, hogy lásd, okoznak-e zavarokat vagy hibákat az inkonzisztens címkék

Jó gyakorlatok

1. Konzisztens gomb címkék minden oldalon

<!-- ŰRLAP OLDAL -->
<form class="kapcsolat-form">
  <div class="form-group">
    <label for="nev">Teljes név:</label>
    <input type="text" id="nev" name="nev" required>
  </div>
  
  <div class="form-group">
    <label for="email">E-mail cím:</label>
    <input type="email" id="email" name="email" required>
  </div>
  
  <div class="form-group">
    <label for="uzenet">Üzenet:</label>
    <textarea id="uzenet" name="uzenet" rows="5" required></textarea>
  </div>
  
  <!-- KONZISZTENS gomb címke minden űrlapnál -->
  <button type="submit" aria-label="Űrlap elküldése">Küldés</button>
  <button type="reset" aria-label="Űrlap visszaállítása">Törlés</button>
</form>

<!-- REGISZTRÁCIÓS OLDAL - UGYANAZOK a gomb címkék -->
<form class="regisztracio-form">
  <div class="form-group">
    <label for="reg-felhasznalonev">Felhasználónév:</label>
    <input type="text" id="reg-felhasznalonev" name="felhasznalonev" required>
  </div>
  
  <div class="form-group">
    <label for="reg-email">E-mail cím:</label>
    <input type="email" id="reg-email" name="email" required>
  </div>
  
  <div class="form-group">
    <label for="reg-jelszo">Jelszó:</label>
    <input type="password" id="reg-jelszo" name="jelszo" required>
  </div>
  
  <!-- PONTOSAN UGYANAZOK a gomb címkék -->
  <button type="submit" aria-label="Űrlap elküldése">Küldés</button>
  <button type="reset" aria-label="Űrlap visszaállítása">Törlés</button>
</form>

<!-- HÍRLEVÉL FELIRATKOZÁS - KONZISZTENS címkék -->
<form class="hirlevel-form">
  <div class="form-group">
    <label for="hirlevel-email">E-mail címe a hírlevélhez:</label>
    <input type="email" id="hirlevel-email" name="email" required>
  </div>
  
  <div class="checkbox-group">
    <input type="checkbox" id="adatkezeles" name="adatkezeles" required>
    <label for="adatkezeles">Elfogadom az adatkezelési tájékoztatót</label>
  </div>
  
  <!-- UGYANAZOK a gomb címkék, még itt is -->
  <button type="submit" aria-label="Űrlap elküldése">Küldés</button>
  <button type="reset" aria-label="Űrlap visszaállítása">Törlés</button>
</form>

<!-- TERMÉK ÉRTÉKELÉS FORM -->
<form class="ertekeles-form">
  <div class="form-group">
    <label for="termek-ertekeles">Termék értékelése:</label>
    <select id="termek-ertekeles" name="ertekeles" required>
      <option value="">Válasszon értékelést</option>
      <option value="5">5 csillag - Kiváló</option>
      <option value="4">4 csillag - Jó</option>
      <option value="3">3 csillag - Elfogadható</option>
      <option value="2">2 csillag - Gyenge</option>
      <option value="1">1 csillag - Rossz</option>
    </select>
  </div>
  
  <div class="form-group">
    <label for="ertekeles-szoveg">Részletes vélemény:</label>
    <textarea id="ertekeles-szoveg" name="velemeny" rows="4"></textarea>
  </div>
  
  <!-- KONZISZTENCIA: még itt is ugyanazok a címkék -->
  <button type="submit" aria-label="Űrlap elküldése">Küldés</button>
  <button type="reset" aria-label="Űrlap visszaállítása">Törlés</button>
</form>

<style>
.form-group {
  margin-bottom: 1rem;
}

.form-group label {
  display: block;
  font-weight: bold;
  margin-bottom: 0.5rem;
}

.form-group input, .form-group select, .form-group textarea {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 1rem;
}

.checkbox-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.checkbox-group input[type="checkbox"] {
  width: auto;
}

button[type="submit"] {
  background: #28a745;
  color: white;
  border: none;
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  cursor: pointer;
  margin-right: 0.5rem;
}

button[type="reset"] {
  background: #6c757d;
  color: white;
  border: none;
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  cursor: pointer;
}

button:hover, button:focus {
  opacity: 0.9;
  outline: 2px solid #007bff;
  outline-offset: 2px;
}
</style>

Magyarázat: Minden űrlapon ugyanazt a „Küldés” és „Törlés” gombot használjuk ugyanazzal az aria-label attribútummal, így a felhasználók mindig tudják, mit várhatnak ezektől a gombaktól.

2. Konzisztens ikon címkézés navigációban

<!-- FŐOLDAL NAVIGÁCIÓ -->
<nav role="navigation" aria-label="Főnavigáció">
  <ul class="main-nav">
    <li>
      <a href="/fooldal" aria-label="Főoldalra ugrás">
        <svg class="nav-icon" aria-hidden="true">
          <use href="#home-icon"></use>
        </svg>
        <span>Főoldal</span>
      </a>
    </li>
    
    <li>
      <a href="/termekek" aria-label="Termékek oldalra ugrás">
        <svg class="nav-icon" aria-hidden="true">
          <use href="#products-icon"></use>
        </svg>
        <span>Termékek</span>
      </a>
    </li>
    
    <li>
      <a href="/kosar" aria-label="Bevásárlókosár megtekintése">
        <svg class="nav-icon" aria-hidden="true">
          <use href="#cart-icon"></use>
        </svg>
        <span>Kosár</span>
        <span class="cart-count" aria-label="3 termék a kosárban">3</span>
      </a>
    </li>
  </ul>
</nav>

<!-- TERMÉKEK OLDAL - UGYANAZOK az ikon címkék -->
<nav role="navigation" aria-label="Főnavigáció">
  <ul class="main-nav">
    <li>
      <!-- PONTOSAN UGYANAZ az aria-label -->
      <a href="/fooldal" aria-label="Főoldalra ugrás">
        <svg class="nav-icon" aria-hidden="true">
          <use href="#home-icon"></use>
        </svg>
        <span>Főoldal</span>
      </a>
    </li>
    
    <li>
      <!-- PONTOSAN UGYANAZ az aria-label -->
      <a href="/termekek" aria-current="page" aria-label="Termékek oldalra ugrás">
        <svg class="nav-icon" aria-hidden="true">
          <use href="#products-icon"></use>
        </svg>
        <span>Termékek</span>
      </a>
    </li>
    
    <li>
      <!-- PONTOSAN UGYANAZ az aria-label struktúra -->
      <a href="/kosar" aria-label="Bevásárlókosár megtekintése">
        <svg class="nav-icon" aria-hidden="true">
          <use href="#cart-icon"></use>
        </svg>
        <span>Kosár</span>
        <span class="cart-count" aria-label="5 termék a kosárban">5</span>
      </a>
    </li>
  </ul>
</nav>

<!-- MŰVELETI GOMBOK minden oldalon ugyanúgy -->
<div class="action-buttons">
  <!-- Szerkesztés gomb - mindig ugyanaz a címke -->
  <button class="edit-btn" aria-label="Tartalom szerkesztése">
    <svg aria-hidden="true">
      <use href="#edit-icon"></use>
    </svg>
    <span class="btn-text">Szerkesztés</span>
  </button>
  
  <!-- Törlés gomb - mindig ugyanaz a címke -->
  <button class="delete-btn" aria-label="Tartalom törlése" data-confirm="true">
    <svg aria-hidden="true">
      <use href="#delete-icon"></use>
    </svg>
    <span class="btn-text">Törlés</span>
  </button>
  
  <!-- Megosztás gomb - mindig ugyanaz a címke -->
  <button class="share-btn" aria-label="Tartalom megosztása">
    <svg aria-hidden="true">
      <use href="#share-icon"></use>
    </svg>
    <span class="btn-text">Megosztás</span>
  </button>
  
  <!-- Nyomtatás gomb - mindig ugyanaz a címke -->
  <button class="print-btn" aria-label="Oldal nyomtatása" onclick="window.print()">
    <svg aria-hidden="true">
      <use href="#print-icon"></use>
    </svg>
    <span class="btn-text">Nyomtatás</span>
  </button>
  
  <!-- Bezárás gomb - mindig ugyanaz a címke -->
  <button class="close-btn" aria-label="Ablak bezárása">
    <svg aria-hidden="true">
      <use href="#close-icon"></use>
    </svg>
    <span class="btn-text">Bezárás</span>
  </button>
</div>

<!-- SVG ikonok definíciói -->
<svg style="display: none;">
  <defs>
    <symbol id="home-icon" viewBox="0 0 24 24">
      <path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
    </symbol>
    
    <symbol id="products-icon" viewBox="0 0 24 24">
      <path d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/>
    </symbol>
    
    <symbol id="cart-icon" viewBox="0 0 24 24">
      <path d="M3 3h2l.4 2M7 13h10l4-8H5.4m0 0L7 13m0 0l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17M17 13v4a2 2 0 01-2 2H9a2 2 0 01-2-2v-4m8 0V9a2 2 0 00-2-2H9a2 2 0 00-2 2v4.01"/>
    </symbol>
    
    <symbol id="edit-icon" viewBox="0 0 24 24">
      <path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/>
      <path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/>
    </symbol>
    
    <symbol id="delete-icon" viewBox="0 0 24 24">
      <path d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
    </symbol>
    
    <symbol id="share-icon" viewBox="0 0 24 24">
      <path d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"/>
    </symbol>
    
    <symbol id="print-icon" viewBox="0 0 24 24">
      <path d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"/>
    </symbol>
    
    <symbol id="close-icon" viewBox="0 0 24 24">
      <path d="M6 18L18 6M6 6l12 12"/>
    </symbol>
  </defs>
</svg>

<style>
.main-nav {
  list-style: none;
  display: flex;
  gap: 1rem;
  padding: 0;
  margin: 0;
}

.main-nav a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  text-decoration: none;
  color: #495057;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.main-nav a:hover, .main-nav a:focus {
  background: #e9ecef;
  color: #007bff;
}

.main-nav a[aria-current="page"] {
  background: #007bff;
  color: white;
}

.nav-icon {
  width: 20px;
  height: 20px;
  fill: currentColor;
  stroke: currentColor;
  stroke-width: 2;
}

.cart-count {
  background: #dc3545;
  color: white;
  border-radius: 50%;
  padding: 0.2rem 0.5rem;
  font-size: 0.8em;
  font-weight: bold;
  min-width: 1.2em;
  text-align: center;
}

.action-buttons {
  display: flex;
  gap: 0.5rem;
  margin: 1rem 0;
  flex-wrap: wrap;
}

.action-buttons button {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border: 1px solid #dee2e6;
  background: white;
  color: #495057;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.action-buttons button:hover, .action-buttons button:focus {
  background: #f8f9fa;
  border-color: #007bff;
  outline: 2px solid #007bff;
  outline-offset: 2px;
}

.edit-btn:hover, .edit-btn:focus {
  background: #d4edda;
  border-color: #28a745;
  color: #155724;
}

.delete-btn:hover, .delete-btn:focus {
  background: #f8d7da;
  border-color: #dc3545;
  color: #721c24;
}

.share-btn:hover, .share-btn:focus {
  background: #d1ecf1;
  border-color: #17a2b8;
  color: #0c5460;
}

.print-btn:hover, .print-btn:focus {
  background: #fff3cd;
  border-color: #ffc107;
  color: #856404;
}

.close-btn:hover, .close-btn:focus {
  background: #e2e3e5;
  border-color: #6c757d;
  color: #383d41;
}

.action-buttons svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}

.btn-text {
  font-size: 0.9em;
}

@media (max-width: 768px) {
  .main-nav {
    flex-direction: column;
  }
  
  .action-buttons {
    justify-content: center;
  }
  
  .action-buttons button {
    flex: 1;
    justify-content: center;
    min-width: 120px;
  }
}
</style>

Magyarázat: Minden ikon és gomb ugyanazzal az aria-label értékkel van ellátva minden oldal navigációjában, biztosítva, hogy a felhasználók mindig tudják, mit tesznek az egyes elemek.

3. Konzisztens link szövegek és képek alt szövegei

<!-- FŐOLDAL - Navigációs linkek -->
<nav role="navigation" aria-label="Oldal navigáció">
  <ul class="page-nav">
    <li><a href="/fooldal">Főoldal</a></li>
    <li><a href="/rolunk">Rólunk</a></li>
    <li><a href="/szolgaltatasok">Szolgáltatások</a></li>
    <li><a href="/portfolio">Portfólió</a></li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/kapcsolat">Kapcsolat</a></li>
  </ul>
</nav>

<!-- SZOLGÁLTATÁSOK OLDAL - PONTOSAN UGYANAZOK a link szövegek -->
<nav role="navigation" aria-label="Oldal navigáció">
  <ul class="page-nav">
    <li><a href="/fooldal">Főoldal</a></li> <!-- Ugyanaz a szöveg -->
    <li><a href="/rolunk">Rólunk</a></li> <!-- Ugyanaz a szöveg -->
    <li><a href="/szolgaltatasok" aria-current="page">Szolgáltatások</a></li>
    <li><a href="/portfolio">Portfólió</a></li> <!-- Ugyanaz a szöveg -->
    <li><a href="/blog">Blog</a></li> <!-- Ugyanaz a szöveg -->
    <li><a href="/kapcsolat">Kapcsolat</a></li> <!-- Ugyanaz a szöveg -->
  </ul>
</nav>

<!-- KONZISZTENS képek alt szövegekkel minden oldalon -->
<div class="company-info">
  <h2>Csapatunk</h2>
  
  <div class="team-member">
    <!-- KONZISZTENS alt szöveg minden oldalon -->
    <img src="ceo-foto.jpg" alt="Kovács János ügyvezető portréfotója">
    <h3>Kovács János</h3>
    <p>Ügyvezető</p>
  </div>
  
  <div class="team-member">
    <!-- KONZISZTENS alt szöveg minden oldalon -->
    <img src="cto-foto.jpg" alt="Nagy Mária műszaki igazgató portréfotója">
    <h3>Nagy Mária</h3>
    <p>Műszaki igazgató</p>
  </div>
</div>

<!-- MŰVELETI GOMBOK képekkel - KONZISZTENS alt szövegek -->
<div class="document-actions">
  <h3>Dokumentum műveletek</h3>
  
  <!-- Minden oldalon UGYANEZ az alt szöveg a letöltés gombra -->
  <button type="button" class="action-btn" onclick="downloadPDF()">
    <img src="download-icon.png" alt="PDF letöltése" role="presentation">
    <span>PDF letöltése</span>
  </button>
  
  <!-- Minden oldalon UGYANEZ az alt szöveg a nyomtatás gombra -->
  <button type="button" class="action-btn" onclick="window.print()">
    <img src="print-icon.png" alt="Oldal nyomtatása" role="presentation">
    <span>Nyomtatás</span>
  </button>
  
  <!-- Minden oldalon UGYANEZ az alt szöveg az email gombra -->
  <a href="mailto:info@vallalat.hu" class="action-btn">
    <img src="email-icon.png" alt="E-mail küldése" role="presentation">
    <span>E-mail küldése</span>
  </a>
  
  <!-- Minden oldalon UGYANEZ az alt szöveg a megosztás gombra -->
  <button type="button" class="action-btn" onclick="shareContent()">
    <img src="share-icon.png" alt="Tartalom megosztása" role="presentation">
    <span>Megosztás</span>
  </button>
</div>

<!-- TERMÉK OLDALAK - Konzisztens értékelési rendszer -->
<div class="product-rating">
  <h4>Termék értékelése</h4>
  
  <!-- MINDEN termék oldalon ugyanezek az alt szövegek -->
  <div class="star-rating" role="img" aria-label="5 csillagból 4 csillag értékelés">
    <img src="star-filled.png" alt="Kitöltött csillag" class="star">
    <img src="star-filled.png" alt="Kitöltött csillag" class="star">
    <img src="star-filled.png" alt="Kitöltött csillag" class="star">
    <img src="star-filled.png" alt="Kitöltött csillag" class="star">
    <img src="star-empty.png" alt="Üres csillag" class="star">
  </div>
  
  <p>4.2/5 (127 értékelés)</p>
</div>

<!-- SOCIAL MEDIA linkek - KONZISZTENS alt szövegek -->
<div class="social-media" role="navigation" aria-label="Közösségi média linkek">
  <h4>Kövessen minket:</h4>
  
  <!-- MINDEN oldalon ugyanezek az alt szövegek -->
  <a href="https://facebook.com/vallalat" target="_blank" rel="noopener">
    <img src="facebook-icon.png" alt="Facebook oldal megnyitása új ablakban" class="social-icon">
    <span class="visually-hidden">Facebook</span>
  </a>
  
  <a href="https://instagram.com/vallalat" target="_blank" rel="noopener">
    <img src="instagram-icon.png" alt="Instagram profil megnyitása új ablakban" class="social-icon">
    <span class="visually-hidden">Instagram</span>
  </a>
  
  <a href="https://linkedin.com/company/vallalat" target="_blank" rel="noopener">
    <img src="linkedin-icon.png" alt="LinkedIn profil megnyitása új ablakban" class="social-icon">
    <span class="visually-hidden">LinkedIn</span>
  </a>
  
  <a href="https://youtube.com/vallalat" target="_blank" rel="noopener">
    <img src="youtube-icon.png" alt="YouTube csatorna megnyitása új ablakban" class="social-icon">
    <span class="visually-hidden">YouTube</span>
  </a>
</div>

<!-- BREADCRUMB navigáció - konzisztens linkek -->
<nav aria-label="Breadcrumb navigáció" class="breadcrumb">
  <ol>
    <li><a href="/fooldal">Főoldal</a></li> <!-- Konzisztens link szöveg -->
    <li><a href="/termekek">Termékek</a></li> <!-- Konzisztens link szöveg -->
    <li><a href="/kategoria/elektronika">Elektronika</a></li>
    <li aria-current="page">Smartphone</li>
  </ol>
</nav>

<script>
// Konzisztens funkcionalitás minden oldalon
function downloadPDF() {
  console.log('PDF letöltése megkezdve...');
  // PDF letöltési logika
}

function shareContent() {
  if (navigator.share) {
    navigator.share({
      title: document.title,
      text: 'Tekintse meg ezt a tartalmat!',
      url: window.location.href
    });
  } else {
    // Fallback megosztási módszerek
    const url = encodeURIComponent(window.location.href);
    const text = encodeURIComponent('Tekintse meg ezt a tartalmat!');
    
    const shareWindow = window.open(
      `https://www.facebook.com/sharer/sharer.php?u=${url}"e=${text}`,
      'shareWindow',
      'width=600,height=400'
    );
  }
}
</script>

<style>
.page-nav {
  list-style: none;
  display: flex;
  gap: 1rem;
  padding: 0;
  margin: 0;
  flex-wrap: wrap;
}

.page-nav a {
  text-decoration: none;
  padding: 0.5rem 1rem;
  background: #f8f9fa;
  color: #495057;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.page-nav a:hover, .page-nav a:focus {
  background: #e9ecef;
  color: #007bff;
}

.page-nav a[aria-current="page"] {
  background: #007bff;
  color: white;
}

.company-info {
  margin: 2rem 0;
}

.team-member {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 1rem 0;
  padding: 1rem;
  border: 1px solid #dee2e6;
  border-radius: 8px;
}

.team-member img {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  object-fit: cover;
}

.document-actions {
  margin: 2rem 0;
  padding: 1rem;
  background: #f8f9fa;
  border-radius: 8px;
}

.action-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  margin: 0.25rem;
  background: white;
  color: #495057;
  text-decoration: none;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.action-btn:hover, .action-btn:focus {
  background: #e9ecef;
  border-color: #007bff;
  color: #007bff;
}

.action-btn img {
  width: 16px;
  height: 16px;
}

.product-rating {
  margin: 1rem 0;
  padding: 1rem;
  border: 1px solid #dee2e6;
  border-radius: 8px;
}

.star-rating {
  display: flex;
  gap: 0.25rem;
  margin: 0.5rem 0;
}

.star {
  width: 20px;
  height: 20px;
}

.social-media {
  margin: 2rem 0;
  padding: 1rem;
  background: #f8f9fa;
  border-radius: 8px;
}

.social-media a {
  display: inline-block;
  margin: 0.25rem;
  padding: 0.5rem;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.social-media a:hover, .social-media a:focus {
  background: #e9ecef;
}

.social-icon {
  width: 32px;
  height: 32px;
}

.breadcrumb ol {
  list-style: none;
  display: flex;
  gap: 0.5rem;
  padding: 0;
  margin: 1rem 0;
  flex-wrap: wrap;
}

.breadcrumb li::after {
  content: " > ";
  margin-left: 0.5rem;
  color: #6c757d;
}

.breadcrumb li:last-child::after {
  content: "";
}

.breadcrumb a {
  color: #007bff;
  text-decoration: none;
}

.breadcrumb a:hover, .breadcrumb a:focus {
  text-decoration: underline;
}

.breadcrumb li[aria-current="page"] {
  color: #6c757d;
  font-weight: bold;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 768px) {
  .page-nav {
    flex-direction: column;
  }
  
  .team-member {
    flex-direction: column;
    text-align: center;
  }
  
  .document-actions {
    text-align: center;
  }
  
  .action-btn {
    display: flex;
    justify-content: center;
    margin: 0.5rem 0;
  }
}
</style>

Magyarázat: Minden oldal ugyanazokat a link szövegeket és alt attribútumokat használja ugyanazokra a funkciókra, így a felhasználók mindig tudják, mit várhatnak.

4. Globális komponensek konzisztens címkézéssel

<!-- GLOBÁLIS KOMPONENS TÁRHÁZ -->
<script>
// Konzisztens címkék központi konfigurációja
const ConsistentLabels = {
  // Gombok
  buttons: {
    submit: "Űrlap elküldése",
    reset: "Űrlap visszaállítása", 
    save: "Mentés",
    cancel: "Mégse",
    delete: "Törlés",
    edit: "Szerkesztés",
    close: "Bezárás",
    print: "Nyomtatás",
    share: "Megosztás",
    download: "Letöltés",
    upload: "Feltöltés",
    search: "Keresés",
    filter: "Szűrés",
    sort: "Rendezés",
    refresh: "Frissítés",
    back: "Vissza",
    next: "Következő",
    previous: "Előző",
    play: "Lejátszás",
    pause: "Szünet",
    stop: "Megállítás"
  },
  
  // Linkek
  links: {
    home: "Főoldal",
    about: "Rólunk", 
    services: "Szolgáltatások",
    products: "Termékek",
    portfolio: "Portfólió",
    blog: "Blog",
    contact: "Kapcsolat",
    login: "Bejelentkezés",
    logout: "Kijelentkezés",
    register: "Regisztráció",
    profile: "Profil",
    settings: "Beállítások",
    help: "Súgó",
    faq: "Gyakori kérdések",
    terms: "Felhasználási feltételek",
    privacy: "Adatvédelmi nyilatkozat"
  },
  
  // Ikonok
  icons: {
    menu: "Menü megnyitása",
    menuClose: "Menü bezárása",
    search: "Keresés megnyitása",
    cart: "Bevásárlókosár megtekintése",
    user: "Felhasználói profil",
    notification: "Értesítések megtekintése",
    settings: "Beállítások megnyitása",
    help: "Súgó megnyitása"
  },
  
  // Képek
  images: {
    logo: "Weboldal logója",
    avatar: "Felhasználói profilkép",
    product: "Termék képe",
    thumbnail: "Előnézeti kép"
  }
};

// Konzisztens komponens generátor
class ConsistentComponents {
  
  // Konzisztens gomb létrehozása
  static createButton(type, additionalClasses = '', onclick = null) {
    const label = ConsistentLabels.buttons[type];
    if (!label) {
      console.error(`Ismeretlen gomb típus: ${type}`);
      return null;
    }
    
    const button = document.createElement('button');
    button.type = type === 'submit' ? 'submit' : 'button';
    button.className = `btn btn-${type} ${additionalClasses}`.trim();
    button.setAttribute('aria-label', label);
    button.textContent = this.getButtonText(type);
    
    if (onclick) {
      button.addEventListener('click', onclick);
    }
    
    return button;
  }
  
  // Konzisztens link létrehozása
  static createLink(type, href = '#', additionalClasses = '') {
    const text = ConsistentLabels.links[type];
    if (!text) {
      console.error(`Ismeretlen link típus: ${type}`);
      return null;
    }
    
    const link = document.createElement('a');
    link.href = href;
    link.className = `link link-${type} ${additionalClasses}`.trim();
    link.textContent = text;
    
    return link;
  }
  
  // Konzisztens ikon gomb létrehozása
  static createIconButton(iconType, additionalClasses = '', onclick = null) {
    const label = ConsistentLabels.icons[iconType];
    if (!label) {
      console.error(`Ismeretlen ikon típus: ${iconType}`);
      return null;
    }
    
    const button = document.createElement('button');
    button.type = 'button';
    button.className = `icon-btn icon-btn-${iconType} ${additionalClasses}`.trim();
    button.setAttribute('aria-label', label);
    
    // SVG ikon hozzáadása
    const svg = this.createSVGIcon(iconType);
    if (svg) {
      button.appendChild(svg);
    }
    
    if (onclick) {
      button.addEventListener('click', onclick);
    }
    
    return button;
  }
  
  // SVG ikon létrehozása
  static createSVGIcon(iconType) {
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('aria-hidden', 'true');
    svg.setAttribute('width', '24');
    svg.setAttribute('height', '24');
    svg.setAttribute('viewBox', '0 0 24 24');
    svg.setAttribute('fill', 'none');
    svg.setAttribute('stroke', 'currentColor');
    svg.setAttribute('stroke-width', '2');
    
    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    
    // Egyszerű SVG útvonalak
    const iconPaths = {
      menu: 'M3 12h18M3 6h18M3 18h18',
      menuClose: 'M18 6L6 18M6 6l12 12',
      search: 'M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z',
      cart: 'M3 3h2l.4 2M7 13h10l4-8H5.4m0 0L7 13m0 0l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17',
      user: 'M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2M12 11a4 4 0 100-8 4 4 0 000 8z',
      notification: 'M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 01-3.46 0',
      settings: 'M12 15a3 3 0 100-6 3 3 0 000 6zM19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z',
      help: 'M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01'
    };
    
    if (iconPaths[iconType]) {
      path.setAttribute('d', iconPaths[iconType]);
      svg.appendChild(path);
    }
    
    return svg;
  }
  
  // Gomb szöveg meghatározása
  static getButtonText(type) {
    const buttonTexts = {
      submit: "Küldés",
      reset: "Törlés", 
      save: "Mentés",
      cancel: "Mégse",
      delete: "Törlés",
      edit: "Szerkesztés",
      close: "Bezárás",
      print: "Nyomtatás",
      share: "Megosztás",
      download: "Letöltés",
      upload: "Feltöltés",
      search: "Keresés",
      filter: "Szűrés",
      sort: "Rendezés",
      refresh: "Frissítés",
      back: "Vissza",
      next: "Következő",
      previous: "Előző",
      play: "Lejátszás",
      pause: "Szünet",
      stop: "Megállítás"
    };
    
    return buttonTexts[type] || type;
  }
  
  // Konzisztens navigáció létrehozása
  static createNavigation(navType, items, currentPath = '') {
    const nav = document.createElement('nav');
    nav.setAttribute('role', 'navigation');
    nav.setAttribute('aria-label', this.getNavLabel(navType));
    nav.className = `navigation navigation-${navType}`;
    
    const ul = document.createElement('ul');
    ul.className = 'nav-list';
    
    items.forEach(item => {
      const li = document.createElement('li');
      li.className = 'nav-item';
      
      const link = document.createElement('a');
      link.href = item.href;
      link.textContent = ConsistentLabels.links[item.type] || item.text;
      link.className = 'nav-link';
      
      if (item.href === currentPath) {
        link.setAttribute('aria-current', 'page');
        link.className += ' nav-link-current';
      }
      
      li.appendChild(link);
      ul.appendChild(li);
    });
    
    nav.appendChild(ul);
    return nav;
  }
  
  // Navigáció címke meghatározása
  static getNavLabel(navType) {
    const navLabels = {
      main: "Főnavigáció",
      user: "Felhasználói navigáció",
      footer: "Lábléc navigáció",
      breadcrumb: "Breadcrumb navigáció",
      secondary: "Másodlagos navigáció"
    };
    
    return navLabels[navType] || "Navigáció";
  }
}

// Használati példák
document.addEventListener('DOMContentLoaded', function() {
  
  // Konzisztens gombok létrehozása
  const formContainer = document.getElementById('form-actions');
  if (formContainer) {
    const submitBtn = ConsistentComponents.createButton('submit', 'btn-primary');
    const resetBtn = ConsistentComponents.createButton('reset', 'btn-secondary');
    
    formContainer.appendChild(submitBtn);
    formContainer.appendChild(resetBtn);
  }
  
  // Konzisztens ikon gombok létrehozása
  const toolbarContainer = document.getElementById('toolbar');
  if (toolbarContainer) {
    const menuBtn = ConsistentComponents.createIconButton('menu', 'mobile-only', () => {
      console.log('Menü megnyitva');
    });
    
    const searchBtn = ConsistentComponents.createIconButton('search', '', () => {
      console.log('Keresés megnyitva');
    });
    
    const cartBtn = ConsistentComponents.createIconButton('cart', '', () => {
      console.log('Kosár megnyitva');
    });
    
    toolbarContainer.appendChild(menuBtn);
    toolbarContainer.appendChild(searchBtn);
    toolbarContainer.appendChild(cartBtn);
  }
  
  // Konzisztens navigáció létrehozása
  const navContainer = document.getElementById('main-navigation');
  if (navContainer) {
    const navItems = [
      { type: 'home', href: '/fooldal' },
      { type: 'products', href: '/termekek' },
      { type: 'about', href: '/rolunk' },
      { type: 'contact', href: '/kapcsolat' }
    ];
    
    const navigation = ConsistentComponents.createNavigation('main', navItems, window.location.pathname);
    navContainer.appendChild(navigation);
  }
});
</script>

<!-- HTML struktúra a komponensekhez -->
<div class="page-layout">
  <header>
    <div class="logo">
      <img src="logo.png" alt="Weboldal logója">
    </div>
    
    <div id="toolbar" class="toolbar"></div>
    <div id="main-navigation"></div>
  </header>
  
  <main>
    <h1>Konzisztens komponensek</h1>
    
    <form>
      <div class="form-group">
        <label for="example-input">Példa mező:</label>
        <input type="text" id="example-input" name="example">
      </div>
      
      <div id="form-actions" class="form-actions"></div>
    </form>
  </main>
</div>

<style>
/* Konzisztens stílusok */
.btn {
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  transition: all 0.2s ease;
  margin: 0.25rem;
}

.btn-primary {
  background: #007bff;
  color: white;
}

.btn-secondary {
  background: #6c757d;
  color: white;
}

.btn:hover, .btn:focus {
  opacity: 0.9;
  outline: 2px solid #007bff;
  outline-offset: 2px;
}

.icon-btn {
  background: none;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  padding: 0.5rem;
  cursor: pointer;
  transition: all 0.2s ease;
  margin: 0.25rem;
}

.icon-btn:hover, .icon-btn:focus {
  background: #f8f9fa;
  border-color: #007bff;
  outline: 2px solid #007bff;
  outline-offset: 2px;
}

.icon-btn svg {
  display: block;
  width: 24px;
  height: 24px;
}

.toolbar {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.navigation {
  margin: 1rem 0;
}

.nav-list {
  list-style: none;
  display: flex;
  gap: 1rem;
  padding: 0;
  margin: 0;
  flex-wrap: wrap;
}

.nav-link {
  text-decoration: none;
  padding: 0.5rem 1rem;
  color: #495057;
  background: #f8f9fa;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.nav-link:hover, .nav-link:focus {
  background: #e9ecef;
  color: #007bff;
}

.nav-link-current {
  background: #007bff;
  color: white;
}

.form-group {
  margin: 1rem 0;
}

.form-group label {
  display: block;
  font-weight: bold;
  margin-bottom: 0.5rem;
}

.form-group input {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.form-actions {
  margin-top: 1rem;
}

@media (max-width: 768px) {
  .mobile-only {
    display: block;
  }
  
  .nav-list {
    flex-direction: column;
  }
  
  .toolbar {
    justify-content: space-between;
    width: 100%;
  }
}

@media (min-width: 769px) {
  .mobile-only {
    display: none;
  }
}
</style>

Magyarázat: Egy központi komponens rendszer biztosítja, hogy minden oldal ugyanazokat a címkéket és aria-label értékeket használja az azonos funkciójú elemekhez.

Rossz gyakorlatok

Különböző címkék ugyanahhoz a funkcióhoz

<!-- FŐOLDAL - "Mentés" gomb -->
<button type="submit" aria-label="Mentés">Mentés</button>

<!-- PROFIL OLDAL - HIBÁS: "Tárolás" gomb ugyanahhoz a funkcióhoz -->
<button type="submit" aria-label="Tárolás">Tárolás</button>

<!-- BEÁLLÍTÁSOK OLDAL - HIBÁS: "Elmentés" gomb -->
<button type="submit" aria-label="Elmentés">Elmentés</button>

<!-- ŰRLAP OLDAL - HIBÁS: "Küldés" gomb mentéshez -->
<button type="submit" aria-label="Küldés">Küldés</button>

Probléma: A felhasználók összezavarodnak, mert nem tudják, hogy ezek a gombok mind ugyanazt a mentési funkciót látják el.

Hiányzó vagy inkonzisztens ARIA címkék ikonokon

<!-- FŐOLDAL - megfelelő aria-label -->
<button aria-label="Menü megnyitása">
  <svg><!-- hamburger ikon --></svg>
</button>

<!-- TERMÉKEK OLDAL - HIBÁS: hiányzó aria-label -->
<button>
  <svg><!-- hamburger ikon --></svg>
</button>

<!-- KAPCSOLAT OLDAL - HIBÁS: különböző aria-label -->
<button aria-label="Navigáció kinyitása">
  <svg><!-- hamburger ikon --></svg>
</button>

<!-- BLOG OLDAL - HIBÁS: ismét más aria-label -->
<button aria-label="Menüsáv megjelenítése">
  <svg><!-- hamburger ikon --></svg>
</button>

Probléma: A képernyőolvasó felhasználók nem tudják megjegyezni, hogyan hivatkoznak ugyanarra a funkcióra különböző oldalakon.

Bizonytalan vagy különböző link szövegek ugyanahhoz a célhoz

<!-- FŐOLDAL navigáció -->
<nav>
  <a href="/kapcsolat">Kapcsolat</a>
  <a href="/rolunk">Rólunk</a>
</nav>

<!-- SZOLGÁLTATÁSOK OLDAL - HIBÁS: különböző szövegek -->
<nav>
  <a href="/kapcsolat">Vegye fel velünk a kapcsolatot</a> <!-- Túl hosszú és más -->
  <a href="/rolunk">Cégünkről</a> <!-- Más szöveg -->
</nav>

<!-- TERMÉKEK OLDAL - HIBÁS: ismét más szövegek -->
<nav>
  <a href="/kapcsolat">Írjon nekünk</a> <!-- Más szöveg -->
  <a href="/rolunk">Bemutatkozás</a> <!-- Más szöveg -->
</nav>

<!-- BLOG OLDAL - HIBÁS: rövidítések -->
<nav>
  <a href="/kapcsolat">Kontakt</a> <!-- Rövidítés -->
  <a href="/rolunk">Info</a> <!-- Félreérthető rövidítés -->
</nav>

Probléma: A felhasználók nem tudják megjegyezni, melyik link vezet hova, mert minden oldalon más-más szöveggel találkoznak.

Inkonzisztens képleírások ugyanazon funkciókhoz

<!-- FŐOLDAL - PDF letöltés gomb -->
<button>
  <img src="download-icon.png" alt="PDF letöltése">
  <span>Letöltés</span>
</button>

<!-- DOKUMENTÁCIÓ OLDAL - HIBÁS: más alt szöveg -->
<button>
  <img src="download-icon.png" alt="Fájl mentése"> <!-- Más leírás -->
  <span>Letöltés</span>
</button>

<!-- TERMÉKEK OLDAL - HIBÁS: ismét más alt szöveg -->
<button>
  <img src="download-icon.png" alt="Dokumentum letöltése"> <!-- Más leírás -->
  <span>Letöltés</span>
</button>

<!-- HÍREK OLDAL - HIBÁS: hiányzó alt szöveg -->
<button>
  <img src="download-icon.png" alt=""> <!-- Üres alt -->
  <span>Letöltés</span>
</button>

Probléma: A képernyőolvasók különböző leírásokat mondanak ugyanarra az ikonra, ami zavart okoz.

Dinamikus tartalom inkonzisztens címkézéssel

<script>
// HIBÁS: véletlenszerű címkék generálása
function createActionButton(action, context) {
  const button = document.createElement('button');
  
  // HIBÁS: kontextus alapján változó címkék
  let label;
  switch(context) {
    case 'product':
      if (action === 'delete') {
        label = 'Termék eltávolítása'; // Más címke
      }
      break;
    case 'user':
      if (action === 'delete') {
        label = 'Felhasználó törlése'; // Más címke
      }
      break;
    case 'post':
      if (action === 'delete') {
        label = 'Bejegyzés törlése'; // Más címke
      }
      break;
    default:
      if (action === 'delete') {
        label = 'Elem törlése'; // Még egy más címke
      }
  }
  
  button.setAttribute('aria-label', label);
  button.textContent = 'Törlés';
  
  return button;
}

// HIBÁS: időpont alapú címkék
function createTimeBasedButton() {
  const hour = new Date().getHours();
  const button = document.createElement('button');
  
  if (hour < 12) {
    button.setAttribute('aria-label', 'Reggeli mentés'); // HIBÁS
  } else if (hour < 18) {
    button.setAttribute('aria-label', 'Délutáni mentés'); // HIBÁS
  } else {
    button.setAttribute('aria-label', 'Esti mentés'); // HIBÁS
  }
  
  button.textContent = 'Mentés';
  return button;
}

// HIBÁS: felhasználói jogosultság alapú címkék
function createRoleBasedButton(userRole) {
  const button = document.createElement('button');
  
  switch(userRole) {
    case 'admin':
      button.setAttribute('aria-label', 'Admin szerkesztés'); // HIBÁS
      break;
    case 'editor':
      button.setAttribute('aria-label', 'Szerkesztői módosítás'); // HIBÁS
      break;
    case 'user':
      button.setAttribute('aria-label', 'Felhasználói szerkesztés'); // HIBÁS
      break;
    default:
      button.setAttribute('aria-label', 'Egyszerű szerkesztés'); // HIBÁS
  }
  
  button.textContent = 'Szerkesztés';
  return button;
}

// HIBÁS: nyelvi beállítás figyelmen kívül hagyása
function createMultiLanguageButton(language) {
  const button = document.createElement('button');
  
  // HIBÁS: kevert nyelvű címkék
  switch(language) {
    case 'en':
      button.setAttribute('aria-label', 'Save document'); // Angol
      button.textContent = 'Mentés'; // Magyar szöveg
      break;
    case 'de':
      button.setAttribute('aria-label', 'Dokument speichern'); // Német
      button.textContent = 'Mentés'; // Magyar szöveg
      break;
    default:
      button.setAttribute('aria-label', 'Documento salvato'); // Olasz?!
      button.textContent = 'Mentés'; // Magyar szöveg
  }
  
  return button;
}
</script>

Probléma: A dinamikusan generált elemek inkonzisztens címkézése miatt a felhasználók nem tudják megjegyezni és kiszámítani a felület viselkedését.

Üres vagy jelentéktelen címkék

<!-- HIBÁS: üres aria-label -->
<button aria-label="">
  <svg><!-- ikon --></svg>
</button>

<!-- HIBÁS: jelentéktelen aria-label -->
<button aria-label="gomb">
  <svg><!-- ikon --></svg>
</button>

<!-- HIBÁS: generikus alt szöveg -->
<img src="action-icon.png" alt="ikon">

<!-- HIBÁS: fájlnév mint alt szöveg -->
<img src="save_icon_24px.png" alt="save_icon_24px.png">

<!-- HIBÁS: technikai információ alt szövegben -->
<img src="print-btn.jpg" alt="24x24 pixel print button image">

<!-- HIBÁS: ugyanaz a címke minden gombra -->
<button aria-label="művelet">Mentés</button>
<button aria-label="művelet">Törlés</button>
<button aria-label="művelet">Szerkesztés</button>

<!-- HIBÁS: nem informatív link szövegek -->
<a href="/dokumentacio">kattintson ide</a>
<a href="/letoltes">tovább</a>
<a href="/info">bővebben</a>
<a href="/regisztracio">itt</a>

Probléma: Az üres, generikus vagy jelentéktelen címkék nem adnak hasznos információt a felhasználóknak arról, hogy az adott elem mit csinál.

Források

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