3.2.1 - Fókuszban
Röviden a szabványpontról
A WCAG 3.2.1 (On Focus) előírja, hogy amikor bármely felhasználói felület komponens billentyűzet fókuszt kap, az nem okozhat kontextusváltozást, hacsak a felhasználó nincs előre tájékoztatva róla. A „kontextusváltozás” azt jelenti, hogy jelentős változás történik a felhasználó környezetében, mint például új ablak vagy lap megnyitása, átirányítás másik oldalra, az oldal tartalmának megváltoztatása, vagy a fókusz váratlan áthelyezése.
Mire vonatkozik: Minden interaktív felhasználói felület elemre, amely billentyűzet fókuszt kaphat: linkek, gombok, űrlap vezérlők és egyéni widgetek.
Cél: Biztosítani, hogy a billentyűzetes navigációra, vagy segítő technológiákra támaszkodó felhasználók előre tudják jelezni és kontrollálni, mikor történnek kontextusváltozások, elkerülve a hibákat és tájékozódási nehézségeket.
Kiket érint
Elsődleges felhasználók: Csak billentyűzetet használó felhasználók, képernyőolvasót használók és kognitív fogyatékossággal élő személyek, akik kiszámítható navigációra és kontextus stabilitásra támaszkodnak.
Másodlagos előnyök: Javítja minden felhasználó élményét azáltal, hogy megakadályozza a váratlan oldalugrásokat vagy tartalom változásokat, intuitívabbá és kevésbé frusztálóvá téve az interakciókat.
Tesztelés
- Billentyűzetes navigációs teszt: Használd a billentyűzetet (Tab, Shift+Tab) hogy végigmenj minden interaktív elemen és ellenőrizd, hogy nincsenek váratlan oldal újratöltések, átirányítások vagy fókusz ugrások fókusz használat közben
- Képernyőolvasó teszt: Navigálj képernyőolvasó virtuális kurzorral, vagy billentyűzet parancsokkal, hogy biztosítsd, hogy a fókusz változások nem váltanak ki váratlan bejelentéseket vagy kontextus váltásokat
- Fókusz esemény monitorozás: Használd a böngésző fejlesztői eszközeit vagy akadálymentességi tesztelő eszközöket (mint az axe DevTools) hogy monitorozd a fókusz eseményeket és ellenőrizd, hogy szkriptek okoznak-e kontextusváltozásokat fókusz közben
- Felhasználói értesítés ellenőrzés: Ha egy fókusz esemény kontextusváltozást okoz, ellenőrizd, hogy a felhasználó előre tisztán tájékoztatva van-e (pl. látható utasításokkal vagy ARIA riasztásokkal)
- Automatizált tesztelés: Futtass automatizált akadálymentességi szkennereket és tekintsd át a fókusz változásokkal vagy fókusz által váltott váratlan navigációval kapcsolatos problémákat
Jó gyakorlatok
1. Egy gomb fókusza nem küldi el azonnal az űrlapot
<!-- Jó: Gomb fókusza nem vált ki műveletet -->
<form class="regisztracios-urlap">
<fieldset>
<legend>Felhasználói adatok</legend>
<div class="mezo-csoport">
<label for="felhasznalonev">Felhasználónév:</label>
<input type="text"
id="felhasznalonev"
name="felhasznalonev"
required
aria-describedby="felhasznalonev-help">
<div id="felhasznalonev-help" class="segito-szoveg">
Legalább 3 karakter, csak betűk és számok
</div>
</div>
<div class="mezo-csoport">
<label for="email">E-mail cím:</label>
<input type="email"
id="email"
name="email"
required
aria-describedby="email-help">
<div id="email-help" class="segito-szoveg">
Érvényes e-mail formátum szükséges
</div>
</div>
<div class="mezo-csoport">
<label for="jelszo">Jelszó:</label>
<input type="password"
id="jelszo"
name="jelszo"
required
aria-describedby="jelszo-help">
<div id="jelszo-help" class="segito-szoveg">
Legalább 8 karakter, tartalmazzon számot és speciális karaktert
</div>
</div>
<div class="gomb-csoport">
<!-- Jó: A mentés gomb fókusza nem küld el űrlapot automatikusan -->
<button type="submit" id="mentesGomb">
💾 Regisztráció
</button>
<button type="reset" id="torlesesGomb">
🗑️ Űrlap törlése
</button>
<button type="button" id="megerositesGomb">
✓ Adatok ellenőrzése
</button>
</div>
</fieldset>
</form>
<script>
// Jó gyakorlat: Csak kattintásra vagy Enter/Space lenyomására történik művelet
document.getElementById('mentesGomb').addEventListener('click', function(event) {
// Az űrlap csak explicit aktiváláskor lesz elküldve
console.log('Regisztráció elküldése...');
});
document.getElementById('megerositesGomb').addEventListener('click', function() {
// Adatok ellenőrzése csak explicit aktiváláskor
const felhasznalonev = document.getElementById('felhasznalonev').value;
const email = document.getElementById('email').value;
if (felhasznalonev && email) {
alert('Adatok rendben vannak!');
} else {
alert('Kérlek töltsd ki az összes mezőt!');
}
});
// Fontos: Nincs onfocus eseménykezelő, amely műveletet váltana ki
</script>
<style>
.regisztracios-urlap {
max-width: 500px;
margin: 20px 0;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
.mezo-csoport {
margin-bottom: 15px;
}
.mezo-csoport label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.mezo-csoport input {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 16px;
}
.segito-szoveg {
font-size: 14px;
color: #666;
margin-top: 5px;
}
.gomb-csoport {
display: flex;
gap: 10px;
margin-top: 20px;
}
.gomb-csoport button {
padding: 10px 15px;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
}
button[type="submit"] {
background-color: #28a745;
color: white;
}
button[type="reset"] {
background-color: #dc3545;
color: white;
}
button[type="button"] {
background-color: #007bff;
color: white;
}
/* Fókusz stílusok - fontos, hogy látható legyen de ne váltson ki műveletet */
button:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
input:focus {
border-color: #0066cc;
box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.2);
}
</style>
<!-- Magyarázat: A gombok fókuszt kaphatnak, de ez nem vált ki automatikus műveleteket.
Csak explicit aktiválás (kattintás, Enter, Space) eredményez műveletet. -->
A gombok fókuszba kerülést követően nem váltanak ki műveletet – csak akkor történik valami, amikor a felhasználó explicit módon aktiválja őket kattintással vagy billentyűzettel.
2. Felhasználó tájékoztatása kontextusváltozás előtt
<!-- Jó: Link előre tájékoztat a kontextusváltozásról -->
<nav class="fo-navigacio" aria-label="Főnavigáció">
<ul>
<li>
<a href="/fooldal">🏠 Főoldal</a>
</li>
<li>
<a href="/szolgaltatasok">💼 Szolgáltatások</a>
</li>
<li>
<!-- Jó: Külső link előre jelezve -->
<a href="https://external-site.com"
target="_blank"
aria-describedby="kulso-link-info">
🌐 Partnerünk oldala
<span class="kulso-jelzo" aria-hidden="true">↗</span>
</a>
<span id="kulso-link-info" class="sr-only">
Ez a link új ablakban nyitja meg külső weboldalt
</span>
</li>
<li>
<!-- Jó: PDF link előre jelezve -->
<a href="/dokumentumok/arlista.pdf"
aria-describedby="pdf-info">
📄 Árlistánk (PDF)
</a>
<span id="pdf-info" class="sr-only">
PDF dokumentum, 2.5 MB méretű
</span>
</li>
<li>
<!-- Jó: Letöltés link előre jelezve -->
<a href="/letoltes/katalogus.zip"
download="termek-katalogus.zip"
aria-describedby="letoltes-info">
💾 Katalógus letöltése
</a>
<span id="letoltes-info" class="sr-only">
ZIP fájl letöltése, 15 MB méretű
</span>
</li>
</ul>
</nav>
<section class="tartalom-terület">
<h2>Hasznos linkek és dokumentumok</h2>
<div class="link-kartya">
<h3>Technikai dokumentáció</h3>
<p>Részletes műszaki információk termékeinhez:</p>
<ul class="dokumentum-lista">
<li>
<!-- Jó: Új ablak előre jelezve -->
<a href="/docs/api-dokumentacio"
target="_blank"
aria-describedby="api-docs-info">
🔧 API dokumentáció
<span class="uj-ablak-jelzo" aria-hidden="true">🔗</span>
</a>
<span id="api-docs-info" class="sr-only">
Új ablakban nyílik meg, interaktív API dokumentáció
</span>
</li>
<li>
<!-- Jó: Nyelvváltás előre jelezve -->
<a href="/en/documentation"
hreflang="en"
aria-describedby="angol-docs-info">
🇬🇧 Documentation (English)
</a>
<span id="angol-docs-info" class="sr-only">
Angol nyelvű dokumentáció, ugyanazon az oldalon
</span>
</li>
</ul>
</div>
<div class="figyelmeztetés-box">
<h3>🔍 Keresési tippek</h3>
<p>A keresési mező fókusza <strong>nem</strong> indít el keresést automatikusan.</p>
<p>Csak az Enter billentyű lenyomása vagy a Keresés gomb aktiválása után történik keresés.</p>
<form class="kereső-form" role="search">
<label for="kereső-mezo">Keresési kifejezés:</label>
<div class="kereső-container">
<input type="search"
id="kereső-mezo"
name="q"
placeholder="Írj be keresési kifejezést..."
aria-describedby="kereső-help">
<button type="submit" aria-label="Keresés indítása">
🔍 Keresés
</button>
</div>
<div id="kereső-help" class="segito-szoveg">
A keresés csak a gomb megnyomásával vagy Enter billentyűvel indul el
</div>
</form>
</div>
</section>
<style>
.fo-navigacio ul {
list-style: none;
padding: 0;
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.fo-navigacio a {
text-decoration: none;
padding: 10px 15px;
border: 2px solid #007bff;
border-radius: 5px;
color: #007bff;
display: inline-block;
transition: all 0.3s ease;
}
.fo-navigacio a:hover,
.fo-navigacio a:focus {
background-color: #007bff;
color: white;
outline: 2px solid #004085;
outline-offset: 2px;
}
.kulso-jelzo,
.uj-ablak-jelzo {
margin-left: 5px;
font-size: 0.9em;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.link-kartya {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.dokumentum-lista {
list-style: none;
padding: 0;
}
.dokumentum-lista li {
margin: 10px 0;
}
.figyelmeztetés-box {
background: #e7f3ff;
border: 1px solid #b3d9ff;
padding: 15px;
border-radius: 5px;
margin: 20px 0;
}
.kereső-container {
display: flex;
gap: 10px;
margin: 10px 0;
}
.kereső-container input {
flex: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.kereső-container button {
padding: 8px 15px;
background: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.segito-szoveg {
font-size: 14px;
color: #666;
}
</style>
<!-- Magyarázat: Minden link és interaktív elem előre jelzi,
ha aktiválása kontextusváltozást okozna. A fókusz önmagában
nem vált ki változásokat. -->
A linkek és interaktív elemek előre tájékoztatják a felhasználót arról, hogy aktiválásuk milyen kontextusváltozást okoz. A fókusz megszerzése önmagában nem indít el semmilyen műveletet.
A modal dialógusok csak explicit aktiválásra nyílnak meg, nem fókusz eseményre. A fókusz kezelése programozottan és kiszámíthatóan történik, nem váratlan ugrásokkal.
4. Beviteli mezők automatikus funkciók nélkül
<!-- Jó: Beviteli mezők fókusza nem vált ki műveletet -->
<div class="keresési-felület">
<header>
<h1>Termékkeresés</h1>
<p>Keress rá termékeinkre név, kategória vagy márka alapján.</p>
</header>
<form class="keresési-űrlap" role="search">
<div class="keresési-mezők">
<div class="mező-csoport">
<label for="termék-keresés">Termék keresése:</label>
<!-- Jó: Fókusz nem indít automatikus keresést -->
<input type="search"
id="termék-keresés"
name="q"
placeholder="pl. laptop, telefon, tablet..."
aria-describedby="keresés-help"
autocomplete="off">
<div id="keresés-help" class="segítő-szöveg">
A keresés csak az Enter megnyomására vagy a Keresés gomb aktiválására indul
</div>
</div>
<div class="mező-csoport">
<label for="kategória-szűrő">Kategória:</label>
<!-- Jó: Select fókusza nem változtatja a megjelenített eredményeket -->
<select id="kategória-szűrő"
name="category"
aria-describedby="kategória-help">
<option value="">Összes kategória</option>
<option value="laptop">Laptopok</option>
<option value="telefon">Telefonok</option>
<option value="tablet">Tabletek</option>
<option value="kiegészítő">Kiegészítők</option>
</select>
<div id="kategória-help" class="segítő-szöveg">
A szűrés csak a keresés elküldése után érvényesül
</div>
</div>
<div class="mező-csoport">
<label for="ár-min">Minimum ár (Ft):</label>
<!-- Jó: Number input fókusza nem trigger-eli azonnali szűrést -->
<input type="number"
id="ár-min"
name="price_min"
min="0"
step="1000"
placeholder="0"
aria-describedby="ár-help">
</div>
<div class="mező-csoport">
<label for="ár-max">Maximum ár (Ft):</label>
<input type="number"
id="ár-max"
name="price_max"
min="0"
step="1000"
placeholder="1000000"
aria-describedby="ár-help">
<div id="ár-help" class="segítő-szöveg">
Az ár szűrés csak a keresés elküldésekor alkalmazódik
</div>
</div>
<div class="mező-csoport">
<fieldset>
<legend>Márka szűrők:</legend>
<!-- Jó: Checkbox-ok fókusza nem vált ki azonnali szűrést -->
<div class="checkbox-lista">
<label>
<input type="checkbox" name="brand" value="apple">
Apple
</label>
<label>
<input type="checkbox" name="brand" value="samsung">
Samsung
</label>
<label>
<input type="checkbox" name="brand" value="huawei">
Huawei
</label>
<label>
<input type="checkbox" name="brand" value="xiaomi">
Xiaomi
</label>
</div>
<div class="segítő-szöveg">
A márka szűrők csak a keresés elküldésekor érvényesülnek
</div>
</fieldset>
</div>
<div class="gomb-csoport">
<button type="submit" class="keresés-gomb">
🔍 Keresés indítása
</button>
<button type="reset" class="törlés-gomb">
🗑️ Szűrők törlése
</button>
<button type="button" class="mentés-gomb">
💾 Keresés mentése
</button>
</div>
</div>
</form>
<div class="keresési-tippek">
<h2>💡 Keresési tippek</h2>
<ul>
<li><strong>Fókusz nem indít keresést:</strong> A mezők fókusza nem trigger-el automatikus keresést</li>
<li><strong>Explicit aktiválás:</strong> Használd az Enter billentyűt vagy a Keresés gombot</li>
<li><strong>Szűrők együtt:</strong> Minden szűrő egyszerre alkalmazódik a keresés elküldésekor</li>
<li><strong>Mentett keresések:</strong> A gyakran használt kereséseket mentheted</li>
</ul>
</div>
</div>
<div id="keresési-eredmények" class="eredmények-terület" style="display: none;">
<h2>Keresési eredmények</h2>
<div id="eredmények-lista">
<!-- Az eredmények itt jelennek meg keresés után -->
</div>
</div>
<script>
// Jó gyakorlat: Nincs automatikus keresés fókusz vagy gépelés során
// Keresési űrlap kezelése - csak explicit submit-re
document.querySelector('.keresési-űrlap').addEventListener('submit', function(event) {
event.preventDefault();
const formData = new FormData(this);
const keresésKifejezés = formData.get('q');
const kategória = formData.get('category');
const minÁr = formData.get('price_min');
const maxÁr = formData.get('price_max');
const márkák = formData.getAll('brand');
// Keresés végrehajtása
keresésVégrehajtása({
kifejezés: keresésKifejezés,
kategória: kategória,
minÁr: minÁr,
maxÁr: maxÁr,
márkák: márkák
});
// Eredmények terület megjelenítése
document.getElementById('keresési-eredmények').style.display = 'block';
// Fókusz az eredményekre (kiszámíthatóan)
document.getElementById('keresési-eredmények').focus();
});
function keresésVégrehajtása(paraméterek) {
console.log('Keresés paraméterek:', paraméterek);
// Szimulált keresési eredmények
const eredményekLista = document.getElementById('eredmények-lista');
eredményekLista.innerHTML = `
<p>Keresési kifejezés: "${paraméterek.kifejezés || 'minden termék'}"</p>
<p>Kategória: ${paraméterek.kategória || 'összes'}</p>
<p>Ár tartomány: ${paraméterek.minÁr || '0'} - ${paraméterek.maxÁr || '∞'} Ft</p>
<p>Márkák: ${paraméterek.márkák.length ? paraméterek.márkák.join(', ') : 'összes'}</p>
<div class="eredmény-elem">3 termék találat</div>
`;
}
// Reset gomb kezelése
document.querySelector('.törlés-gomb').addEventListener('click', function() {
document.getElementById('keresési-eredmények').style.display = 'none';
console.log('Keresési szűrők törölve');
});
// Mentés gomb kezelése
document.querySelector('.mentés-gomb').addEventListener('click', function() {
const formData = new FormData(document.querySelector('.keresési-űrlap'));
console.log('Keresés mentve:', Object.fromEntries(formData));
alert('Keresés sikeresen mentve!');
});
// FONTOS: Nincs fókusz vagy input eseménykezelő, amely automatikus keresést indítana!
// Az alábbi rossz gyakorlatok nincsenek implementálva:
// ROSSZ - ne használd:
// document.getElementById('termék-keresés').addEventListener('focus', function() {
// // Ez rossz lenne - fókusz eseményre automatikus keresés
// });
// ROSSZ - ne használd:
// document.getElementById('kategória-szűrő').addEventListener('change', function() {
// // Ez rossz lenne - azonnali szűrés változtatáskor
// });
// ROSSZ - ne használd:
// document.getElementById('termék-keresés').addEventListener('input', function() {
// // Ez rossz lenne - gépelés közben automatikus keresés
// });
</script>
<style>
.keresési-felület {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.keresési-mezők {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
border: 1px solid #dee2e6;
}
.mező-csoport {
margin-bottom: 20px;
}
.mező-csoport label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.mező-csoport input,
.mező-csoport select {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 16px;
}
.checkbox-lista {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 10px;
margin: 10px 0;
}
.checkbox-lista label {
display: flex;
align-items: center;
gap: 8px;
font-weight: normal;
}
.checkbox-lista input[type="checkbox"] {
width: auto;
}
.gomb-csoport {
display: flex;
gap: 10px;
margin-top: 20px;
flex-wrap: wrap;
}
.gomb-csoport button {
padding: 12px 20px;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
}
.keresés-gomb {
background: #007bff;
color: white;
}
.törlés-gomb {
background: #6c757d;
color: white;
}
.mentés-gomb {
background: #28a745;
color: white;
}
.segítő-szöveg {
font-size: 14px;
color: #6c757d;
margin-top: 5px;
}
.keresési-tippek {
background: #e7f3ff;
padding: 15px;
border-radius: 8px;
margin: 20px 0;
border: 1px solid #b3d9ff;
}
.eredmények-terület {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
border: 1px solid #dee2e6;
}
/* Fókusz stílusok - láthatóak de nem váltanak ki műveletet */
input:focus,
select:focus,
button:focus {
outline: 2px solid #007bff;
outline-offset: 2px;
border-color: #007bff;
}
fieldset {
border: 1px solid #dee2e6;
border-radius: 4px;
padding: 15px;
}
legend {
padding: 0 10px;
font-weight: bold;
}
</style>
<!-- Magyarázat: Az összes beviteli mező fókusza nem vált ki automatikus műveleteket.
A keresés és szűrés csak explicit aktiválásra (Enter, gomb kattintás) történik meg. -->
A beviteli mezők fókusza nem indít automatikus keresést vagy szűrést. Minden művelet csak explicit felhasználói aktiválásra történik meg.
Rossz gyakorlatok
Átirányítás fókusz eseményre
<!-- Rossz: Azonnali átirányítás fókuszra -->
<div class="navigációs-terület">
<h2>Gyors navigáció - ROSSZ példa</h2>
<p>Az alábbi linkek rosszul vannak implementálva!</p>
<nav class="rossz-nav">
<ul>
<li>
<!-- ROSSZ: Link fókuszra átirányít -->
<a href="fooldal.html"
onfocus="window.location='fooldal.html'">
Főoldal
</a>
<!-- Probléma: A fókusz megszerzésekor azonnal átirányít,
nem várja meg a felhasználó aktiválását -->
</li>
<li>
<!-- ROSSZ: Másik oldal betöltése fókuszra -->
<a href="szolgaltatasok.html"
onfocus="location.href='szolgaltatasok.html'">
Szolgáltatások
</a>
</li>
<li>
<!-- ROSSZ: Új ablak megnyitása fókuszra -->
<a href="kapcsolat.html"
onfocus="window.open('kapcsolat.html', '_blank')">
Kapcsolat
</a>
</li>
<li>
<!-- ROSSZ: JavaScript átirányítás fókuszra -->
<a href="#"
onfocus="document.location.assign('rolunk.html')">
Rólunk
</a>
</li>
</ul>
</nav>
<div class="hibás-keresés">
<h3>Hibás keresési funkciók</h3>
<!-- ROSSZ: Keresési mező fókuszra átirányít -->
<form>
<label for="rossz-kereső">Keresés (rossz implementáció):</label>
<input type="search"
id="rossz-kereső"
name="q"
placeholder="Keresési kifejezés..."
onfocus="window.location='kereses.html'">
<!-- Probléma: A keresési mező fókuszba kerülésekor
átirányít a keresési oldalra -->
</form>
<!-- ROSSZ: Select mező fókuszra navigation -->
<form>
<label for="rossz-kategoria">Kategória választás (rossz):</label>
<select id="rossz-kategoria"
name="category"
onfocus="if(this.value) location.href='kategoria.html?cat=' + this.value">
<option value="">Válassz kategóriát</option>
<option value="tech">Technológia</option>
<option value="sport">Sport</option>
<option value="etel">Étel</option>
</select>
<!-- Probléma: Fókusz esetén azonnal navigál ha van érték -->
</form>
</div>
<div class="problémás-gombok">
<h3>Problémás gombok</h3>
<!-- ROSSZ: Gomb fókuszra betölt új oldalt -->
<button type="button"
onfocus="window.location='dashboard.html'">
Dashboard megnyitása (rossz)
</button>
<!-- ROSSZ: Fókuszra iframe betöltése -->
<button type="button"
onfocus="document.getElementById('tartalomKeret').src='content.html'">
Tartalom betöltése (rossz)
</button>
<!-- ROSSZ: Fókuszra popup ablak -->
<button type="button"
onfocus="alert('Ez egy váratlan popup!')">
Információ gomb (rossz)
</button>
</div>
</div>
<iframe id="tartalomKeret" style="width: 100%; height: 200px; border: 1px solid #ccc;"></iframe>
<div class="probléma-magyarázat">
<h3>⚠️ Miért problémásak ezek a megoldások?</h3>
<ul>
<li><strong>Váratlan navigáció:</strong> A felhasználó csak fókuszt szeretne adni az elemnek, de váratlanul átirányításra kerül</li>
<li><strong>Billentyűzetes navigáció lehetetlensége:</strong> Tab-bal való végigmenés lehetetlenné válik, mert minden fókusz átirányít</li>
<li><strong>Képernyőolvasó problémák:</strong> A képernyőolvasók nem tudják felolvasni az elemeket, mert azonnal elnavigálnak</li>
<li><strong>Kiszámíthatatlanság:</strong> A felhasználó nem tudja előre, hogy a fókusz kontextusváltozást okoz</li>
<li><strong>Akadálymentességi szabály megsértése:</strong> Sérti a WCAG 3.2.1 szabványt</li>
</ul>
</div>
<style>
.rossz-nav ul {
list-style: none;
padding: 0;
background: #ffe6e6;
border: 2px solid #ff6b6b;
border-radius: 5px;
padding: 15px;
}
.rossz-nav li {
margin: 10px 0;
}
.rossz-nav a {
color: #dc3545;
text-decoration: none;
padding: 8px 12px;
border: 1px solid #dc3545;
border-radius: 4px;
display: inline-block;
}
.hibás-keresés,
.problémás-gombok {
background: #fff3cd;
border: 2px solid #ffc107;
padding: 15px;
border-radius: 5px;
margin: 15px 0;
}
.hibás-keresés input,
.hibás-keresés select {
width: 100%;
padding: 8px;
margin: 5px 0;
border: 2px solid #ffc107;
border-radius: 4px;
}
.problémás-gombok button {
background: #dc3545;
color: white;
border: none;
padding: 10px 15px;
margin: 5px;
border-radius: 4px;
cursor: pointer;
}
.probléma-magyarázat {
background: #f8d7da;
border: 2px solid #dc3545;
padding: 15px;
border-radius: 5px;
margin: 20px 0;
}
.probléma-magyarázat h3 {
color: #721c24;
margin-top: 0;
}
.probléma-magyarázat ul {
color: #721c24;
}
</style>
<!-- Probléma összefoglalás:
Az összes fenti elem sérti a WCAG 3.2.1 szabványt, mert fókusz eseményre
kontextusváltozást okoz a felhasználó előzetes értesítése nélkül. -->
Probléma: A fókusz eseményre bekövetkező azonnali átirányítások tájékoztatják a felhasználót és lehetetlenné teszik a kiszámítható navigációt.
Váratlan popup-ok és ablakok fókuszra aktiválódva
<!-- Rossz: Váratlan popup-ok és új ablakok fókuszra -->
<div class="hibás-popup-példák">
<h2>Hibás popup és ablak kezelés</h2>
<p><strong>Figyelem:</strong> Az alábbi példák ROSSZ gyakorlatokat mutatnak!</p>
<section class="rossz-helpek">
<h3>Hibás súgó rendszer</h3>
<div class="űrlap-mező">
<label for="hibás-név">Teljes név:</label>
<!-- ROSSZ: Input fókuszra súgó popup -->
<input type="text"
id="hibás-név"
name="fullname"
onfocus="window.open('help-name.html', 'help', 'width=400,height=300')">
<!-- Probléma: Fókuszra váratlan súgó ablak nyílik -->
</div>
<div class="űrlap-mező">
<label for="hibás-email">E-mail cím:</label>
<!-- ROSSZ: Input fókuszra alert box -->
<input type="email"
id="hibás-email"
name="email"
onfocus="alert('E-mail formátum: pelda@domain.hu')">
<!-- Probléma: Fókuszra váratlan alert popup -->
</div>
<div class="űrlap-mező">
<label for="hibás-telefon">Telefonszám:</label>
<!-- ROSSZ: Input fókuszra confirm dialog -->
<input type="tel"
id="hibás-telefon"
name="phone"
onfocus="confirm('Szeretnél súgót a telefonszám formátumhoz?')">
<!-- Probléma: Fókuszra váratlan confirm dialog -->
</div>
</section>
<section class="rossz-modal-kezelés">
<h3>Hibás modal kezelés</h3>
<!-- ROSSZ: Gomb fókuszra modal megnyitás -->
<button type="button"
id="hibás-modal-gomb"
onfocus="document.getElementById('váratlan-modal').style.display='block'">
Beállítások (rossz implementáció)
</button>
<!-- ROSSZ: Link fókuszra overlay megjelenítés -->
<a href="#info"
onfocus="document.getElementById('info-overlay').classList.add('aktív')">
Információ megtekintése (rossz)
</a>
<!-- ROSSZ: Select fókuszra tooltip popup -->
<select id="hibás-opciók"
onfocus="document.getElementById('opciók-popup').style.visibility='visible'">
<option value="">Válassz opciót</option>
<option value="1">Opció 1</option>
<option value="2">Opció 2</option>
</select>
</section>
<section class="rossz-tartalom-váltás">
<h3>Hibás tartalom manipuláció</h3>
<div class="tabos-felület">
<!-- ROSSZ: Tab fókuszra tartalom váltás -->
<button class="tab-gomb"
onfocus="váltTabTartalom('tab1')">
Tab 1 (rossz)
</button>
<button class="tab-gomb"
onfocus="váltTabTartalom('tab2')">
Tab 2 (rossz)
</button>
<button class="tab-gomb"
onfocus="váltTabTartalom('tab3')">
Tab 3 (rossz)
</button>
<div id="tab-tartalom">
<p>Eredeti tartalom - ez változni fog fókusz eseményekre</p>
</div>
</div>
<!-- ROSSZ: Accordion fókuszra kinyitás -->
<div class="accordion">
<button class="accordion-fejléc"
onfocus="document.getElementById('accordion-tartalom').style.display='block'">
Kérdés 1: Mi ez a szolgáltatás? (rossz)
</button>
<div id="accordion-tartalom" style="display: none;">
<p>Ez a válasz váratlanul jelenik meg fókuszra.</p>
</div>
</div>
</section>
</div>
<!-- Váratlan modal-ok -->
<div id="váratlan-modal" class="modal" style="display: none;">
<div class="modal-tartalom">
<h3>Váratlan modal!</h3>
<p>Ez a modal váratlanul jelent meg fókusz eseményre.</p>
<button onclick="this.parentElement.parentElement.style.display='none'">
Bezárás
</button>
</div>
</div>
<div id="info-overlay" class="overlay">
<div class="overlay-tartalom">
<h3>Információs overlay</h3>
<p>Ez az overlay váratlanul jelent meg.</p>
<button onclick="this.parentElement.parentElement.classList.remove('aktív')">
Bezárás
</button>
</div>
</div>
<div id="opciók-popup" class="tooltip-popup" style="visibility: hidden;">
<p>Ez egy váratlan tooltip popup.</p>
</div>
<script>
// ROSSZ gyakorlatok - ne használd ezeket!
function váltTabTartalom(tabId) {
// ROSSZ: Tartalom váltása fókusz eseményre
const tartalom = document.getElementById('tab-tartalom');
switch(tabId) {
case 'tab1':
tartalom.innerHTML = '<p>Tab 1 tartalma - váratlanul változott!</p>';
break;
case 'tab2':
tartalom.innerHTML = '<p>Tab 2 tartalma - fókusz miatt váltott!</p>';
break;
case 'tab3':
tartalom.innerHTML = '<p>Tab 3 tartalma - ez is váratlan!</p>';
break;
}
// ROSSZ: A tartalom váltása tájékozódási zavarhoz vezet
}
// Még több ROSSZ példa:
// ROSSZ: Automatikus form submit fókuszra
function automatikusSubmit() {
document.getElementById('hibás-form').submit();
}
// ROSSZ: Scroll pozíció váltása fókuszra
function scroll ToTarget() {
window.scrollTo(0, 500);
}
// ROSSZ: URL hash váltása fókuszra
function váltHash() {
window.location.hash = '#new-section';
}
// ROSSZ: Felugró ablak új tab-ban fókuszra
function újTabNyitás() {
window.open('new-page.html', '_blank');
}
</script>
<style>
.hibás-popup-példák {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.rossz-helpek,
.rossz-modal-kezelés,
.rossz-tartalom-váltás {
background: #ffe6e6;
border: 2px solid #ff6b6b;
padding: 15px;
margin: 15px 0;
border-radius: 8px;
}
.rossz-helpek h3,
.rossz-modal-kezelés h3,
.rossz-tartalom-váltás h3 {
color: #dc3545;
margin-top: 0;
}
.űrlap-mező {
margin: 15px 0;
}
.űrlap-mező label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.űrlap-mező input,
.űrlap-mező select {
width: 100%;
padding: 8px;
border: 2px solid #ff6b6b;
border-radius: 4px;
background: #fff5f5;
}
.tab-gomb {
background: #dc3545;
color: white;
border: none;
padding: 10px 15px;
margin: 5px;
border-radius: 4px 4px 0 0;
cursor: pointer;
}
.accordion-fejléc {
background: #dc3545;
color: white;
border: none;
padding: 10px;
width: 100%;
text-align: left;
cursor: pointer;
border-radius: 4px;
}
#tab-tartalom {
background: #fff;
border: 2px solid #dc3545;
padding: 15px;
margin-top: 5px;
}
#accordion-tartalom {
background: #fff5f5;
border: 2px solid #dc3545;
border-top: none;
padding: 15px;
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(220, 53, 69, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-tartalom {
background: white;
padding: 20px;
border-radius: 8px;
border: 3px solid #dc3545;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 193, 7, 0.9);
display: none;
justify-content: center;
align-items: center;
z-index: 999;
}
.overlay.aktív {
display: flex;
}
.overlay-tartalom {
background: white;
padding: 20px;
border-radius: 8px;
border: 3px solid #ffc107;
}
.tooltip-popup {
position: absolute;
background: #333;
color: white;
padding: 10px;
border-radius: 4px;
margin-top: 5px;
z-index: 100;
}
</style>
<div class="hibák-összefoglalása">
<h3>🚫 Összefoglalás: Miért hibásak ezek a megoldások?</h3>
<ol>
<li><strong>Váratlan kontextusváltozás:</strong> Popup-ok, modal-ok, új ablakok váratlan megjelenése</li>
<li><strong>Billentyűzetes navigáció megszakítása:</strong> Tab navigáció lehetetlenné válik</li>
<li><strong>Képernyőolvasó zavar:</strong> Váratlan announce-ok és kontextus váltások</li>
<li><strong>Kognitív terhelés:</strong> A felhasználó nem tudja megjósolni, mi fog történni</li>
<li><strong>WCAG 3.2.1 szabály megsértése:</strong> Fókusz eseményre nem szabad kontextusváltozás</li>
</ol>
</div>
<style>
.hibák-összefoglalása {
background: #f8d7da;
border: 2px solid #dc3545;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.hibák-összefoglalása h3 {
color: #721c24;
margin-top: 0;
}
.hibák-összefoglalása ol {
color: #721c24;
}
</style>
<!-- Minden fenti példa sérti a WCAG 3.2.1 szabványt, mert fókusz eseményre
váratlan kontextusváltozásokat okoz felhasználói értesítés nélkül. -->
Probléma: A váratlan popup-ok, modal ablak megnyitások és overlay-ek fókusz eseményre megzavarják a felhasználókat és megszakítják a navigációs folyamatot.
Váratlan fókusz áthelyezés
<!-- Rossz: Váratlan fókusz áthelyezések -->
<div class="hibás-fókusz-kezelés">
<h2>Hibás fókusz áthelyezési példák</h2>
<p><strong>Figyelmeztetés:</strong> Az alábbi elemek rosszul kezelik a fókuszt!</p>
<section class="rossz-űrlap-navigáció">
<h3>Hibás űrlap navigáció</h3>
<form class="problémás-form">
<div class="mező-sor">
<label for="első-mező">Első mező:</label>
<!-- ROSSZ: Fókuszra a következő mezőre ugrik -->
<input type="text"
id="első-mező"
name="field1"
onfocus="document.getElementById('harmadik-mező').focus()">
<!-- Probléma: Átugrik a második mezőt, zavart okoz -->
</div>
<div class="mező-sor">
<label for="második-mező">Második mező:</label>
<!-- ROSSZ: Fókuszra visszaugrik az első mezőre -->
<input type="text"
id="második-mező"
name="field2"
onfocus="document.getElementById('első-mező').focus()">
<!-- Probléma: Végtelen fókusz hurok lehet -->
</div>
<div class="mező-sor">
<label for="harmadik-mező">Harmadik mező:</label>
<!-- ROSSZ: Fókuszra a form elején kezd újra -->
<input type="text"
id="harmadik-mező"
name="field3"
onfocus="document.getElementById('első-mező').focus()">
<!-- Probléma: Visszaugrik az első mezőre -->
</div>
<div class="mező-sor">
<label for="negyedik-mező">Negyedik mező:</label>
<!-- ROSSZ: Fókuszra teljesen máshová ugrik -->
<input type="text"
id="negyedik-mező"
name="field4"
onfocus="document.getElementById('külső-gomb').focus()">
<!-- Probléma: Távoli elemre ugrik a fókusz -->
</div>
<button type="submit">Elküldés</button>
</form>
</section>
<section class="rossz-navigációs-logika">
<h3>Hibás navigációs logika</h3>
<div class="hibás-menü">
<h4>Problémás menü rendszer</h4>
<nav>
<ul>
<li>
<!-- ROSSZ: Fókuszra a lista végére ugrik -->
<a href="#home"
onfocus="document.querySelector('nav ul li:last-child a').focus()">
Főoldal (rossz)
</a>
</li>
<li>
<!-- ROSSZ: Fókuszra random elem fókuszba kerül -->
<a href="#about"
onfocus="document.getElementById('véletlenszerű-elem').focus()">
Rólunk (rossz)
</a>
</li>
<li>
<!-- ROSSZ: Fókuszra a body-ra ugrik (elveszti fókuszt) -->
<a href="#contact"
onfocus="document.body.focus()">
Kapcsolat (rossz)
</a>
</li>
<li>
<!-- ROSSZ: Fókuszra oldal tetejére scroll és fókusz váltás -->
<a href="#services"
onfocus="window.scrollTo(0,0); document.getElementById('header-logo').focus()">
Szolgáltatások (rossz)
</a>
</li>
</ul>
</nav>
</div>
<div class="hibás-widget-ok">
<h4>Problémás widget-ek</h4>
<!-- ROSSZ: Slider fókuszra random értékre ugrik -->
<div class="slider-container">
<label for="hibás-slider">Hangerő (rossz implementáció):</label>
<input type="range"
id="hibás-slider"
min="0"
max="100"
value="50"
onfocus="this.value=100; document.getElementById('híbás-kijelző').focus()">
<!-- Probléma: Fókuszra az érték változik és másik elemre ugrik -->
<div id="híbás-kijelző" tabindex="0">Kijelző elem</div>
</div>
<!-- ROSSZ: Checkbox fókuszra másik checkbox-ra ugrik -->
<div class="checkbox-csoport">
<h5>Hibás checkbox navigáció</h5>
<label>
<input type="checkbox"
id="checkbox1"
onfocus="document.getElementById('checkbox3').focus()">
Első opció (ugrik a harmadikra)
</label>
<label>
<input type="checkbox"
id="checkbox2"
onfocus="document.getElementById('checkbox1').focus()">
Második opció (ugrik az elsőre)
</label>
<label>
<input type="checkbox"
id="checkbox3"
onfocus="document.getElementById('checkbox2').focus()">
Harmadik opció (ugrik a másodikra)
</label>
</div>
</div>
</section>
<section class="dinamikus-fókusz-problémák">
<h3>Dinamikus fókusz problémák</h3>
<!-- ROSSZ: Gomb fókuszra új elem jelenik meg és az kapja a fókuszt -->
<button id="dinamikus-gomb"
onfocus="létrehozÚjElemÉsFókusz()">
Dinamikus tartalom (rossz)
</button>
<div id="dinamikus-tartalom"></div>
<!-- ROSSZ: Link fókuszra iframe betöltődik és az kapja a fókuszt -->
<a href="#iframe-content"
onfocus="betöltÉsFókuszIframe()">
Iframe betöltése (rossz)
</a>
<iframe id="dinamikus-iframe" style="display: none; width: 100%; height: 200px;"></iframe>
</section>
</div>
<!-- Külső elemek a teszteléshez -->
<div style="margin: 50px 0;">
<button id="külső-gomb">Külső gomb (ide ugrik a fókusz)</button>
<button id="véletlenszerű-elem">Véletlenszerű elem</button>
<div id="header-logo" tabindex="0">Logo elem (ide ugrik a fókusz)</div>
</div>
<script>
// ROSSZ gyakorlatok - ezeket ne használd!
function létrehozÚjElemÉsFókusz() {
// ROSSZ: Új elem létrehozása és azonnali fókusz áthelyezés
const újElem = document.createElement('input');
újElem.type = 'text';
újElem.placeholder = 'Váratlanul létrejött mező';
újElem.id = 'váratlan-input';
document.getElementById('dinamikus-tartalom').appendChild(újElem);
// ROSSZ: Fókusz azonnali áthelyezése az új elemre
újElem.focus();
}
function betöltÉsFókuszIframe() {
// ROSSZ: Iframe megjelenítése és fókusz áthelyezés
const iframe = document.getElementById('dinamikus-iframe');
iframe.src = 'about:blank';
iframe.style.display = 'block';
// ROSSZ: Fókusz áthelyezése az iframe-re
iframe.focus();
}
// Még több ROSSZ példa:
// ROSSZ: Véletlen fókusz áthelyezések
function véletlenFókuszUgrás() {
const elemek = document.querySelectorAll('button, input, a');
const véletlenIndex = Math.floor(Math.random() * elemek.length);
elemek[véletlenIndex].focus();
}
// ROSSZ: Időzített fókusz váltás
function időzítettFókuszVáltás() {
setTimeout(() => {
document.getElementById('véletlenszerű-elem').focus();
}, 100);
}
// ROSSZ: Kondicionális fókusz áthelyezés
function kondicionálisFókuszVáltás(elem) {
if (elem.value.length > 3) {
document.getElementById('harmadik-mező').focus();
}
}
</script>
<style>
.hibás-fókusz-kezelés {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.rossz-űrlap-navigáció,
.rossz-navigációs-logika,
.dinamikus-fókusz-problémák {
background: #ffe6e6;
border: 2px solid #ff6b6b;
padding: 15px;
margin: 15px 0;
border-radius: 8px;
}
.mező-sor {
margin: 10px 0;
}
.mező-sor label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.mező-sor input {
width: 100%;
padding: 8px;
border: 2px solid #ff6b6b;
border-radius: 4px;
background: #fff5f5;
}
.hibás-menü ul {
list-style: none;
padding: 0;
}
.hibás-menü li {
margin: 5px 0;
}
.hibás-menü a {
color: #dc3545;
text-decoration: none;
padding: 8px 12px;
border: 1px solid #dc3545;
border-radius: 4px;
display: inline-block;
}
.slider-container,
.checkbox-csoport {
background: #fff3cd;
border: 2px solid #ffc107;
padding: 10px;
margin: 10px 0;
border-radius: 4px;
}
.checkbox-csoport label {
display: block;
margin: 5px 0;
}
#dinamikus-tartalom {
background: #f8f9fa;
border: 1px solid #dee2e6;
padding: 10px;
margin: 10px 0;
min-height: 50px;
border-radius: 4px;
}
#header-logo {
background: #007bff;
color: white;
padding: 10px;
text-align: center;
border-radius: 4px;
margin: 10px 0;
}
/* Figyelmeztetés stílus hibás elemekhez */
input[onfocus],
button[onfocus],
a[onfocus] {
border: 3px solid #dc3545 !important;
background-color: #fff5f5 !important;
}
</style>
<div class="fókusz-hibák-összefoglalója">
<h3>🔄 Fókusz áthelyezési hibák összefoglalása</h3>
<ul>
<li><strong>Kiszámíthatatlan navigáció:</strong> A felhasználó nem tudja, hová kerül a fókusz</li>
<li><strong>Tab sorrend megszakítása:</strong> A logikus navigációs folyamat megtörik</li>
<li><strong>Végtelen hurkok:</strong> A fókusz körbe-körbe ugrálhat elemek között</li>
<li><strong>Elveszett fókusz:</strong> A felhasználó nem tudja, hol van a fókusz</li>
<li><strong>Képernyőolvasó zavar:</strong> Váratlan ugrások zavarják a felolvasást</li>
<li><strong>WCAG 3.2.1 sérülés:</strong> Váratlan kontextus változás fókusz eseményre</li>
</ul>
</div>
<style>
.fókusz-hibák-összefoglalója {
background: #f8d7da;
border: 2px solid #dc3545;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.fókusz-hibák-összefoglalója h3 {
color: #721c24;
margin-top: 0;
}
.fókusz-hibák-összefoglalója ul {
color: #721c24;
}
</style>
<!-- Minden fenti példa sérti a WCAG 3.2.1 szabványt, mert fókusz eseményre
váratlan fókusz áthelyezéseket okoz, ami kontextusváltozásnak minősül. -->
Probléma: A váratlan fókusz áthelyezések megszakítják a természetes navigációs folyamatot a weboldalon és kiszámíthatatlanná teszik a felhasználó információ szerzését.
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!