Så valde vi de 46 reglerna: insidan av @holmdigital/engine

Var vi började
I flera klientuppdrag har vi sett samma mönster. Ett team kör axe-core i sin CI, får en ren rapport, och tror sig vara klara. Månader senare kommer ett brev från tillsynsmyndigheten. Rapporten hade missat saker som i WCAG-listan ser ut som marginella detaljer, men som i DOS-lagen eller EAA är tydligt utpekade krav.
Det var den typen av glapp vi ville stänga. Inte fler regler, utan rätt regler kopplade till rätt lag.
Vi byggde engine tillsammans på Holm Digital. Regelurvalet, WCAG-tolkningen och den juridiska mappningen är min domän. Koden och monorepot ligger på andra bord i teamet. Vi gjorde det en regel i taget, mot lagtext och tillsynspraxis.
Varför 46 och inte 80
Axe-core har över 80 kontroller. Pa11y ligger i samma härad. Lighthouse har runt 40 audits. Vi landade på 46.
Det är en medveten avvägning. När vi gick igenom WCAG 2.1 och 2.2 kriterium för kriterium mot EN 301 549, DOS-lagen, BITV 2.0, RGAA och EAA, började ett mönster synas. Vissa kriterier prövas sällan, eller prövas aldrig i tillsyn. Andra är det som tillsynsmyndigheter faktiskt går på när de skriver förelägganden.
Vi kallar dem konvergensregler. Det är reglerna där WCAG, EN 301 549 och den nationella lagstiftningen pekar på samma sak, med samma skärpa. Det är där den juridiska risken är konkret. Det är där vi lade vårt arbete.
Resultatet blev en databas där varje regel har:
- Relevant WCAG-kriterium
- Motsvarande punkt i EN 301 549
- Paragrafhänvisning i nationell lagstiftning för 16 länder
- Tillsynsmyndighet per land och sektor
- Sanktionsram där den är uttryckt i lag
Det fanns ingen sådan sammanställning att köpa. Det fanns inget open source-paket som gjorde jobbet. Vi fick bygga det själva, och vi bestämde tidigt att vi skulle dela det under MIT-licens.
Varför offentlig och privat sektor är två olika frågor
Det här är den del vi lagt mest interna diskussioner på, och där engine skiljer sig tydligast från alternativen.
Offentlig sektor i EU lyder under Web Accessibility Directive. I Sverige blir det DOS-lagen, tillsyn ligger hos DIGG. Kraven gäller sedan 2019, praxis har satt sig, tillsynen är igång.
Privat sektor lyder under European Accessibility Act. Den trädde i kraft 28 juni 2025. I Sverige är det PTS som är tillsynsmyndighet. Tillsynen är färskare än för DOS-lagen. Flera branscher som aldrig behövt tänka tillgänglighet juridiskt är plötsligt i ramen.
En scanner som inte vet vilken sektor den arbetar i kan inte svara på frågan "vad riskerar vi". Därför tar vår CLI ett --sector-argument. Sätt det till public om ni är offentlig aktör, private om ni är ett bolag. Engine dirigerar till rätt tillsynsmyndighet och rätt kravnivå.
import { getEnforcementBody } from '@holmdigital/standards';
getEnforcementBody('SE', 'public'); // DIGG
getEnforcementBody('SE', 'private'); // PTS
getEnforcementBody('DE', 'private'); // Marktüberwachungsbehörden enligt BFSG
Ett bolag som driver offentlig verksamhet på kontrakt behöver ofta svara mot båda regelverken. Vi flaggar det i rapporten så frågan inte faller mellan stolar. Den juridiska bedömningen gör kunden, men rapporten ska inte vara tyst om att den finns.
Den mest tidskrävande delen var inte koden
Scanner-motorn gick relativt snabbt att bygga. Puppeteer, axe-core, html-validate, lite limkod. Det svåra var något annat.
Att koppla 46 regler till paragrafer i 16 länders lagstiftning är hundratals datapunkter som var och en måste verifieras mot en faktisk lagtext, en föreskrift från tillsynsmyndigheten, eller i vissa fall ett avgörande. Det tog månader. Jag läste lagtext på språk jag inte talar flytande, kontrollerade mot engelska eller svenska översättningar, och dubbelkollade med jurister i nätverket när jag var osäker.
Vi har fortfarande poster märkta [?] i databasen där vi väntar på en andra källa innan vi tar bort osäkerhetsmarkeringen. Det är medvetet. Hellre en synlig osäkerhet än ett falskt påstående.
Tillsynspraxis skiljer sig också kraftigt mellan länderna. Norge använder dagböter, Nederländerna kräver självrapportering, och amerikanska ADA Title II drabbar numera även EU-bolag som säljer mot USA. Samma WCAG-kriterium kan alltså betyda helt olika saker rättsligt beroende på var ni verkar.
Scannern i CI
Engine är byggd för att köras i varje pipeline, inte bara innan lansering. Det är där efterlevnaden måste hända om den ska hålla över tid. Grundkommandot ser ut så här:
npx hd-a11y-scan https://example.se \
--country SE \
--sector public \
--ci \
--threshold critical \
--junit reports/a11y.xml
I CI-läge stannar bygget när något fel når tröskeln ni satt. Rapporten i JUnit-XML läses direkt av GitHub Actions, GitLab CI och Azure DevOps, med regel, WCAG-punkt, paragraf och myndighet synliga per fel.
I revisioner vi gjort för offentlig sektor är det sista det som betyder mest. Utvecklaren behöver inte veta vad DIGG heter. Rapporten säger det.
Shadow DOM och SPAs
Att se samma sida som användaren ser är inte en implementationsdetalj för oss. Det är själva frågan vi svarar på.
Det mesta på webben idag är React, Vue eller Angular. Mycket är byggt med Web Components. Standardverktygen tittar ofta bara på light DOM och missar mycket av det som ligger inkapslat.
Engine går igenom shadow roots och väntar ut JavaScript-rendering innan kontrollen körs. I praktiken betyder det att den ser samma sidinnehåll som användaren ser, inte den råa HTML som servern skickade. Ett verktyg som missar stora delar av innehållet kan inte svara på en lagfråga.
Komponentbiblioteket är inte efterhandskonstruktionen
@holmdigital/components växte fram samtidigt som standards-databasen. När vi byggde regelurvalet skrev jag ned för varje regel: vilken komponent löser det här strukturellt?
Ett formulärfält som saknar label är inte ett fel att rätta per sida. Det är en indikation på att teamet saknar en A11yInput-komponent. En tillgänglighetsförklaring som inte uppfyller DOS-lagens krav är inte en textfil att skriva om. Det är en AccessibilityStatement-komponent som ska generera rätt innehåll på rätt språk åt 13 språkversioner. Vi skriver felen så att lösningen pekar mot ett mönster, inte en patch.
Därför är komponenterna otematiserade, utan Radix-beroende, utan åsikter om design. Ni bygger er visuella identitet ovanpå, vi levererar den tillgängliga grunden.
Vad som inte finns än
46 regler mot axe-cores 80+ är en medveten begränsning, inte ett påstående att vi täcker allt. Vi täcker inte alla WCAG 2.2-kriterier ännu. Standards-databasen är inte komplett på WCAG 2.2-delarna, och några jurisdiktioner utanför EU är grovare mappade än de inom. Det står i README, det står i wikin, och det står här.
Aktuella versioner när jag skriver det här: engine@2.5.1, standards@2.4.0, components@2.3.0. Vi versionerar regelurvalet separat från koden så ni kan låsa er mot en specifik regeluppsättning i er CI och välja när ni vill flytta er fram.
Automatisk skanning räcker inte hela vägen
Det här är viktigt att säga rakt ut: ingen automatisk scanner, inte engine heller, kan hitta alla tillgänglighetsbrister. Branschpraxis säger att automatiserade verktyg fångar omkring 30 till 40 procent av det som WCAG faktiskt kräver.
Resten kräver en människa. En skärmläsare som testar faktiska användarflöden. En tangentbordsnavigering från första fokuspunkt till sista. En bedömning av om rubrikstrukturen är logisk, om felmeddelanden är begripliga, om animationer utlöser problem för personer med vestibulär känslighet. Det är kvalitativa bedömningar som ett verktyg inte kan göra.
Engine är byggt för att göra den automatiska delen så bra och juridiskt relevant som möjligt. Den manuella delen gör vi i konsultuppdrag, och det är där vi fångar det som ingen scanner kan se. Mer om vad vi levererar hittar ni på vår sida för tillgänglighetsanalys.
För er som vill längre än verktyget
Att installera @holmdigital/engine tar trettio sekunder. Att förstå vad rapporten betyder för just er organisation, vilka sektorgränser ni ligger i, och hur ni bygger ett arbetssätt som håller genom upphandlingar och revisioner, är arbete som fortsätter efter CI-körningen.
Den delen tar vi i konsultuppdrag på Holm Digital. Vi erbjuder manuell granskning där vi testar med skärmläsare, tangentbord och kognitiv belastning, går igenom faktiska användarflöden, och kompletterar scanner-rapporten med det som bara en människa kan bedöma. Resultatet blir en fullständig bild av vad ni faktiskt behöver åtgärda för att vara i enlighet med DOS-lagen eller EAA, inte bara det som engine kunde fånga automatiskt.
Läs mer och boka en tillgänglighetsanalys, eller kontakta oss direkt på karin@holmdigital.se. Vill ni köra själva finns allt på github.com/holmdigital/a11y-hd och wiki.holmdigital.se. MIT-licens, inga strängar.
Målet har hela tiden varit detsamma: rätt fel mot rätt lag, så en scanner-rapport faktiskt svarar på vad som står på spel.
Tillgänglighet borde inte vara en konkurrensfördel. Det borde vara en baseline.
#tillgänglighet #wcag #engine #eaa #dos-lagen #digitaltillgänglighet #opensource
