Navbar - Tillgänglighetsförbättringar

🎯 Tillgänglighetsförbättringar

Denna demo visar de tillgänglighetsförbättringar som har implementerats i SweNavbar-komponenten:

⌨️ Tangentbordsnavigation

Testa dessa tangentbordskortkommandon:

✨ Ny funktionalitet - Focus Trap:

🎛️ Testa tillgänglighetsegenskaper

Navigation:

Användarinformation:

Språk:

Sökfunktion:

Rubrik:

🔒 Testa Focus Trap i Drawer-menyn

Steg-för-steg instruktioner för att testa focus trap:

  1. Tryck på Tab flera gånger tills du når hamburger-ikonen (längst upp till höger)
  2. Tryck Enter eller Space för att öppna drawer-menyn
  3. Observera: Fokus flyttas automatiskt till stäng-knappen (×)
  4. Tryck Tab upprepade gånger för att navigera genom drawer-menyalternativen
  5. Observera: När du når sista menyalternativet och trycker Tab igen, cyklar fokus tillbaka till stäng-knappen
  6. Testa Shift + Tab för att navigera bakåt - fokus cyklar från första till sista elementet
  7. Hitta ett menyalternativ med en pil (›) och tryck Enter eller Space för att expandera undermenyn
  8. Observera: Pilen roterar (›→∨) och aria-expanded ändras från "false" till "true"
  9. Tryck Escape för att stänga drawer
  10. Observera: Fokus återställs automatiskt till hamburger-ikonen

💡 Tips: Använd en skärmläsare (VoiceOver på Mac: Cmd+F5, NVDA/JAWS på Windows) för att höra hur aria-expanded och aria-haspopup annonseras när du navigerar.

🔍 Tillgänglighetstest

För att testa tillgängligheten kan du:

🛠️ Teknisk implementation

De viktigaste tillgänglighetsförbättringarna som implementerats:

1. Focus Trap i Drawer (NYA!):

// Hämta alla fokuserbara element i drawer
function getFocusableElements(container) {
    const selectors = 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])';
    return Array.from(container.querySelectorAll(selectors))
        .filter(el => el.offsetParent !== null);
}

// Hantera Tab/Shift+Tab för att cykla fokus
function handleDrawerFocusTrap(e) {
    if (e.key !== 'Tab') return;
    const focusableElements = getFocusableElements(drawer);
    const firstFocusable = focusableElements[0];
    const lastFocusable = focusableElements[focusableElements.length - 1];

    // Cykla fokus inom drawer
    if (e.shiftKey && document.activeElement === firstFocusable) {
        e.preventDefault();
        lastFocusable.focus();
    } else if (!e.shiftKey && document.activeElement === lastFocusable) {
        e.preventDefault();
        firstFocusable.focus();
    }
}
                

2. ARIA-expanded för menyalternativ med barn (NYA!):

// Sätt ARIA-attribut för menyalternativ med barn
menuItem.setAttribute('role', 'button');
menuItem.setAttribute('aria-expanded', 'false');
menuItem.setAttribute('aria-haspopup', 'true');
menuItem.setAttribute('tabindex', '0');

// Uppdatera aria-expanded vid toggle
function toggleSubmenu(e) {
    const isExpanded = submenuContainer.style.maxHeight !== '0px';
    if (isExpanded) {
        menuItem.setAttribute('aria-expanded', 'false');
    } else {
        menuItem.setAttribute('aria-expanded', 'true');
    }
}

// Tangentbordsstöd för expansion
menuItem.addEventListener('keydown', function(e) {
    if (e.key === 'Enter' || e.key === ' ') {
        e.preventDefault();
        toggleSubmenu(e);
    }
});
                

3. Fokushantering vid öppning/stängning:

function openDrawer() {
    // Spara element som öppnade drawer
    drawerTriggerElement = document.activeElement;

    // Aktivera focus trap
    document.addEventListener('keydown', handleDrawerFocusTrap);

    // Flytta fokus till stäng-knappen
    setTimeout(() => closeButton.focus(), 50);
}

function closeDrawer() {
    // Avaktivera focus trap
    document.removeEventListener('keydown', handleDrawerFocusTrap);

    // Återställ fokus till hamburger-ikonen
    if (drawerTriggerElement && drawerTriggerElement.focus) {
        drawerTriggerElement.focus();
    }
}
                

4. ARIA-attribut för navigation:

navbar.setAttribute('role', 'banner');
navbar.setAttribute('aria-label', 'Huvudnavigation');
brand.setAttribute('role', 'button');
brand.setAttribute('aria-label', 'Logotyp, gå till startsida');
navList.setAttribute('role', 'menubar');
link.setAttribute('role', 'menuitem');
                

5. Fokusindikatorer:

/* Fokusindikatorer för drawer-menyalternativ */
.drawer-menu-item:focus {
    outline: 2px solid var(--navbar-yellow);
    outline-offset: -2px;
    background-color: rgba(255, 255, 255, 0.1) !important;
}

/* Högt kontrast för tillgänglighet */
@media (prefers-contrast: high) {
    .drawer-menu-item:focus {
        outline-color: var(--navbar-white);
        outline-width: 3px;
    }
}
                

📚 WCAG 2.1 Level A & AA - Riktlinjer som följs

✅ Ny compliance: Med focus trap-implementationen uppfyller komponenten nu WCAG 2.1 Level A Success Criterion 2.1.2 (No Keyboard Trap) genom att:
• Fånga fokus inom drawer när den är öppen
• Tillåta användare att stänga drawer med Escape-tangenten
• Återställa fokus till utlösande element vid stängning