Varje egenskap från guiden med vad den är, vad den gör, vad som
följer med av sig själv – och samma exempel med och utan den, så att du ser
skillnaden i stället för att läsa om den.
Prov 2 är måndag 9 november. Det är skriftligt och utan dator, och det täcker
fem saker: selektorer och specificitet, boxmodellen, Flexbox, Grid och
CSS-variabler. Färg och typografi är med här också, eftersom de finns i all
kod du kommer att läsa på provet.
Så använder du sidan
Läs en post, titta på rutorna och försök säga med egna ord vad som skiljer dem
åt innan du läser förklaringen. Varje avsnitt slutar med Testa dig
själv: svara i huvudet först, klicka sedan på raden för att se svaret.
Rutorna är riktig CSS som körs i din webbläsare. Koden under varje ruta är
precis det som skiljer dem åt.
1. Selektorer och specificitet
Selektorn är det som står före klammern. Den säger vad regeln träffar.
Specificiteten avgör vilken regel som vinner när två träffar samma element.
Element, klass och id
Tre sätt att peka ut element: på taggnamn, på
class eller på id.
p träffar alla stycken. .ingress träffar bara element
med class="ingress". #faglar träffar det enda elementet
med id="faglar".
Att veta: punkt betyder klass, brädgård betyder id. Ett
element kan ha flera klasser, class="kort viktig", men bara ett id.
Elementselektor
Ingressen.
Brödtext ett.
Brödtext två.
p { color: #2f6f5e; }
Klassselektor
Ingressen.
Brödtext ett.
Brödtext två.
.ingress {
color: #2f6f5e;
font-weight: 700;
}
Vanligt misstag: att formge med #id. Den är så
specifik att den blir svår att skriva över, och den är förbjuden för formgivning i
Projekt 2. Använd klasser.
Två sätt att kombinera selektorer: någonstans inuti och
direkt barn.
.artikel p träffar varje p som ligger inuti
.artikel, hur djupt som helst. .artikel > p träffar
bara de p som ligger direkt i .artikel, inte de som
ligger i ett element längre in.
Att veta: komma är något helt annat. h1, h2
betyder "både h1 och h2" – två selektorer som delar samma regel.
Väljer element utifrån ett attribut de redan har i HTML:en.
a[aria-current="page"] träffar länken till sidan man står på. Ingen
extra klass behövs – attributet säger redan "du är här", och formen kan följa
innebörden.
Vanligt misstag: att glömma citattecknen eller skriva
mellanslag före hakparentesen. a [aria-current] betyder "något med
attributet inuti en länk" – inte samma sak.
:hover och :focus-visible
Pseudoklasser som väljer på tillstånd: muspekaren är över,
respektive elementet har fått fokus med tangentbordet.
För musen över länkarna nedan. Klicka sedan i rutan och tryck Tab tills
du når länken i den högra rutan.
Att veta: en pseudoklass skrivs med ett kolon direkt efter
selektorn, utan mellanslag. Den räknas som en klass i specificiteten.
Vanligt misstag:.lank :hover med mellanslag.
Då betyder den "något inuti länken som muspekaren är över".
:nth-child(even)
Väljer element efter deras plats bland syskonen.
even är jämna – andra, fjärde, sjätte. odd är udda. Det
används mest för att tona varannan rad i en tabell eller lista, utan att märka en
enda rad i HTML:en.
Utan
Måndag
Tisdag
Onsdag
Torsdag
Fredag
/* ingen regel */
Med
Måndag
Tisdag
Onsdag
Torsdag
Fredag
li:nth-child(even) {
background: #e7f0ec;
}
Fler i samma familj::first-child,
:last-child, :nth-child(3) för just det tredje.
Specificitet: vilken regel vinner?
När två regler säger olika saker om samma element vinner den mest
specifika – oavsett vilken som står sist.
Specificitet räknas som tre siffror: id – klass – element. Jämför från
vänster. En klass slår hur många element som helst.
Selektor
Räknas som
p
0-0-1
.kort p
0-1-1
.ingress
0-1-0
a:hover
0-1-1 – pseudoklassen räknas som klass
a[aria-current="page"]
0-1-1 – attributet räknas som klass
#faglar
1-0-0
I rutan till höger står klassregeln först och elementregeln sist. Klassen
vinner ändå.
Vanligt misstag: att lösa krocken med
!important. Den hoppar över hela räkningen, och det enda som slår den
är en till. Sänk den andra selektorns specificitet i stället.
Är selektorerna lika specifika avgör ordningen i filen.
Samma två regler i båda rutorna, i omvänd ordning. Det är därför man skriver
stilmallen från allmänt till särskilt: det som står längre ned ska få bestämma.
Vanligt misstag: att tro att formulärfält ärver typsnittet.
Det gör de inte – därför font: inherit på input,
select och textarea.
Testa dig själv
Fråga
Svar
Vilken specificitet har .meny a?
0-1-1
Vilken vinner: .kort p eller p.ingress?
Lika, båda 0-1-1. Den som står sist vinner
Vilken vinner: #faglar eller .kort .ingress?
#faglar. 1-0-0 slår 0-2-0
Vad är skillnaden mellan nav a och nav > a?
Den första träffar länkar var som helst i nav, den andra bara direkta barn
Vad träffar h2, h3?
Alla h2 och alla h3
Du sätter background på body. Ärvs den?
Nej. Barnen är genomskinliga, så den syns igenom – men den ärvs inte
Vilka rader träffar tr:nth-child(odd)?
Första, tredje, femte …
2. Boxmodellen
Varje element är en låda med fyra lager, inifrån och ut: content (innehållet),
padding (luft innanför kanten), border (kanten) och margin
(luft utanför).
box-sizing: border-box
Bestämmer vad width mäter.
Webbläsarens förval är content-box: bredden gäller bara innehållet,
och padding och border läggs utanpå. Med border-box räknas de inåt,
så att 12rem blir 12rem. Den bruna linjen i båda rutorna är 12rem lång.
Följer med: ingenting – men utan den regeln gäller
content-box för alla element. Skriv den överst i varje stilmall.
Uppe, höger, nere, vänster – medurs från klockan tolv
border
Kanten runt lådan.
Kortformen tar tre värden: tjocklek, stil och färg. Ordningen spelar ingen
roll, men stilen måste finnas med.
Följer med: utan stil blir stilen none – och då
syns ingen kant alls, hur tjock du än gör den.
Stilen saknas
Var är kanten?
.ruta { border: 3px #2f6f5e; }
Med stil
Där är den.
.ruta { border: 3px solid #2f6f5e; }
Vanliga stilar: solid, dashed,
dotted. En sida i taget: border-bottom,
border-left.
Marginalkollaps
Två lodräta marginaler som möts slås ihop till en.
Den första rutan har margin-bottom: 2rem, den andra
margin-top: 1rem. I vanligt flöde blir avståndet 2rem – den
största vinner, de adderas inte. Inuti en flex- eller grid-behållare kollapsar
marginaler inte, och då blir det 3rem.
Att veta: det gäller bara lodrätt. Sidledes marginaler
kollapsar aldrig.
max-width
Den största bredd elementet får ha.
Elementet får vara smalare, men aldrig bredare. Två vanliga användningar:
läsmått på brödtext, så att raderna inte blir för långa, och
max-width: 100% på bilder, så att de inte spränger sin spalt. Den
bruna stapeln står för en bild som är 60rem bred.
Utan
Långa rader är svåra att läsa. Ögat ska hitta tillbaka till början av nästa
rad, och ju längre raden är desto lättare tappar det bort sig.
/* ingen regel */
Med
Långa rader är svåra att läsa. Ögat ska hitta tillbaka till början av nästa
rad, och ju längre raden är desto lättare tappar det bort sig.
p { max-width: 20rem; }
.bild { max-width: 100%; }
Vanligt misstag:width i stället för
max-width. Med width: 20rem blir stycket 20rem även i en
telefon som bara har 18rem att ge.
Testa dig själv
Fråga
Svar
Vilka är boxmodellens fyra lager, inifrån och ut?
content, padding, border, margin
width: 300px; padding: 20px; border: 1px solid; utan border-box. Hur bred blir lådan?
342px – 300 + 2 × 20 + 2 × 1
Samma sak med border-box?
300px
Vad betyder padding: 0.5rem 1rem;?
0.5rem uppe och nere, 1rem höger och vänster
Två stycken: margin-bottom: 1.5rem och margin-top: 1rem. Avstånd?
1.5rem – marginalkollaps, den största vinner
Vilket lager har elementets bakgrundsfärg: padding eller margin?
Padding
Varför syns inte border: 2px red;?
Stilen saknas, till exempel solid
3. Färg
color
Textfärgen.
color ärvs. Sätter du den på en behållare får all text inuti samma
färg, om inget längre in säger något annat.
Utan
Rubrik
Och ett stycke.
/* ingen regel */
Med
Rubrik
Och ett stycke.
.ruta { color: #2f6f5e; }
Vanligt misstag: grå text på vit bakgrund som ser stilren ut
men har för låg kontrast. Riktvärdet är 4,5:1 för brödtext. DevTools visar värdet
när du inspekterar färgen.
background
Bakgrunden bakom innehållet och paddingen.
background ärvs inte. Att stycket inuti ändå ser tonat ut beror
på att det är genomskinligt som förval – rutans bakgrund syns igenom.
Utan
Ett stycke i rutan.
.ruta { padding: 0.6rem; }
Med
Ett stycke i rutan.
.ruta {
padding: 0.6rem;
background: #e7f0ec;
}
background är en kortform. background-color
sätter bara färgen och gör samma sak här.
Färgvärden: hex, rgb och hsl
Fyra sätt att skriva samma sak: namn, hex, rgb och hsl.
Skrivs
Betyder
darkgreen
Ett av 147 färgnamn
#2f6f5e
Hex: två tecken per kanal – rött 2f, grönt 6f, blått 5e. #fff är #ffffff
rgb(47 111 94)
Rött, grönt, blått från 0 till 255
hsl(164 40% 31%)
Nyans, mättnad, ljushet
rgb(47 111 94 / 30%)
Fjärde värdet efter snedstrecket är alfa – genomskinlighet
Att veta: hsl är den enda som går att räkna i huvudet. Byt
bara ljusheten, så får du en skala som hänger ihop.
Testa dig själv
Fråga
Svar
Vad är #000 utskrivet i sex tecken?
#000000 – svart
Vilken av color och background ärvs?
color
Vad gör / 50% i rgb(0 0 0 / 50%)?
Gör färgen halvt genomskinlig
Vilket kontrastvärde är riktvärdet för brödtext?
4,5:1
Vad ändras mellan hsl(164 40% 31%) och hsl(164 40% 60%)?
Bara ljusheten. Samma färg, ljusare
4. Typografi
font-family
Vilket typsnitt texten ska ha.
Värdet är en stack: en lista i fallande ordning. Webbläsaren tar det första
som finns på datorn. Sist står alltid en generisk familj –
sans-serif, serif eller monospace – så att
det finns något att falla tillbaka på.
Följer med: utan regel använder de flesta webbläsare ett
serift typsnitt, oftast Times. font-family ärvs, så det räcker att
sätta den på body.
Utan – förvalet
Vikstads naturreservat har fyra markerade stigar.
/* ingen regel */
Med
Vikstads naturreservat har fyra markerade stigar.
body {
font-family: "Segoe UI",
system-ui, -apple-system,
sans-serif;
}
Vanligt misstag: att glömma citattecknen runt namn med
mellanslag, eller att inte avsluta med en generisk familj.
font-size med rem och em
Textstorleken.
rem betyder gånger sidans grundstorlek, normalt 16 pixlar.
em betyder gånger förälderns storlek – och därför växer den
ihop när element ligger i varandra. Båda rutorna har tre nivåer inuti varandra
med klassen steg.
em – växer ihop
Nivå 1
Nivå 2
Nivå 3
.steg { font-size: 1.2em; }
rem – samma hela vägen
Nivå 1
Nivå 2
Nivå 3
.steg { font-size: 1.2rem; }
Varför rem och inte px? Har användaren ställt in större text
i webbläsaren följer rem med. px står still.
Räkna: 1.5rem är 24px, 0.875rem är 14px –
om grundstorleken är 16px.
line-height
Radavståndet.
Skriv den utan enhet. Då betyder 1.6 "1,6 gånger elementets
egen textstorlek", och rubriker och brödtext får var sitt rimliga avstånd.
Riktvärde för brödtext: 1,5–1,7.
Följer med: förvalet normal är ungefär 1,2 –
tätt för brödtext. line-height ärvs.
Utan – normal
Stigarna är markerade med färgade pilar. Den gröna är kortast och den enda som går att ta sig fram på med barnvagn.
/* ingen regel */
Med
Stigarna är markerade med färgade pilar. Den gröna är kortast och den enda som går att ta sig fram på med barnvagn.
p { line-height: 1.6; }
Vanligt misstag:line-height: 24px. Den ärvs som
ett fast värde, och en rubrik på 40px får då 24px radavstånd – raderna krockar.
clamp()
Ett värde som växer med fönstret, mellan ett minsta och ett största.
Tre värden: minsta, önskade, största. Det mittersta innehåller oftast
vw – en hundradel av fönstrets bredd – och det är det som får värdet
att växa. Dra i webbläsarfönstret och se rubriken nedan ändra storlek, men aldrig
under 1,2rem eller över 2,2rem.
Att veta: det är ett sätt att få något att skala utan en
enda media query.
Testa dig själv
Fråga
Svar
Hur många pixlar är 2rem om grundstorleken är 16px?
32px
font-size: 1.5em inuti ett element med 1.5em. Hur många gånger grundstorleken?
2,25 – em växer ihop
Varför ska line-height skrivas utan enhet?
Då räknas den om för varje element utifrån dess egen textstorlek
Vad står de tre värdena i clamp() för?
Minsta, önskade, största
Varför står sans-serif sist i en typsnittsstack?
Så att det finns något att falla tillbaka på om inget av de andra finns
Ärvs font-family?
Ja – utom i formulärfält
5. Flexbox
Flexbox lägger element i en riktning – en rad eller en kolumn – och fördelar
utrymmet mellan dem. Allt utom flex: 1 skrivs på behållaren,
inte på barnen. Den streckade linjen visar var behållaren går.
display: flex
Gör elementet till en flexbehållare. Barnen blir flex-barn.
Barnen slutar ligga under varandra och ställer sig på en rad. De blir bara så breda
som sitt innehåll.
Följer med automatiskt:flex-direction: row
(en rad), flex-wrap: nowrap (ingen radbrytning),
justify-content: flex-start (samlade till vänster) och
align-items: stretch (lika höga). Inget av det behöver du skriva –
bara det du vill ändra.
Utan
Ett
Två
Tre
.rad { }
Med
Ett
Två
Tre
.rad {
display: flex;
gap: 0.4rem;
}
Vanligt misstag: att sätta display: flex på
barnen. Det ska stå på föräldern – den som ska ordna sina barn.
row är förvalet: vågrätt. column lägger dem lodrätt –
men fortfarande som flex-barn, så gap och de andra egenskaperna
fungerar.
Att veta:justify-content och
align-itemsbyter håll med column. De följer
riktningen, inte skärmen.
row – förvalet
Ett
Två
Tre
.rad { display: flex; }
column
Ett
Två
Tre
.rad {
display: flex;
flex-direction: column;
}
justify-content
Hur barnen fördelas längs riktningen.
Det märks bara när det finns utrymme över. space-between lägger det
första barnet längst till vänster, det sista längst till höger och fördelar luften
mellan dem.
flex-start – förvalet
Ett
Två
Tre
.rad { display: flex; }
center
Ett
Två
Tre
justify-content: center;
space-between
Ett
Två
Tre
justify-content: space-between;
Vanligt misstag: att använda justify-content för
att centrera lodrätt i en rad. Lodrätt i en rad är tvärs riktningen – det
är align-items.
align-items
Hur barnen placeras tvärs riktningen.
Det mittersta barnet är högre än de andra. Förvalet stretch drar ut
alla till samma höjd. center låter dem behålla sin höjd och lägger dem
i mitten.
stretch – förvalet
Ett
Hög
Tre
.rad { display: flex; }
center
Ett
Hög
Tre
.rad {
display: flex;
align-items: center;
}
Minnesregel:justify längs, align tvärs. Med
flex-direction: column är längs lodrätt och tvärs vågrätt.
flex-wrap
Om barnen får radbryta när de inte får plats.
Förvalet nowrap pressar ihop barnen på en rad tills de inte går att
krympa mer – sedan sticker de ut ur behållaren. Med wrap flyttar de
ned på en ny rad. Det är så en meny klarar en smal telefonskärm utan media
queries.
Vilken flex-direction får du om du bara skriver display: flex?
row
Ska display: flex stå på menyns ul eller på varje li?
På ul – behållaren
Du vill centrera barnen lodrätt i en rad. Vilken egenskap?
align-items: center
Samma sak, men med flex-direction: column?
justify-content: center – de har bytt håll
Menyn pressas ihop i mobilen. Vilken rad saknas?
flex-wrap: wrap
gap: 1rem gör ingenting. Varför?
Elementet är varken flex eller grid
Vad gör flex: 1 på ett av tre barn?
Det barnet tar allt utrymme som blir över
6. Grid
Grid lägger element i rader och kolumner samtidigt. Tumregeln: en riktning
är Flexbox, två riktningar är Grid.
display: grid
Gör elementet till en grid-behållare.
Ensam gör den nästan ingenting synligt – rutorna nedan ser likadana ut.
Det är grid-template-columns som gör jobbet. Men nu fungerar
gap, och barnen är grid-barn som kan placeras.
Följer med automatiskt:en enda kolumn, så många
rader som behövs, och barn som fyller sin cell på bredden.
Ett värde per kolumn. fr betyder en andel av det som blir
över. 1fr 1fr 1fr är tre lika breda, 2fr 1fr är två
där den första är dubbelt så bred. Barnen fyller cellerna i tur och ordning, rad
för rad.
Blanda gärna:200px 1fr ger en fast kolumn och
en som tar resten.
Vanligt misstag: att tro att 1fr är en bredd. Det
är en andel av det som blir över när de fasta kolumnerna fått sitt.
repeat(auto-fit, minmax(…, 1fr))
Ett rutnät som väljer antal kolumner själv.
Läs den inifrån och ut. minmax(6rem, 1fr): varje kolumn är minst
6rem och högst sin andel av resten. repeat(auto-fit, …): lägg in så
många sådana kolumner som får plats.
Dra i det lilla hörnet nere till höger i varje ruta för att göra den
smalare. Med fasta kolumner trycks korten ihop. Med auto-fit blir det
färre kolumner.
Att veta: i ditt projekt är det här ofta
minmax(16rem, 1fr) – tre kolumner på en laptop, en i en telefon, utan
en enda media query. Hörnet att dra i finns inte på alla telefoner; prova på en
dator.
grid-column: 1 / -1
Skrivs på ett barn: sträck dig över alla kolumner.
Siffrorna är linjer, inte kolumner. 1 är linjen längst till
vänster, -1 är den längst till höger. Rubriken nedan är ett barn till
rutnätet precis som korten.
Vanligt misstag: att linda in korten i en extra
div för att få rubriken på egen rad. Det behövs inte.
grid-template-areas
Layouten ritad i text.
Varje sträng är en rad, varje ord en cell. Samma namn i flera celler bredvid
varandra blir ett område som sträcker sig över dem. Barnen hamnar på plats med
grid-area. Områdets namn och barnets klass är två olika saker –
de behöver inte heta likadant.
Vanligt misstag: olika många ord i raderna, eller ett område
som inte blir en rektangel. Då struntar webbläsaren i hela regeln.
minmax(0, 1fr) och overflow-x: auto
Fällan när något brett ligger i ett rutnät – och vägen ut.
Ett grid-barn blir som förval aldrig smalare än sitt innehåll. Ligger en bred
tabell i en 1fr-kolumn växer kolumnen i stället för att hålla emot, och
hela sidan börjar scrolla i sidled. minmax(0, 1fr) låter kolumnen bli
hur smal som helst, och overflow-x: auto låter innehållet scrolla i sin
egen ruta.
Utan – sticker ut
En bred tabell, 28rem, som inte får plats i rutan.
Rutnätet är 900px brett. Hur breda blir kolumnerna med 2fr 1fr, utan gap?
600px och 300px
Samma rutnät med 300px 1fr?
300px och 600px
Vad betyder minmax(16rem, 1fr)?
Minst 16rem, högst en andel av det som blir över
Rubriken ska gå över alla kolumner. Vilken rad, och på vilket element?
grid-column: 1 / -1 på rubriken
När väljer du Grid framför Flexbox?
När sakerna ska ligga i linje åt två håll – rader och kolumner
Hela sidan scrollar i sidled på grund av en tabell i ett rutnät. Vad gör du?
minmax(0, 1fr) på kolumnen och overflow-x: auto runt tabellen
7. Variabler
En variabel – i CSS kallad egen egenskap – är ett namngivet värde du
definierar en gång och använder på många ställen.
--namn och var(--namn)
Definiera ett värde med två bindestreck, hämta det med
var().
Båda rutorna har exakt samma regler för rubriken och knapparna. Det enda som skiljer
är ett värde i :root – och allt som använder variabeln byter
färg på en gång.
Att veta: variabler ärvs nedåt precis som
color. Därför läggs de på :root, dokumentets rot, och
gäller då på hela sidan.
Variabeln heter --accent, men regeln frågar efter
--accnet. Webbläsaren säger inget – texten får bara den färg den
skulle ha haft utan regeln. Ett reservvärde efter kommatecknet används när
variabeln saknas.
Felstavad
Varför är jag inte grön?
:root { --accent: #2f6f5e; }
p { color: var(--accnet); }
Att veta: namnen är skiftlägeskänsliga.
--Accent och --accent är två olika variabler.
@media (prefers-color-scheme: dark)
Regler som bara gäller när användaren valt mörkt läge.
Ligger färgerna i variabler räcker det att byta värdena. Ingen regel längre
ned i filen behöver skrivas om – de hämtar redan sin färg från variablerna.
Prova: byt till mörkt läge i datorns inställningar. Den här
sidan är byggd på precis det sättet – men rutorna med exemplen behåller sin ljusa
bakgrund med flit, så att färgerna i koden stämmer.
Testa dig själv
Fråga
Svar
Hur många bindestreck inleder ett variabelnamn?
Två: --namn
Hur hämtar du värdet av --yta?
var(--yta)
Varför läggs variablerna på :root?
Den är dokumentets rot, och variabler ärvs nedåt – då gäller de överallt
Vad gör var(--accent, green) om --accent inte finns?
Använder reservvärdet green
Vilket namn är bäst: --bla eller --lank?
--lank – det säger vad värdet är till för
Mörkt läge: vad behöver ändras om allt ligger i variabler?
Bara variablernas värden, i ett @media (prefers-color-scheme: dark)-block
Kvällen före
Läs inte allt igen. Gå igenom Testa dig själv i alla sju avsnitt och läs om
posterna där du svarade fel. Öppna sedan din egen stilmall och förklara varje
regel högt för dig själv – det är så provet frågar.