Produktsidan i webbutiken: varianter, galleri och knappar
Så gör du val av storlek och antal, slutsålda varianter, bildgalleri, inbäddade tjänster och knappnamn tillgängliga, med kodexempel och tester per punkt.
Det här är teknisk vägledning och inte juridisk rådgivning. För tolkningsfrågor om Lag (2023:254) om vissa produkters och tjänsters tillgänglighet, vänd dig till Post- och telestyrelsen (PTS).
På produktsidan gör kunden sina val innan varan hamnar i varukorgen: storlek, färg, antal, kanske ett foto till i galleriet. Det är också den sida där plattformarnas färdiga teman oftast har byggts om med eget skript, och därför den sida där det är lättast att tappa tangentbordet eller skärmläsaren. Den här guiden följer checklistans grupp Produktsidan och går igenom fem områden: varianter, slutsålda varor, galleriet, inbäddade tjänster och knappnamn.
Varianter: storlek, färg och antal (1.3.1, 4.1.2 och 2.1.1)
Kriteriet Information och relationer kräver att det som syns för ögat också går att läsa av för programvara. W3C ger etiketter på formulärfält som exempel och nämner fieldset med legend för att gruppera relaterade fält. På en produktsida betyder det att ”Storlek” ska höra ihop med alla storleksvalen, och att ett antalsfält har en etikett kopplad till fältet.
Före, valen är bara fyrkanter med klickskript:
<div class="val" onclick="valj('s')">S</div>
<div class="val" onclick="valj('m')">M</div>
<div class="val" onclick="valj('l')">L</div>
Efter, med riktiga radioknappar i en grupp:
<fieldset>
<legend>Storlek</legend>
<label><input type="radio" name="storlek" value="s"> S</label>
<label><input type="radio" name="storlek" value="m"> M</label>
<label><input type="radio" name="storlek" value="l"> L</label>
</fieldset>
<label for="antal">Antal</label>
<input type="number" id="antal" name="antal" min="1" value="1">
Rullistan för färg får en etikett på samma sätt:
<label for="farg">Färg</label>
<select id="farg" name="farg">
<option value="gra">Grå</option>
<option value="bla">Blå</option>
</select>
Det här är också svaret på Namn, roll, värde: W3C skriver att vanliga HTML-kontroller klarar kriteriet när de används som tänkt, medan en div eller span som får fungera som kontroll behöver extra arbete och räknas som ett fel om den saknar roll. Deque beskriver dessutom att en kontroll utan programmatisk etikett fångas av axe-reglerna label och select-name.
Tangentbordet hör till Tangentbord, som kräver att all funktion går att nå utan mus. Riktiga radioknappar hanteras av webbläsaren. Bygger du egna val med role=radio gäller i stället mönstret i ARIA Authoring Practices. Där flyttar Tab fokus in i och ut ur gruppen, fokus hamnar på den valda knappen eller på den första, piltangenterna flyttar och markerar nästa eller föregående val, och mellanslag väljer den knapp som har fokus. Varje knapp har role=radio och aria-checked, och gruppen har role=radiogroup med en synlig etikett. Det är mycket att bygga om, så använd den inbyggda radioknappen om du kan.
Sist: ändrar ett val automatiskt något mer än priset, till exempel byter sida eller flyttar fokus, behöver kunden veta det i förväg. Det tar kriteriet Vid inmatning upp. W3C anger tre vägar: berätta det före valet, låt en knapp utföra ändringen eller se till att ändringen inte byter sammanhang. Mer om det finns i Kontroll före köp i kassan.
Så testar du: gå till varianterna med bara Tab och piltangenter. Kan du välja storlek och antal utan mus? Läser en skärmläsare upp ”Storlek” och sedan valet, eller bara ”S”?
Slutsålda varianter (1.4.1)
Användning av färger säger att färg inte får vara det enda sättet att visa information. W3C beskriver att färg gärna får användas, men att något annat synligt ska bära samma budskap. Sidan tar inte upp slutsålda varor som exempel, men principen är densamma som för obligatoriska fält: en grå ruta med streck över berättar inget för den som inte ser skillnaden i färg, och inget alls för den som använder skärmläsare.
Före, bara klass och färg:
<label class="slut"><input type="radio" name="storlek" value="xl" disabled> XL</label>
Efter, med text som både syns och läses:
<label class="slut">
<input type="radio" name="storlek" value="xl" disabled aria-describedby="xl-info"> XL
<span id="xl-info">Slutsåld</span>
</label>
Texten Slutsåld finns i koden och syns bredvid valet. En överstrykning eller grå ton får finnas kvar som extra signal. Ett inaktiverat fält med disabled tas ur tabbordningen, vilket betyder att tangentbordsanvändaren aldrig stannar vid det och därför inte hör beskedet. Vill du att den som tabbar ska höra att XL finns men är slut kan du i stället låta valet vara fokuserbart och visa texten tydligt intill det, eller lägga en rad före gruppen som säger vilka storlekar som är slut.
Så testar du: titta på sidan i gråskala (de flesta datorer och telefoner har ett läge för det i tillgänglighetsinställningarna). Går det fortfarande att se vilka varianter som är slut?
Bildgalleri och zoom (2.1.1 och 4.1.2)
Galleriet består oftast av en stor bild, miniatyrer, pilar för att bläddra och en zoomfunktion. Det här är de delarna som går sönder:
- Pilarna är en ikon i en div eller en knapp utan namn.
- Miniatyrerna reagerar på klick men går inte att fokusera.
- Zoomen öppnar ett överlägg som fokus aldrig kommer in i, eller som inte går att stänga med Esc.
Namn, roll, värde och Tangentbord täcker alla tre. W3C räknar det som ett fel när en kontroll bara svarar på pekarhändelser, och som ett fel när skript tar bort fokus från ett element som får det. Pilar ska vara knappar med ett namn som beskriver funktionen:
<div role="group" aria-label="Produktbilder">
<button type="button" aria-label="Föregående bild">
<svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20"><path d="M12 3L5 10l7 7"></path></svg>
</button>
<button type="button" aria-label="Nästa bild">
<svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20"><path d="M8 3l7 7-7 7"></path></svg>
</button>
</div>
Miniatyrerna görs om till knappar om de växlar bild, och får ett namn som säger vilken bild det gäller, till exempel ”Visa bild 2 av 4”. Texten på bilderna själva behandlar vi inte här. Den finns i Alt-texter för produktbilder.
För zoomen gäller samma sak som för andra överlägg: fokus flyttas in när det öppnas, Esc och en stängknapp med namn tar ut kunden, och fokus går tillbaka till knappen som öppnade det. Mer om det i Tangentbord och synligt fokus i webbutiken.
Så testar du: gå igenom galleriet med Tab och Enter. Kan du bläddra, öppna zoomen och komma ut igen? Läser skärmläsaren upp ”Nästa bild”, eller bara ”knapp”?
Inbäddade tjänster (4.1.2)
Recensioner, delbetalning och videor kommer ofta som en iframe från en annan leverantör. Deque beskriver regeln frame-title: varje iframe behöver ett title som inte är tomt och som berättar vad ramen innehåller, och titlarna bör vara unika på sidan. Regeln hör till samma kriterium som ovan, Namn, roll, värde.
<iframe src="https://exempel.se/recensioner" title="Kundrecensioner för produkten"></iframe>
Skriv titeln som en kort beskrivning av innehållet, inte som ett varumärke och inte som ”iframe”. Har ramen kod som du inte styr över, be leverantören om en inställning för titeln. Mer om iframes finns i avsnittet ”Iframe utan titel” i Länktexter, rubriker och struktur i webbutiken.
Så testar du: sök efter iframe i sidans källkod. Har varje träff ett title med innehåll?
Knappnamn som matchar texten (2.5.3)
Etiketter i namn kräver att den text som syns på en knapp eller kontroll också finns med i dess namn i koden. Digg skriver att namnet inte behöver vara identiskt men måste innehålla den synliga texten, och W3C rekommenderar att namnet börjar med den. Skälet är röststyrning: den som styr med rösten säger det som syns på knappen, till exempel ”klicka Köp”, och det fungerar bara om namnet innehåller ordet.
Fel, namnet saknar den synliga texten:
<button aria-label="Lägg produkten i varukorgen">Köp</button>
Rätt, namnet börjar med den synliga texten:
<button aria-label="Köp Ullkofta grå">Köp</button>
Digg tar också upp flera knappar med samma text: ”Läs mer” på fem ställen som leder till olika innehåll gör det oklart för en röststyrd användare vilken man aktiverar. Digg rekommenderar, utöver lagkravet, samma namn bara för kontroller som gör exakt samma sak. W3C varnar för att aria-label och aria-labelledby ersätter den synliga texten i namnberäkningen, så använd dem försiktigt när det redan finns text.
Så testar du: leta efter aria-label på knappar och länkar som också har synlig text. Finns texten med i början av namnet? Har du en iPhone eller Windows kan du prova röststyrning på riktigt.
Vad AccessAudit kontrollerar
Det gratis testet på butik.nightwave.se/tillganglighet läser källkoden på upp till fem sidor. Det hittar fält utan etikett, knappar och länkar utan namn och iframes utan title. Det jämför inte knappars synliga text med deras namn, bedömer inte tangentbordet och ser inte om en variant är slut.
Månadsgranskningen kör axe-core i en riktig webbläsare med reglerna för WCAG 2.0 och 2.1, nivå A och AA, och går igenom sidorna med Tab. Den flaggar klickbara element som inte går att nå med tangentbord, element utan synlig fokusmarkering och fokusfällor. Axe-regeln label-content-name-mismatch, som jämför synlig text med namnet, är märkt experimentell i axe-core och avstängd som standard, så månadsgranskningen kör den inte. Val av storlek, färg och antal, galleriets pilar och slutsålda varianter måste du därför gå igenom själv. Checklistan visar vilka punkter som testas automatiskt.
Källor
Alla källor lästa 2026-10-27.
- Understanding 1.3.1 Info and Relationships, W3C
- Understanding 4.1.2 Name, Role, Value, W3C
- Understanding 2.1.1 Keyboard, W3C
- Understanding 1.4.1 Use of Color, W3C
- Understanding 2.5.3 Label in Name, W3C
- Understanding 3.2.2 On Input, W3C
- Radio Group Pattern, ARIA Authoring Practices Guide, W3C
- Se till att text på knappar och kontroller överensstämmer med maskinläsbara namn, Digg
- Deque, axe-core 4.11: frame-title
- Deque, axe-core 4.11: label-content-name-mismatch
- Deque, axe-core 4.11: label
- Deque, axe-core 4.11: select-name