2.3.1 - Három villanás vagy alatta

Röviden a szabványpontról

A WCAG 2.3.1 (Three Flashes or Below Threshold) előírja, hogy a webes tartalom nem tartalmazhat olyan elemeket, amelyek másodpercenként háromnál többször villognak, vagy a villogás nem éri el az általános villogási és vörös villogási küszöbértékeket. Ez minden olyan tartalomra vonatkozik, amely villogó vizuális elemeket tartalmaz, mint animációk, GIF-ek, videó tartalom vagy bármilyen egyéb villogó hatás.

Cél: Megakadályozni olyan tartalmak létrehozását, amelyek rohamokat vagy fizikai reakciókat válthatnak ki fényérzékeny epilepsziával vagy más rohamzavarokkal élő embereknél. Ez a kritérium biztosítja, hogy a villogó tartalom vagy biztonságos frekvenciájú legyen, vagy úgy legyen tervezve, hogy elkerülje a káros reakciók kiváltását.

Kiket érint

Elsődleges felhasználók: Fényérzékeny epilepsziával vagy más rohamokkal kapcsolatos állapotokkal élő emberek. A gyors villogásnak való kitettség rohamokat vagy más fizikai reakciókat okozhat.

Másodlagos előnyök: A villogás csökkentése vagy szabályozása előnyös a migrénnel, vestibularis zavarokkal és kognitív érzékenységgel élő felhasználóknak is, minimalizálva a zavaró vizuális ingereket. Javítja az általános felhasználói élményt a zavaró vagy kényelmetlen hatások elkerülésével.

Tesztelés

  1. Vizuális ellenőrzés: Manuálisan figyeld meg az oldalon található villogó vagy pislogó elemeket. Számold meg a másodpercenkénti villogások számát és jegyezd fel a színt és intenzitást
  2. Automatizált eszközök használata: Egyes akadálymentességi tesztelő eszközök képesek észlelni a küszöbértékeket meghaladó villogó tartalmat
  3. Videó képkocka analízis: Videó tartalom esetén elemezd a másodpercenkénti képkockákat a másodpercenként háromszornál többször villogó vagy nagy kontrasztú villogások észlelésére
  4. Színkontraszt és villogási küszöb ellenőrzés: Értékeld, hogy a villogó tartalom megfelel-e a „küszöb alatti” kritériumoknak a villogás intenzitásának és színkontrasztjának mérésével
  5. Felhasználói visszajelzés: Vonj be fényérzékeny epilepsziával élő felhasználókat a tesztelésbe vagy használj szimulációs eszközöket

Jó gyakorlatok

1. Biztonságos villogási frekvencia (maximum 3 villogás/másodperc)

<div class="safe-notification" role="alert" aria-live="assertive">
  <div class="notification-icon" aria-hidden="true">⚠️</div>
  <div class="notification-content">
    <h3>Fontos értesítés</h3>
    <p>Kérjük, olvassa el figyelmesen az alábbi információkat.</p>
  </div>
  <button class="dismiss-btn" onclick="dismissNotification(this)">Bezárás</button>
</div>

<style>
.safe-notification {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 20px;
  background: #fff3cd;
  border: 1px solid #ffeeba;
  border-radius: 8px;
  margin: 20px;
  max-width: 600px;
}

.notification-icon {
  font-size: 24px;
  animation: safeFlash 3s infinite;
}

/* Biztonságos villogás: csak 3 villogás 3 másodperc alatt */
@keyframes safeFlash {
  0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 100% { opacity: 1; }
  5%, 15%, 25% { opacity: 0.3; }
}

.notification-content {
  flex: 1;
}

.notification-content h3 {
  margin: 0 0 8px 0;
  font-size: 18px;
  color: #856404;
}

.notification-content p {
  margin: 0;
  color: #856404;
}

.dismiss-btn {
  background: #856404;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
}

.dismiss-btn:hover,
.dismiss-btn:focus {
  background: #6c5428;
  outline: 2px solid #333;
  outline-offset: 2px;
}
</style>

<script>
function dismissNotification(button) {
  const notification = button.closest('.safe-notification');
  notification.style.animation = 'none'; // Villogás leállítása
  notification.style.display = 'none';
}
</script>

Magyarázat: Az animáció csak 3 másodpercenként háromszor villog, megfelel a szabványnak, és a felhasználó leállíthatja.

2. Lágy átmenetek villogás helyett

<div class="status-indicator">
  <div class="indicator-light" id="status-light"></div>
  <div class="status-info">
    <h4>Rendszer állapot</h4>
    <p id="status-text">Kapcsolódás...</p>
  </div>
  <div class="status-controls">
    <button onclick="toggleAnimation()" id="animation-toggle">
      Animáció kikapcsolása
    </button>
  </div>
</div>

<style>
.status-indicator {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 20px;
  background: #f8f9fa;
  border: 1px solid #dee2e6;
  border-radius: 8px;
  margin: 20px;
  max-width: 400px;
}

.indicator-light {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #ffc107;
  position: relative;
}

.indicator-light.animated {
  animation: gentlePulse 4s ease-in-out infinite;
}

/* Lágy átmenet villogás helyett */
@keyframes gentlePulse {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.7);
  }
  50% {
    opacity: 0.7;
    transform: scale(1.1);
    box-shadow: 0 0 0 8px rgba(255, 193, 7, 0);
  }
}

.status-info h4 {
  margin: 0 0 5px 0;
  font-size: 16px;
  color: #495057;
}

.status-info p {
  margin: 0;
  color: #6c757d;
  font-size: 14px;
}

.status-controls button {
  background: #6c757d;
  color: white;
  border: none;
  padding: 8px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.status-controls button:hover,
.status-controls button:focus {
  background: #5a6268;
  outline: 2px solid #333;
  outline-offset: 2px;
}

/* Csökkentett mozgás preferencia */
@media (prefers-reduced-motion: reduce) {
  .indicator-light.animated {
    animation: none;
  }
}
</style>

<script>
let animationEnabled = true;
const light = document.getElementById('status-light');
const toggle = document.getElementById('animation-toggle');

// Kezdeti animáció bekapcsolása
light.classList.add('animated');

function toggleAnimation() {
  animationEnabled = !animationEnabled;
  
  if (animationEnabled) {
    light.classList.add('animated');
    toggle.textContent = 'Animáció kikapcsolása';
  } else {
    light.classList.remove('animated');
    toggle.textContent = 'Animáció bekapcsolása';
  }
}

// Rendszer preferenciák figyelése
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');

function handleReducedMotionChange() {
  if (prefersReducedMotion.matches) {
    light.classList.remove('animated');
    toggle.textContent = 'Animáció letiltva (rendszer beállítás)';
    toggle.disabled = true;
  } else {
    toggle.disabled = false;
    if (animationEnabled) {
      light.classList.add('animated');
      toggle.textContent = 'Animáció kikapcsolása';
    }
  }
}

// Kezdeti ellenőrzés és változások figyelése
handleReducedMotionChange();
prefersReducedMotion.addEventListener('change', handleReducedMotionChange);
</script>

Magyarázat: Lágy átmenetek használata a hirtelen villogás helyett, felhasználói vezérléssel és rendszer preferenciák tiszteletben tartásával.

3. Videó tartalom villogás szűréssel

<div class="video-container">
  <div class="video-controls">
    <h3>Videó lejátszó</h3>
    <div class="safety-controls">
      <label class="safety-checkbox">
        <input type="checkbox" id="flash-filter" checked>
        <span>Villogás szűrő bekapcsolása</span>
      </label>
      <div class="safety-warning" id="flash-warning">
        ⚠️ Ez a videó villogó elemeket tartalmazhat
      </div>
    </div>
  </div>
  
  <div class="video-wrapper">
    <video id="safe-video" controls preload="metadata">
      <source src="example-video.mp4" type="video/mp4">
      <track src="captions.vtt" kind="captions" srclang="hu" label="Magyar feliratok">
      A böngésző nem támogatja a video elemet.
    </video>
    <div class="flash-overlay" id="flash-overlay"></div>
  </div>
</div>

<style>
.video-container {
  max-width: 800px;
  margin: 20px auto;
  background: #f8f9fa;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.video-controls {
  padding: 20px;
  border-bottom: 1px solid #dee2e6;
}

.video-controls h3 {
  margin: 0 0 15px 0;
  color: #495057;
}

.safety-controls {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.safety-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.safety-checkbox input {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

.safety-warning {
  padding: 10px;
  background: #fff3cd;
  border: 1px solid #ffeeba;
  border-radius: 4px;
  color: #856404;
  font-size: 14px;
  display: none;
}

.safety-warning.show {
  display: block;
}

.video-wrapper {
  position: relative;
  background: #000;
}

#safe-video {
  width: 100%;
  height: auto;
  display: block;
}

.flash-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(128, 128, 128, 0.3);
  backdrop-filter: brightness(0.8) contrast(0.8);
  pointer-events: none;
  display: none;
}

.flash-overlay.active {
  display: block;
}

/* Hozzáférhető fókusz indikátorok */
.safety-checkbox:focus-within {
  outline: 2px solid #007bff;
  outline-offset: 2px;
  border-radius: 4px;
}

#safe-video:focus {
  outline: 3px solid #007bff;
  outline-offset: 2px;
}
</style>

<script>
const flashFilter = document.getElementById('flash-filter');
const flashOverlay = document.getElementById('flash-overlay');
const flashWarning = document.getElementById('flash-warning');
const video = document.getElementById('safe-video');

let flashDetectionActive = false;

// Villogás szűrő kapcsolása
flashFilter.addEventListener('change', (e) => {
  if (e.target.checked) {
    flashOverlay.classList.add('active');
    flashWarning.classList.remove('show');
    announceToScreenReader('Villogás szűrő bekapcsolva');
  } else {
    flashOverlay.classList.remove('active');
    flashWarning.classList.add('show');
    announceToScreenReader('Villogás szűrő kikapcsolva - figyelem: villogó tartalom lehet jelen');
  }
});

// Videó metaadatok betöltése után
video.addEventListener('loadedmetadata', () => {
  checkForFlashingContent();
});

// Villogó tartalom ellenőrzése (szimulált)
function checkForFlashingContent() {
  // Valós implementációban itt történne a videó analízis
  // Most szimulálunk egy villogó tartalmat tartalmazó videót
  const hasFlashingContent = true; // Szimulált eredmény
  
  if (hasFlashingContent) {
    flashWarning.classList.add('show');
    flashOverlay.classList.add('active');
    
    // ARIA élő régió értesítése
    announceToScreenReader('Figyelem: ez a videó villogó tartalmat tartalmazhat. A villogás szűrő automatikusan bekapcsolva.');
  }
}

// Videó lejátszás figyelése villogó tartalom észleléséhez
video.addEventListener('timeupdate', () => {
  if (!flashFilter.checked) return;
  
  // Szimulált villogás észlelés bizonyos időpontokban
  const currentTime = video.currentTime;
  const flashingTimeRanges = [
    {start: 10, end: 15},  // 10-15 másodperc között villogás
    {start: 45, end: 50}   // 45-50 másodperc között villogás
  ];
  
  const isInFlashingRange = flashingTimeRanges.some(range => 
    currentTime >= range.start && currentTime <= range.end
  );
  
  if (isInFlashingRange && !flashDetectionActive) {
    flashDetectionActive = true;
    flashOverlay.style.background = 'rgba(128, 128, 128, 0.5)';
    announceToScreenReader('Villogó szegmens észlelve, szűrő aktiválva');
  } else if (!isInFlashingRange && flashDetectionActive) {
    flashDetectionActive = false;
    flashOverlay.style.background = 'rgba(128, 128, 128, 0.3)';
  }
});

// Képernyőolvasó értesítése
function announceToScreenReader(message) {
  const announcement = document.createElement('div');
  announcement.setAttribute('role', 'status');
  announcement.setAttribute('aria-live', 'polite');
  announcement.className = 'sr-only';
  announcement.textContent = message;
  document.body.appendChild(announcement);
  
  setTimeout(() => {
    document.body.removeChild(announcement);
  }, 1000);
}

// Kezdeti állapot beállítása
flashOverlay.classList.add('active');
</script>

Magyarázat: Videó lejátszó villogás szűrővel, automatikus észleléssel és felhasználói vezérléssel.

Rossz gyakorlatok

Gyors villogó animáció (5+ villogás/másodperc)

<div class="dangerous-flash">VÉSZHELYZET!</div>

<style>
.dangerous-flash {
  padding: 20px;
  text-align: center;
  font-weight: bold;
  animation: rapidFlash 1s infinite;
}

@keyframes rapidFlash {
  0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 100% { 
    background: red; 
    color: white;
  }
  5%, 15%, 25%, 35%, 45%, 55%, 65%, 75%, 85%, 95% { 
    background: white; 
    color: red;
  }
}
</style>

Probléma: Ez az animáció másodpercenként 10-szer villog, messze meghaladva a biztonságos 3 villogás/másodperc határt.

Nagy kontrasztú piros villogás

<div class="red-flash-danger">FIGYELEM</div>

<style>
.red-flash-danger {
  padding: 30px;
  font-size: 24px;
  text-align: center;
  animation: redFlashDanger 0.5s infinite;
}

@keyframes redFlashDanger {
  0%, 100% { 
    background: #ff0000; 
    color: #ffffff; 
  }
  50% { 
    background: #ffffff; 
    color: #ff0000; 
  }
}
</style>

Probléma: Nagy kontrasztú piros és fehér között váltakozó villogás különösen veszélyes a fényérzékeny epilepsziával élőkre.

Vezérlők nélküli villogó tartalom

<div class="uncontrollable-flash">
  <img src="flashing-gif.gif" alt="Villogó animáció">
</div>

<style>
.uncontrollable-flash {
  animation: backgroundFlash 2s infinite;
}

@keyframes backgroundFlash {
  0%, 25%, 50%, 75%, 100% { background: yellow; }
  12%, 37%, 62%, 87% { background: orange; }
}
</style>

Probléma: Nincs lehetőség a villogás leállítására vagy szüneteltetésére.

Automatikus videó lejátszás villogó tartalommal

<video autoplay muted loop>
  <source src="flashing-video.mp4" type="video/mp4">
</video>

Probléma: Automatikusan elindul villogó tartalommal, figyelmeztetés vagy vezérlők nélkül.

Stroboszkóp hatású CSS animáció

<div class="strobe-effect">Disco fények</div>

<style>
.strobe-effect {
  animation: strobe 0.1s infinite;
}

@keyframes strobe {
  0%, 50% { 
    background: #ff00ff; 
    box-shadow: 0 0 20px #ff00ff;
  }
  25%, 75% { 
    background: #00ffff; 
    box-shadow: 0 0 20px #00ffff;
  }
}
</style>

Probléma: Rendkívül gyors váltakozás (10 villogás/másodperc) élénk színekkel, ami erős stroboszkóp hatást okoz.

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