Webbutveckling 1 · område 4 · guide
UX, design och mobilanpassning
Guide till lektion 34–37. Den ska fungera för dig som var borta, och gå att slå i mitt under ett arbetspass. Alla exempel är hämtade ur den responsiva Vikstadssajten – koden här är samma kod som i förlagan.
Vad du kan efter guiden
- Få en sida att bete sig som en sida i en telefon, i stället för som en nedzoomad skärm.
- Bygga en layout som håller på varje bredd utan att du skriver en enda brytpunkt.
- Välja brytpunkter utifrån ditt innehåll, och säga varför just där.
- Rita en wireframe i två bredder och koda efter den.
- Säga vad som gör en sajt begriplig – och vilka konventioner du inte bör bryta.
- Köra WAVE och Lighthouse, läsa vad de säger och rätta felen.
- Ta dig igenom hela din sajt med enbart tangentbordet.
- Kontrollera kontrast i stället för att gissa.
1. Viewport-taggen och mobile first
Raden som måste finnas
<meta name="viewport" content="width=device-width, initial-scale=1">
Den ligger i head på varje sida i förlagan, och utan den spelar
resten av det här området ingen roll.
En telefon som möter en sida utan viewport-tagg antar att sidan är byggd för en dator. Den låtsas då vara ungefär 980 pixlar bred och zoomar ut alltihop tills det får plats. Resultatet är en sida där texten är för liten att läsa och dina media queries aldrig löser ut – telefonen tycker ju att den är bred.
width=device-width säger: använd skärmens faktiska bredd.
initial-scale=1 säger: börja på 100 procents zoom.
Öppna din sida i telefonen, ta bort raden, ladda om. Lägg tillbaka den. Det är den tydligaste demonstrationen i hela området, och den tar en minut.
Mobile first
Mobile first betyder att grundreglerna gäller den smala skärmen, och att media queries lägger till för de breda. Inte tvärtom.
/* Gäller alla. Den smala skärmen behöver inget extra. */
body > header {
padding: 1.5rem 2.5rem;
}
/* Lägger till när det finns plats. */
@media (min-width: 40rem) {
body > header {
display: flex;
justify-content: space-between;
}
}
Skälet är inte att telefoner är viktigare. Skälet är att det är lättare att
lägga till än att ta bort. Börjar du med desktoplayouten består ditt
mobilarbete av att nollställa saker – float: none,
width: auto, display: block – och varje sådan rad är en
rad som kan glömmas.
Praktiskt betyder det min-width i dina media queries, nästan alltid.
Prova själv
Öppna din sajt, gör fönstret så smalt det går, och läs igenom den. Skriv upp tre saker som inte fungerar. Det är din arbetslista för det här området.
2. Relativa enheter
En layout som mäts i px är låst vid en bredd. En layout som mäts
relativt anpassar sig av sig själv – och den som anpassar sig av sig själv behöver
färre brytpunkter. Det här avsnittet är alltså inte pyssel. Det är det som gör
nästa avsnitt kort.
De fem du behöver
| Enhet | Utgår från | Använd till |
|---|---|---|
rem | Webbläsarens grundstorlek | Typografi, avstånd, brytpunkter |
% | Föräldern | Bredder inuti sidan |
fr | Det som blir över i ett grid | Kolumnbredder |
vw | Fönstrets bredd | Sällan ensam. Bra inuti clamp() |
ch | Bredden på en nolla | Läsmått på text |
em finns också och utgår från elementets egen textstorlek. Den är
användbar men förvirrande, eftersom den ärvs och multipliceras. Håll dig till
rem tills du har skäl.
rem, och varför du inte ska röra html
1rem är webbläsarens grundstorlek, normalt 16 pixlar. Den som behöver
större text ändrar den inställningen i sin webbläsare – och då ska din sajt växa
med.
/* Gör inte så här. */
html { font-size: 12px; }
Den raden låser fast grundstorleken och slår ut besökarens egen inställning. Låt
html vara.
vw ensam är nästan alltid fel
/* Ser bra ut i ett fönster. Oläsbart i ett annat. */
h1 { font-size: 5vw; }
5vw är fem procent av fönsterbredden. På en telefon blir det 19
pixlar, på en bred skärm 96. Det finns ingen undre eller övre gräns.
clamp() är svaret
--text-jatte: clamp(1.9rem, 1.2rem + 2.4vw, 2.8rem);
Det är rubrikstorleken i förlagan, och clamp() tar tre värden: minst,
önskat, högst. Rubriken blir aldrig mindre än 1.9rem och aldrig större
än 2.8rem, och däremellan växer den mjukt med fönstret.
Det där är en brytpunkt du slipper skriva. Utan clamp() hade du
behövt en media query för att byta rubrikstorlek, och den hade hoppat i stället
för att glida.
Prova själv
Leta upp tre px-värden i din stilmall och byt dem mot
rem. Sätt sedan clamp() på din h1 och dra
fönstret långsamt. Ser du var den slutar växa?
3. Media queries
En media query frågar webbläsaren om något och lägger till regler när svaret är ja.
@media (min-width: 40rem) {
/* Gäller från 40rem och uppåt. */
}
Brytpunkter kommer ur innehållet
Det här är avsnittets enda riktigt viktiga mening: brytpunkten ligger där ditt innehåll slutar fungera, inte där någon telefon råkar vara bredd.
Listor på "vanliga brytpunkter" finns överallt och de är nästan alltid fel. Skärmar kommer i alla storlekar, och din layout vet ingenting om vilken modell den visas på. Den vet däremot när menyn blir trång, när textraderna blir för långa, eller när det finns plats för en spalt till.
Så här hittar du dem: dra fönstret långsamt från smalt till brett. Där något blir
fult sätter du en brytpunkt. Skriv sedan ner i din README.md vad det
var som blev fult. Kan du inte formulera det har du förmodligen inte behövt
brytpunkten.
Måtten i rem, inte px
Sätter du brytpunkten i rem flyttar den sig när besökaren zoomar upp
texten. Det är precis vad du vill: den som läser med större text får
desktoplayouten senare, eftersom texten tar mer plats.
Hela förlagans uppsättning
Vikstadssajten har tre media queries. Tre, för hela sajten.
/* 26rem – de smalaste telefonerna. Padding satt för läsbarhet äter
en sjättedel av en 320 px-skärm. */
@media (max-width: 26rem) {
main { padding-left: 1.5rem; padding-right: 1.5rem; }
}
/* 40rem – när namnet och menyn får plats bredvid varandra.
flex-wrap kan radbryta, men den kan inte byta riktning. */
@media (min-width: 40rem) {
body > header {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: space-between;
}
}
/* 55rem – när det finns plats för en sidospalt.
Grid kan inte veta när det finns plats. Det måste du säga. */
@media (min-width: 55rem) {
main.medsidospalt {
display: grid;
grid-template-columns: minmax(0, 1fr) 14rem;
column-gap: 3.5rem;
align-items: start;
}
}
Lägg märke till vad som inte står där. Menyn radbryter med
flex-wrap. Kortrutnätet väljer antal kolumner med
repeat(auto-fit, minmax(16rem, 1fr)). Rubriken växer med
clamp(). Bilderna skalar med max-width: 100%. Ingen av
dem behövde en brytpunkt.
När automatiken räcker – och när den inte gör det
| Situation | Behöver brytpunkt? | Varför |
|---|---|---|
| Meny som ska radbryta | Nej | flex-wrap: wrap |
| Kort som ska bli färre kolumner | Nej | repeat(auto-fit, minmax(...)) |
| Rubrik som ska växa | Nej | clamp() |
| Bild som ska krympa | Nej | max-width: 100% |
| Byta från kolumn till rad | Ja | Flex kan inte byta riktning själv |
| Lägga till en sidospalt | Ja | Grid vet inte när det finns plats |
| Ändra avstånd på små skärmar | Ja | Ingen automatik känner till läsbarhet |
Testa brytpunkterna
Device mode. F12 och sedan telefonikonen uppe till vänster i DevTools, eller Ctrl + Shift + M. Du får en linjal längst upp – dra i den och se var din layout ändrar sig. Det är det snabbaste sättet att hitta brytpunkter.
Riktig telefon. Device mode simulerar bredden. Den simulerar inte fingrar, verklig upplösning, långsam uppkoppling eller att du håller telefonen i solen. Publicera med GitHub Pages och öppna adressen i din egen telefon minst en gång. Det är ett bör-krav i Projekt 3, och det brukar hitta något.
Prova själv
Dra fönstret från smalt till brett och skriv ner varje bredd där något ser fel ut. Sätt en brytpunkt på den första. Skriv en mening om varför den ligger där.
4. Wireframen: vad och varför
En wireframe är en skiss av sidan som visar var innehållet ligger och hur viktigt det är – inget annat. Inga färger, inga typsnitt, inga bilder. Grå rutor med etiketter.
Varför inte bara börja koda
För att du då fattar layoutbeslut medan du samtidigt slåss med CSS. Två svåra saker på en gång. Wireframen skiljer dem åt: först bestämmer du vad som ska ligga var, sedan bygger du det.
Det märks tydligast när desktopvyn ska göras. Den som ritat vet vart blocken ska ta vägen. Den som inte ritat upptäcker mitt i att strukturen inte bär.
Två ramar, samma innehåll
Du ritar din sida i två bredder: mobil 375 px och desktop 1280 px.
Samma innehåll i båda. Blocken flyttas, de tillkommer inte och de försvinner inte. Har du en meny, en rubrik, en ingress och fyra avsnitt på mobilen ska exakt de sakerna finnas i desktopramen – omflyttade.
Bryter du regeln har du ritat två olika sajter, och då kan du inte bygga båda ur samma HTML.
Gråskala med flit
Färg drar uppmärksamheten till fel fråga. Wireframen ska svara på "vad är viktigast här och vad kommer först", inte "vilken grön ska rubriken ha". Formen gjorde du i Projekt 2.
Prova själv
Ta en sida du redan har. Rita den som block på ett papper, i mobilbredd, på fem minuter. Bara rektanglar med namn i. Rita sedan samma sida i desktopbredd bredvid.
5. Figma-grunder
Figma är ett ritverktyg som körs i webbläsaren. Du behöver fyra saker ur det.
Ramar
En ram (frame) är en yta med en bestämd storlek – din skärm. Du ritar en ram på 375 px bredd för mobilen och en på 1280 px för desktop, och sedan ritar du inuti dem. Ramar kan ligga inuti ramar: ett kort inuti en sida är också en ram.
Komponenter
En komponent är ett element du gjort en gång och återanvänder. Din meny, din knapp, ditt kort. Ändrar du originalet ändras alla kopior.
Det är samma tanke som en CSS-klass, och det är därför komponenter är värda besväret: det du gör till komponent i Figma blir oftast en klass i din stilmall.
Autolayout
Autolayout låter en ram sköta avstånden mellan sina barn i stället för att du placerar dem för hand. Du säger "på rad, 16 px mellan" och innehållet ordnar sig. Det är Flexbox. Samma egenskaper, andra namn:
| Figma | CSS |
|---|---|
| Autolayout, horisontell | display: flex; flex-direction: row |
| Autolayout, vertikal | display: flex; flex-direction: column |
| Spacing between items | gap |
| Padding | padding |
| Alignment | justify-content och align-items |
Ritar du med autolayout blir översättningen till kod nästan mekanisk.
Anteckningsytan
Bredvid ramarna skriver du var brytpunkten ligger och varför. Det är den texten som kopplar ihop skissen med avsnitt 3, och den efterfrågas i Projekt 3.
Prova själv
Duplicera mallen från itslearning. Rita mobilramen med autolayout: header, meny, rubrik, ingress, tre innehållsblock, footer. Gör menyn till en komponent.
6. Från wireframe till kod
Ordningen
- Skriv HTML:en efter mobilramen, uppifrån och ner. Ett block i skissen
blir ett element. En ruta märkt "meny" blir
<nav>, en märkt "innehåll" blir<main>. - Stila för mobil. Grundreglerna, utan media queries.
- Dra fönstret bredare tills något blir fult. Där sätter du din brytpunkt.
- Skriv media queryn så att layouten blir desktopramen.
Lägg märke till att HTML:en skrivs en gång. Desktopvyn är samma dokument med andra regler, inte ett nytt dokument.
Blocken blir element
| I skissen | I koden |
|---|---|
| Toppen med namn och meny | <header> med <nav> |
| Sidans innehåll | <main> |
| Ett avsnitt med rubrik | <section> med <h2> |
| Ett kort i ett rutnät | <article> |
| Innehållsförteckning | <nav> med <ul> |
| Botten | <footer> |
Det här är semantiken från område 2. Wireframen gör den lättare, eftersom du redan bestämt vad varje ruta är innan du väljer element.
Ordningen i filen är inte layouten
Det här är avsnittets viktigaste sak, och den kommer tillbaka i avsnitt 11.
I förlagan ligger innehållsförteckningen i HTML:en mellan ingressen och första avsnittet. På en telefon står den där – man läser den på vägen ner. På en bred skärm flyttas den visuellt till en egen spalt:
@media (min-width: 55rem) {
main.medsidospalt > .pasidan {
grid-column: 2;
grid-row: 1;
}
}
Bara var rutan hamnar ändras. Det spelar roll, för tangentbordet och skärmläsaren följer filen, inte layouten. Flyttar du ett block visuellt förbi något annat får du en sida som hoppar när man tabbar – och det är ett fel som ingen ser förrän någon provar.
Prova själv
Ta din mobilram och skriv HTML:en efter den, uppifrån och ner, utan att öppna stilmallen. Öppna sedan sidan. Den ska vara ful men fullständig.
7. Hierarki och läsmönster
UX är frågan om sajten går att förstå utan att man anstränger sig. Det mesta av det är inte kod – det är ordning.
Ögat läser i mönster
Besökare läser inte sidor. De skannar dem, och de gör det i förutsägbara banor: uppifrån och ner, vänster till höger, med extra tid på det som sticker ut. Det första och det största får uppmärksamhet. Det i mitten av ett stycke får det inte.
Praktiskt: det viktigaste ska ligga högst upp och se viktigast ut. Om din sida handlar om öppettider ska öppettiderna inte ligga i tredje stycket.
Hierarki med tre verktyg
| Verktyg | Hur du säger "det här är viktigare" |
|---|---|
| Storlek | Rubriker större än brödtext |
| Position | Högre upp, längre till vänster |
| Kontrast | Mörkare mot ljus bakgrund |
Du behöver sällan mer än två nivåer skillnad. Är allt framhävt är ingenting framhävt.
Rubriknivåer är innehållsförteckningen
En h1 per sida som säger vad sidan handlar om. h2 för
sidans delar. h3 för delar av delarna. Hoppa aldrig från
h2 till h4 för att h4 råkar ha lagom
storlek – storleken sätter du i CSS.
Det här är både UX och tillgänglighet: skärmläsare kan lista sidans rubriker, och den listan är din innehållsförteckning. Är den trasig är sidan svår att navigera.
Läsmått
En textrad som är för lång är svår att läsa, eftersom ögat tappar bort vilken rad det ska tillbaka till. Runt 60–75 tecken är bekvämt.
p { max-width: 34rem; }
Det är därför förlagan har en maxbredd på brödtexten fast main är
bredare.
Prova själv
Öppna din startsida och fråga: vad ser jag först? Är det det viktigaste? Om inte, flytta eller förstärk.
8. Klickbarhet och feedback
Det klickbara ska se klickbart ut
Länkar ska se ut som länkar. Understruket eller tydligt avvikande färg – helst båda, eftersom den som inte skiljer färger behöver något mer än färgen. Knappar ska se ut som knappar: en yta med kant eller bakgrund, inte bara text.
Det omvända gäller också: det som inte är klickbart ska inte se klickbart ut. En understruken rubrik får folk att klicka och bli besvikna.
Klickytan är större än texten
Ett finger är ungefär 10 millimeter brett. En muspekare är en pixel. Riktmärket är minst 44 × 44 pixlar för allt som ska tryckas på.
.huvudmeny a {
min-height: 44px;
display: flex;
align-items: center;
}
Det är förlagans lösning. Lägg märke till att texten inte växer – bara ytan runt den.
Feedback: sidan ska svara
Varje gång någon gör något ska något hända, direkt.
| Tillstånd | Vad besökaren får veta |
|---|---|
:hover | Det här går att klicka på |
:focus-visible | Tangentbordet är här nu |
:active | Klicket registrerades |
aria-current="page" | Du är på den här sidan |
Förlagan använder alla fyra. Den sista är värd att titta på:
.huvudmeny a[aria-current="page"] {
color: var(--accent-djup);
border-bottom-color: var(--accent);
}
Attributet står i HTML:en och säger vilken sida vi är på. CSS:en låter formen följa innebörden i stället för att lägga till en klass som säger samma sak en gång till.
Prova själv
Hovra över varje klickbar sak på din sajt. Svarar de alla? Tabba sedan igenom sidan. Ser du var du är, hela vägen?
9. Formulär och konventioner
Formulär-UX i fem punkter
- Varje fält har en synlig
label. Platshållartext räknas inte – den försvinner när man börjar skriva, precis när man behöver den. - Säg vad som förväntas innan felet uppstår. "Format: 070-123 45 67" bredvid fältet slår ett rött felmeddelande efteråt.
- Fråga inte om sådant du inte behöver. Varje fält kostar besökaren tid och dig ifyllningar.
- Gruppera det som hör ihop med
fieldsetochlegend. - Använd rätt
type.type="email"ger tangentbord med snabel-a på telefonen.type="tel"ger sifferknappsatsen.
Konventioner du inte bör bryta
Besökaren har varit på tusen sajter före din. De förväntningarna är gratis att uppfylla och dyra att bryta.
| Konvention | Vad som händer om du bryter den |
|---|---|
| Logotypen leder till startsidan | Folk klickar och kommer ingenstans |
| Menyn ligger högst upp | Folk letar |
| Aktuell sida är markerad i menyn | Folk vet inte var de är |
| Länkar är understrukna eller tydligt färgade | Folk hittar dem inte |
| Formulärets knapp ligger sist | Folk skickar för tidigt eller inte alls |
| Kontaktuppgifter finns i footern | Folk letar överallt annars |
Att bryta en konvention kan vara rätt, men det ska vara ett beslut du kan motivera, inte något som råkade bli så.
Prova själv
Be någon som inte sett din sajt hitta en sak på den – öppettiderna, kontaktformuläret. Titta på var de letar innan de hittar. Det är den billigaste användbarhetstesten som finns.
10. Tillgänglighet i praktiken
Tillgänglighet betyder att sajten fungerar också för den som inte ser skärmen, inte kan använda mus, eller inte uppfattar färgskillnader. Det är ett krav i lag för offentliga sajter, och det är hantverk för alla andra.
WCAG är regelverket. Det är stort, men det mesta du behöver ryms i det här avsnittet och nästa.
Semantiken gör grovjobbet
Det här är den goda nyheten: gjorde du område 2 ordentligt är du redan halvvägs.
| Det du redan gör | Vad det ger |
|---|---|
header, nav, main, footer | Landmärken att hoppa mellan |
En h1 per sida, inga hopp i nivåerna | En innehållsförteckning som går att navigera |
alt på bilderna | Bilderna beskrivs för den som inte ser dem |
label kopplad med for | Fälten går att förstå och träffa |
<a> för länkar, <button> för knappar | Fokuserbara av sig själva, fungerar med tangentbord |
Den sista raden är värd att stanna vid. En <div onclick> går
inte att nå med tangentbordet. En <button> gör det, utan att du
gör något.
alt-texten
alt beskriver vad bilden visar, inte vad den heter.
<img src="bilder/karta.svg"
alt="Karta över reservatet. Parkeringen ligger i sydväst, och därifrån går
tre markerade stigar norrut mot mossen och österut längs stranden.">
Är bilden ren dekoration som inte tillför något: alt="". Tomt, inte
borttaget. Då hoppar skärmläsaren över den i stället för att läsa upp filnamnet.
Hopplänken
Den som tabbar sig in på en sida måste annars igenom hela menyn, på varje sida. Hopplänken låter dem hoppa direkt till innehållet:
<a class="hoppa" href="#innehall">Hoppa till innehållet</a>
Den ligger först i body och pekar på
<main id="innehall">. I CSS:en göms den ovanför skärmkanten och
kommer fram när den får fokus:
.hoppa {
position: absolute;
top: -4rem;
}
.hoppa:focus {
top: 0;
}
Då försvinner den ur tabbordningen och gör ingen nytta alls.
Prova själv
Öppna en av dina sidor och stäng av bilderna i webbläsaren, eller läs bara dina
alt-texter i tur och ordning. Förstår du vad sidan visar?
11. Tangentbord, kontrast och fokus
Tangentbordstestet
Det tar två minuter och hittar mer än något verktyg.
- Klicka högst upp på sidan, i adressfältet.
- Tryck Tab upprepade gånger.
- Följ med blicken.
Tre saker ska stämma:
- Du ska se var du är. Försvinner markeringen har någon skrivit
outline: none. - Ordningen ska följa läsordningen. Hoppar fokus fram och tillbaka har layouten flyttat något förbi något annat.
- Du ska nå allt klickbart. Hoppas något över är det troligen en
divsom borde varit enbutton.
Fokusmarkeringen
a:focus-visible,
button:focus-visible,
input:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
}
:focus-visible skiljer på tangentbord och mus. Musanvändaren behöver
ingen ram runt länken hen just klickade på; tangentbordsanvändaren behöver den
absolut. Använder du :focus får båda den, och då blir frestelsen att ta
bort den igen.
Ta aldrig bort en fokusmarkering utan att sätta en egen i stället.
Kontrast
Kontrast är förhållandet mellan textens ljushet och bakgrundens. Kraven:
| Vad | Krav |
|---|---|
| Brödtext | 4,5:1 |
| Stor text (från ungefär 24px, eller 19px fet) | 3:1 |
| Gränser på fält och knappar | 3:1 |
Gissa inte. Ljusgrå text på vit bakgrund ser stilren ut på din skärm i ett välbelyst rum, och blir omöjlig på en telefon i solljus.
Verktyg: WAVE visar kontrastfel direkt, och DevTools visar kontrastvärdet när du hovrar över en färg i stilpanelen.
Rörelse
@media (prefers-reduced-motion: reduce) {
* {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
}
}
Har du animationer ska den som slagit på "minska rörelse" i sitt system slippa dem.
Lägg märke till att den här media queryn frågar om användaren, inte om
skärmen – precis som prefers-color-scheme från område 3.
Prova själv
Tangentbordstesta alla dina sidor. Skriv ner varje ställe där du tappar bort fokus.
12. WAVE och Lighthouse steg för steg
Två verktyg som hittar det du missat. De ersätter inte tangentbordstestet – de hittar andra saker.
WAVE
WAVE är ett tillägg som lägger ikoner ovanpå din sida och pekar på problemen.
- Installera WAVE Evaluation Tool i Chrome eller Firefox.
- Öppna din publicerade sida. WAVE behöver en adress, inte en lokal fil.
- Klicka på WAVE-ikonen.
- Läs vänsterpanelen.
Panelen delar fynden i grupper, och de väger olika:
| Grupp | Betyder | Vad du gör |
|---|---|---|
| Errors (röda) | Verkliga fel | Rätta alla. Bör-krav i Projekt 3 |
| Contrast Errors | Text som inte når 4,5:1 | Rätta alla |
| Alerts (gula) | Kanske fel, kanske inte | Läs varje, förklara de du lämnar |
| Features (gröna) | Sådant du gjort rätt | Kontrollera att de sitter där du tror |
| Structural | Rubriker och landmärken | Kontrollera att strukturen stämmer |
De vanligaste felen och vad de betyder
| WAVE säger | Vad som är fel | Fix |
|---|---|---|
| Missing alternative text | En img saknar alt | Beskriv bilden, eller alt="" om den är dekoration |
| Empty link | Länken innehåller ingen text | En bild utan alt inuti en länk. Ge bilden alt |
| Missing form label | Fält utan label | for och id ska vara exakt samma sträng |
| Very low contrast | Under 4,5:1 | Mörkare text eller ljusare bakgrund |
| Missing first level heading | Ingen h1 | En per sida |
| Skipped heading level | h2 följt av h4 | Nivå, inte storlek |
| Redundant link | Två länkar bredvid varandra till samma mål | Slå ihop dem |
Före och efter
Projekt 3 kräver en WAVE-rapport före och en efter, som skärmbilder i din
README.md.
"Före" är första körningen på din sajt, innan du rättat något. Kör den tidigt – det är mycket lättare att visa vad du gjort om du har utgångsläget sparat. "Efter" är när du är klar.
Lighthouse
Lighthouse ligger inbyggt i Chrome DevTools och ger poäng i fyra kategorier.
- F12, fliken Lighthouse.
- Kryssa i minst Accessibility. Performance är intressant men hör till område 7.
- Välj Mobile.
- Analyze page load.
Du får en siffra och en lista. Siffran är inte målet – listan är. Ett fel som Lighthouse inte kan mäta finns fortfarande.
Varken WAVE eller Lighthouse kan avgöra om din alt-text är bra. De
ser att den finns. Att den beskriver rätt sak kan bara du kontrollera.
Prova själv
Kör WAVE på din startsida nu, innan du rättat något. Spara skärmbilden. Det är din "före"-mätning, och den blir bara svårare att ta senare.
13. Ta det längre
Fördjupning mot C och A. Inget här krävs för E.
Rutnät helt utan brytpunkter
.kortrutnat {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1.5rem;
}
auto-fit fyller på så många kolumner som får plats,
minmax säger att ingen får bli smalare än 16rem. Rutnätet
väljer själv: fyra kolumner på en bred skärm, en på en telefon, utan att du skriver
en enda @media.
Kan du förklara varför det här ibland är bättre än en brytpunkt, är du på A-nivå i matrisens rad om responsiv layout.
minmax(0, 1fr) och tabeller som spränger sidan
body {
display: grid;
grid-template-columns: minmax(0, 1fr);
}
Ett grid-item har min-width: auto – "bli aldrig smalare än ditt
innehåll". Ett brett barn, som en tabell, drar då spåret bredare än skärmen och
hela sidan börjar scrolla i sidled. minmax(0, ...) säger att spåret
får bli hur smalt som helst.
Det är den vanligaste orsaken till vågrät rullning som inte går att hitta.
Svepet
.tabellsvep {
overflow-x: auto;
}
Fem kolumner text får inte plats på en telefon, och ingen befintlig struktur kan
bära den scrollningen. Ett extra element runt tabellen är rätt svar – och det är
också exemplet på när en ny div är motiverad enligt Projekt 3:s
regel.
Fokusordning i två layouter
Har du flyttat block mellan mobil och desktop: tangentbordstesta båda bredderna. Fokusordningen följer filen, och en layout som ser logisk ut kan ha en tabbordning som inte gör det.
prefers-color-scheme
Mörkt läge från område 3 hör hit också. Det är samma familj som
prefers-reduced-motion: media queries som frågar om användarens
inställningar i stället för om skärmens mått.
14. Felsökning
22 rader
| Symptom | Trolig orsak | Åtgärd |
|---|---|---|
| Sidan är utzoomad i telefonen | Viewport-taggen saknas | <meta name="viewport" …> i head, på varje sida |
| Det går att dra sidan i sidled | Något element är bredare än skärmen | Leta fasta px-bredder i DevTools, ett element i taget |
| Vågrät rullning som inte går att hitta | Ett grid-item vägrar krympa | minmax(0, 1fr) i stället för 1fr |
100vw ger vågrät rullning | vw räknar med rullningslisten | 100% för bredder inuti sidan |
| Bilden spränger sidan | Ingen maxbredd | img { max-width: 100%; height: auto; } |
@media-regeln gör ingenting | Den står före regeln den ska åsidosätta | Media queries sist i filen |
@media-regeln gäller alltid | min-width och max-width förväxlade | min-width = från den bredden och uppåt |
| Layouten hoppar vid en bredd | Brytpunkten ligger där innehållet inte behöver den | Dra fönstret långsamt, flytta dit det faktiskt blir trångt |
| Bra i device mode, trasigt i telefonen | Device mode simulerar bara bredden | Publicera och öppna på riktig telefon |
| Texten blir jättestor på bred skärm | vw utan gränser | clamp(minst, önskat, högst) |
rem ger fel storlek överallt | font-size är satt på html | Låt html vara |
| Menyn radbryter till oläslighet | gap saknas, eller ingen brytpunkt | gap på behållaren, kolumn under brytpunkten |
| Svårt att träffa länkarna med fingret | Klickytan är bara texten | min-height: 44px och padding på länken |
| Fokusmarkeringen syns inte | outline: none utan ersättning | :focus-visible med egen outline |
| Tab hoppar i konstig ordning | Filens ordning skiljer sig från den visuella | Flytta i HTML:en, inte med tabindex |
| Något klickbart går inte att tabba till | Det är en div, inte en a eller button | Byt element |
| WAVE: Empty link | Bild utan alt inuti en länk | Ge bilden alt som säger vart länken går |
| WAVE: Missing form label | for matchar inte id | Exakt samma sträng, versaler räknas |
| WAVE: Skipped heading level | Rubriknivå vald efter storlek | Nivå i HTML, storlek i CSS |
| WAVE hittar fel jag inte ser | De flesta tillgänglighetsfel är osynliga | Det är hela poängen. Rätta felet, inte mätningen |
| WAVE vill inte köra | Sidan ligger lokalt | WAVE behöver en publicerad adress |
| Lighthouse ger låg poäng på allt | Performance mäts också | Kryssa i bara Accessibility i det här området |
15. Snabbreferens
Viewport
<meta name="viewport" content="width=device-width, initial-scale=1">
Media queries
@media (min-width: 40rem) { } /* från 40rem och uppåt */
@media (max-width: 26rem) { } /* till och med 26rem */
@media (prefers-reduced-motion: reduce) { }
@media (prefers-color-scheme: dark) { }
Enheter
| Enhet | Utgår från |
|---|---|
rem | Webbläsarens grundstorlek |
% | Föräldern |
fr | Det som blir över i ett grid |
vw / vh | Fönstrets bredd / höjd |
ch | Bredden på en nolla |
Skalar utan brytpunkt
| Vad | Hur |
|---|---|
| Text | clamp(minst, önskat, högst) |
| Rutnät | repeat(auto-fit, minmax(16rem, 1fr)) |
| Rad som radbryter | flex-wrap: wrap |
| Bild | max-width: 100%; height: auto |
| Grid-spår som får krympa | minmax(0, 1fr) |
Tillgänglighet
| Krav | Mått |
|---|---|
| Kontrast, brödtext | 4,5:1 |
| Kontrast, stor text | 3:1 |
| Klickyta | 44 × 44 px |
| Rubriker | En h1, inga hopp |
Tangentbordstestet
Tab genom sidan. Ser du fokus? Följer ordningen läsordningen? Når du allt?
16. Ordlista
Klicka på en rad för att visa betydelsen, eller träna på orden med knapparna nedan.
Ordträning
| Ord | Betyder |
|---|---|
| viewport | Den yta i webbläsaren där sidan visas |
| mobile first | Grundreglerna gäller smal skärm, media queries lägger till för breda |
| brytpunkt | Bredden där en media query börjar gälla |
| media query | Regel som gäller när ett villkor är uppfyllt |
| relativ enhet | Mått som utgår från något annat: rem, %, fr, vw |
| clamp() | Tre värden: minst, önskat, högst. Skalar mjukt mellan gränserna |
| device mode | DevTools-läge som visar sidan i en vald skärmbredd |
| wireframe | Skiss som visar var innehållet ligger, utan färg och form |
| ram (frame) | Ytan du ritar i i Figma – en skärm |
| komponent | Element du gjort en gång och återanvänder. Figmas motsvarighet till en klass |
| autolayout | Figmas sätt att sköta avstånd automatiskt. Samma tanke som Flexbox |
| hierarki | Vad som ser viktigast ut, och därmed läses först |
| läsmått | Hur långa textraderna är. Runt 60–75 tecken är bekvämt |
| konvention | Sådant besökaren redan förväntar sig, från andra sajter |
| feedback | Att sidan svarar när någon gör något |
| WCAG | Regelverket för webbtillgänglighet |
| landmärke | Semantiskt område man kan hoppa mellan: header, nav, main, footer |
| hopplänk | Länk först på sidan som hoppar förbi menyn, syns bara vid fokus |
| kontrast | Förhållandet mellan textens och bakgrundens ljushet |
| fokusmarkering | Ramen som visar var tangentbordet är |
| :focus-visible | Fokusmarkering för tangentbord men inte för mus |
| tabbordning | Ordningen Tab går i. Följer filen, inte layouten |
| WAVE | Tillägg som visar tillgänglighetsfel ovanpå sidan |
| Lighthouse | Verktyg i DevTools som ger poäng och en åtgärdslista |
| skärmläsare | Program som läser upp sidan för den som inte ser den |