Fokusindikatorer og tastaturnavigation
Anvend ring-utilities til synlige fokusstyles, brug focus-visible for at undgå at vise fokus ved klik, og sørg for, at alle interaktive elementer kan nås med tastaturet.
Fokusindikatorer og tastaturnavigation er en gratis Tailwind CSS Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Tailwind CSS Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Tailwind CSS Academy-kurset indeholder 4 lektioner i alt.
Hvorfor tastaturnavigation er vigtig
Ikke alle brugere navigerer med en mus. Brugere med motoriske handicap er afhængige af tastaturer, switchstyring eller stemmestyring. Erfarne brugere foretrækker tastaturgenveje for at arbejde effektivt. Brugere af skærmlæsere navigerer primært med tastaturet. WCAG 2.4.3 Fokusrækkefølge kræver, at al funktionalitet kan betjenes via tastatur, og WCAG 2.4.7 kræver, at elementer med tastaturfokus har en synlig fokusindikator. Tailwind leverer utilities til at implementere begge krav.
Standardfokus-styling og dens problemer
Browsere viser som standard fokusindikatorer (typisk en blå kontur), men mange designere fjerner dem globalt med outline: none eller outline: 0, fordi de også vises ved museklik. Det er en alvorlig tilgængelighedsfejl — når konturen fjernes, har tastaturbrugere ingen visuel indikator, der viser, hvilket element der har fokus. Tailwinds moderne tilgang skelner mellem musefokus og tastaturfokus ved hjælp af pseudoklassen focus-visible.
/* NEVER do this globally */
* {
outline: none; /* destroys keyboard accessibility */
}
/* WRONG approach in Tailwind */
<button class='focus:outline-none'>...</button>
/* Removes focus for keyboard users too */
/* BETTER: suppress only for mouse users */
<button class='focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500'>
This button shows ring for keyboard users only
</button>Tailwinds variant til focus-visible
Varianten focus-visible: rammer CSS-pseudoklassen :focus-visible, som browseren anvender, når fokus blev opnået via tastaturnavigation (Tab- eller piletaster), men IKKE når fokus blev opnået ved et museklik. Det er præcis det, designere ønsker — ingen fokusring ved museklik, men en tydelig ring, når du navigerer med Tab. Brug focus-visible:ring-2 focus-visible:ring-blue-500 som standardfokusstil for interaktive elementer.
<!-- Standard button with focus-visible ring -->
<button
class='
px-4 py-2 bg-blue-600 text-white rounded-lg font-medium
focus:outline-none
focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2
'
>
Submit
</button>
<!-- Link with focus-visible style -->
<a
href='/docs'
class='
text-blue-700 underline
focus:outline-none
focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1 focus-visible:rounded
'
>
Documentation
</a>Hjælpeklasser til ringe som fokusindikatorer
Tailwinds ring-*-hjælpeklasser opretter en kontur baseret på CSS-egenskaben box-shadow, som vises uden for elementets kant uden at påvirke layoutet. ring-2 angiver en ring på 2 px, ring-blue-500 angiver dens farve, og ring-offset-2 tilføjer et mellemrum på 2 px mellem elementets kant og ringen. Det skaber en tydelig adskillelse, som gør fokusindikatoren mere synlig på farvede baggrunde.
<!-- Ring width options -->
<button class='ring-1 ...'>1px ring</button>
<button class='ring-2 ...'>2px ring (recommended)</button>
<button class='ring-4 ...'>4px ring (high visibility)</button>
<!-- Ring with offset (recommended for buttons) -->
<button class='focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2'>
With offset gap
</button>
<!-- Ring offset on dark background -->
<div class='bg-gray-900 p-4'>
<button class='
bg-blue-600 text-white px-4 py-2 rounded
focus-visible:ring-2 focus-visible:ring-blue-400
focus-visible:ring-offset-2 focus-visible:ring-offset-gray-900
'>Dark bg button</button>
</div>Tab-rækkefølge og tabindex
Tastaturets Tab-rækkefølge bør følge sidens visuelle læserækkefølge (fra top til bund og fra venstre mod højre i LTR-layouts). Brug semantiske HTML-elementer som button, a og input, der fra naturens side kan modtage fokus i den korrekte rækkefølge. Undgå at bruge tabindex til at gennemtvinge unaturlige fokusrækkefølger. Brug tabindex='0' til at gøre et ikke-interaktivt element (f.eks. en brugerdefineret komponent) fokuserbart med tastaturet, og tabindex='-1' til at fjerne et element fra Tab-rækkefølgen, mens det stadig kan fokuseres programmatisk.
<!-- Native elements: in tab order automatically -->
<button>First</button> <!-- tab stop 1 -->
<a href='/'>Second</a> <!-- tab stop 2 -->
<input type='text' /> <!-- tab stop 3 -->
<!-- Custom component: add to tab order with tabindex='0' -->
<div
role='button'
tabindex='0'
class='focus-visible:ring-2 focus-visible:ring-blue-500'
onKeyDown={(e) => e.key === 'Enter' && handleClick()}
>
Custom interactive element
</div>
<!-- Remove from tab order but allow programmatic focus -->
<div tabindex='-1' ref={modalPanelRef}>
Modal content (focused by JS, not Tab)
</div>Fokushåndtering i SPA'er
I Single Page Applications medfører skift af rute og opdatering af dynamisk indhold ikke en genindlæsning af siden, så browseren nulstiller ikke fokus. Efter navigation skal du flytte fokus programmatisk til den nye sides primære overskrift eller målet for et spring-over-link. Når en modal åbnes, skal du flytte fokus ind i den. Når den lukkes, skal du føre fokus tilbage til det element, der udløste den. Brug Reacts useRef og element.focus() til at implementere disse mønstre.
// Focus management after route change (React/Next.js)
import { useEffect, useRef } from 'react';
import { usePathname } from 'next/navigation';
function MainContent({ children }) {
const mainRef = useRef(null);
const pathname = usePathname();
useEffect(() => {
// Move focus to main content on route change
mainRef.current?.focus();
}, [pathname]);
return (
<main
ref={mainRef}
tabIndex={-1} // focusable but not in tab order
className='focus:outline-none'
>
{children}
</main>
);
}Links til at springe over navigation
Et link til at springe over navigation er et visuelt skjult link øverst på siden, som bliver synligt, når det får fokus. Det giver tastaturbrugere mulighed for at gå direkte til hovedindholdet uden at skulle navigere gennem alle navigationslinks. Dette kræves af WCAG 2.4.1 (omgåelse af blokke). Tailwinds sr-only- og focus:not-sr-only- (eller focus:ring-)hjælpeklasser implementerer dette elegant.
<!-- Skip nav: hidden until focused by keyboard -->
<a
href='#main-content'
class='
sr-only
focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-50
focus:bg-white focus:text-blue-700 focus:font-semibold
focus:px-4 focus:py-2 focus:rounded-lg focus:shadow-lg
focus:ring-2 focus:ring-blue-500
'
>
Skip to main content
</a>
<nav><!-- navigation --></nav>
<main id='main-content' tabIndex={-1} className='focus:outline-none'>
<!-- page content -->
</main>Navigationsmønstre med piletaster
Nogle interaktive komponenter bør reagere på piletaster ud over Tab. Værktøjslinjer og menulinjer bruger venstre- og højrepil til at flytte mellem elementer. Valgmenuer og listebokse bruger op- og nedpil. Faneområder bruger piletaster til at skifte fane. Når du implementerer piletastnavigation i brugerdefinerede komponenter, kræver det JavaScript-hændelsesbehandlere for tastaturhændelser, som flytter fokus mellem relaterede interaktive elementer.
// Arrow key navigation for a custom tab list
function TabList({ tabs }) {
const tabRefs = useRef([]);
const handleKeyDown = (e, index) => {
let newIndex;
if (e.key === 'ArrowRight') newIndex = (index + 1) % tabs.length;
if (e.key === 'ArrowLeft') newIndex = (index - 1 + tabs.length) % tabs.length;
if (e.key === 'Home') newIndex = 0;
if (e.key === 'End') newIndex = tabs.length - 1;
if (newIndex !== undefined) {
e.preventDefault();
tabRefs.current[newIndex]?.focus();
}
};
return (
<div role='tablist'>
{tabs.map((tab, i) => (
<button
key={tab.id}
ref={el => tabRefs.current[i] = el}
role='tab'
onKeyDown={e => handleKeyDown(e, i)}
className='focus-visible:ring-2 focus-visible:ring-blue-500'
>
{tab.label}
</button>
))}
</div>
);
}Fokusstile med høj synlighed af hensyn til tilgængeligheden
WCAG 2.4.11 (fokusudseende, WCAG 2.2) kræver, at fokusindikatorer opfylder minimumskrav til størrelse og kontrast. En fokusring bør være mindst 2 px tyk og have mindst et kontrastforhold på 3:1 både mod det fokuserede element og den tilstødende baggrund. Tailwinds ring-2 med en tilstrækkeligt kontrasterende farve opfylder dette krav. Hvis du vil understøtte tilstande med høj kontrast, kan du overveje at bruge outline i stedet for box-shadow, som Windows' tilstand med høj kontrast understøtter.
/* High contrast mode compatible focus style */
@media (forced-colors: active) {
button:focus-visible,
a:focus-visible,
input:focus-visible {
outline: 3px solid ButtonText;
outline-offset: 2px;
}
}
/* Tailwind equivalent for standard mode */
<button
class='
focus:outline-none
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600
/* Fallback for High Contrast Mode uses CSS above */
'
>
Accessible button
</button>Test af tastaturnavigation
Test tastaturnavigation manuelt: Læg musen helt væk, og naviger gennem hele din applikation udelukkende med Tab, Shift+Tab, Enter, mellemrumstasten og piletasterne. Alle interaktive elementer skal kunne nås, alle handlinger skal kunne udføres, og alle fokuserede elementer skal have en synlig indikator. Værktøjer som axe DevTools kan automatisk finde manglende fokusindikatorer, men manuel test afslører problemer i den logiske rækkefølge, som automatiserede værktøjer ikke opdager.
/*
Keyboard navigation test checklist:
Tab through entire page:
[ ] Every interactive element is reachable
[ ] Every focused element shows a visible indicator
[ ] Tab order follows visual reading order
[ ] No focus traps outside intentional ones (modals)
Activate elements:
[ ] Enter activates buttons and links
[ ] Space activates checkboxes and toggles
[ ] Arrow keys navigate menus, tabs, selects
Modal behavior:
[ ] Focus enters modal on open
[ ] Tab stays inside modal while open
[ ] Escape closes modal
[ ] Focus returns to trigger on close
Automated:
axe-core, Lighthouse accessibility audit
*/Oprettelse af en global grundstil for fokus
Definér en ensartet fokusstil som en global grundstil i din CSS i stedet for at gentage den på hvert element. Brug addBase i et Tailwind-plugin, eller tilføj den i blokken @layer base i din globale CSS. Det sikrer, at alle elementer, der naturligt kan modtage fokus, som standard får en ensartet og tilgængelig fokusindikator, og at brugerdefinerede komponenter kun behøver at tilvælge det samme mønster.
/* globals.css — consistent focus baseline */
@layer base {
:focus-visible {
outline: 2px solid #3b82f6; /* blue-500 */
outline-offset: 2px;
border-radius: 0.25rem;
}
/* Remove outline only for mouse users */
:focus:not(:focus-visible) {
outline: none;
}
}
/* Components that need ring instead of outline: */
/* Still override per-element with focus-visible:ring-2 etc. */
<button class='focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500'>Hurtigt tjek
Test din forståelse af begreberne fra denne lektion i Tailwind CSS Mastery.
Opsummering af lektionen
I denne lektion lærte du, at focus-visible: kun viser fokusringe for tastaturbrugere, at ring-2 med ring-offset-2 skaber tilgængelige og visuelt tydelige fokusindikatorer, og at links til at springe over navigation sammen med sr-only giver tastaturbrugere mulighed for at springe gentagen navigation over. Nu går vi videre til ARIA-attributter og ser på, hvordan du bruger Tailwinds sr-only-hjælpeklasse til understøttelse af skærmlæsere.
Lær HTML med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “Fokusindikatorer og tastaturnavigation” gratis?
Ja — hele teksten til “Fokusindikatorer og tastaturnavigation” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Tailwind CSS Academy-kurset, skal du opgradere til CoddyKit PRO. Tailwind CSS Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Fokusindikatorer og tastaturnavigation”?
Anvend ring-utilities til synlige fokusstyles, brug focus-visible for at undgå at vise fokus ved klik, og sørg for, at alle interaktive elementer kan nås med tastaturet. Du øver dig i Tailwind CSS Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Tailwind CSS Academy?
Der kræves ingen tidligere erfaring. Tailwind CSS Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Fokusindikatorer og tastaturnavigation”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Tailwind CSS Academy-lektion?
Ja. Alle Tailwind CSS Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Farvekontrast og læsbar tekst
- Fokusindikatorer og tastaturnavigation
- ARIA-attributter og skærmlæsere
- Tilgængelige formularkomponenter