Publicerad den Lämna en kommentar

EM vs REM vs PX – Varför du inte ”bara ska använda pixlar”

Debatten har förts många gånger – vilka måttenheter ska vi använda i vår CSS?

Vi, liksom många andra, var redo att dumpa REM:s och återgå till den älskade pixeln. Vi tappade bort varför vi överhuvudtaget införde användningen av REMs. Problemet kretsar inte bara kring typsnittsstorlekar – det handlar också om tillgänglighet.

TL;DR:

  • Pixlar är okunniga, använd dem inte.
  • Använd REMs för storlekar och avstånd.
  • Använd EMs för media queries.

Pixlar

Pixlar (px) är vad vi alla har vant oss vid genom åren. Alla vet vad en pixel är (även om storleken på en pixel inte alltid är densamma, men det är en annan dag). Alla är bekväma med att använda pixlar. De är lätta att översätta. Designers arbetar vanligtvis i pixlar, så det är lätt att ta storlekar direkt från Photoshop direkt till build.

Så vad är det för fel på pixlar?

Tillgänglighet

Jag är en stor förespråkare av tillgänglighet på webben. Jag föredrar tillgänglighet framför ”vackert” när som helst.

Om du ställer in alla dina typsnittsstorlekar, elementstorlekar och avstånd i pixlar behandlar du inte slutanvändaren med respekt.

I de flesta webbläsare kan en användare ställa in standardtypsnittsstorleken i webbläsaren till en annan storlek än standardstorleken (vanligtvis 16px). Om användaren ställer in standardstorleken på 20px bör alla typsnittsstorlekar skalas i enlighet med detta.

Och om webbplatsen uttryckligen ställer in typsnittsstorlekar i pixlar kommer en rubrik som är inställd på 30px alltid att vara 30px. Det kan låta bra ur en designers/utvecklares synvinkel – men du är inte användaren, sluta skapa webbplatser för dig själv.

Troligtvis förstör inte inställningen av teckensnittsstorlekar i pixlar tillgängligheten helt och hållet. Användaren kan fortfarande zooma in och ut med ctrl plus +/- (cmd istället för ctrl på OS X). Vi kan dock göra bättre.

REMs

Om du på något sätt är bekant med webbdesignvärlden har du utan tvekan hört talas om REMs. Om du inte är det, är REMs ett sätt att ställa in teckensnittsstorlekar baserat på teckensnittsstorleken för HTML-elementet i roten. De gör det också möjligt att snabbt skala ett helt projekt genom att ändra rotfontstorleken (t.ex. vid en viss mediaquery/skärmstorlek).

” unit representerar rotelementets fontstorlek (t.ex. fontstorleken för <html>elementet). När det används på font-size på detta rotelement representerar det dess ursprungliga värde.”

Hur man beräknar PX från REM

Ett grundläggande och vanligast förekommande exempel: html font-size är satt till 10px, paragraph är satt till 1,6rem – 1,6rem * 10px = 16px.

Att ställa in ett rotfont-size på 10px är det vanligaste scenariot när jag ser att folk använder REMs. Det möjliggör en snabb konvertering mellan pixelvärden till REM-värden helt enkelt genom att dividera talet med 10.

Men om man ställer in grundfontstorleken i pixlar har man fortfarande samma problem som i exemplet med pixlar ovan. Tillgänglighet åsidosätts.

Och även om REMs säkert har sina användningsområden är jag villig att slå vad om att de flesta använder REMs för att de uppfattas som coolare än pixlar. Jag ser sällan ett projekt där någon faktiskt ändrar HTML-rotens teckensnittsstorlek beroende på skärmstorlek, och det med rätta. Om du inte har en mycket typografiskt tung design är det osannolikt att du vill skala allting på en gång.

Så hur kan vi göra oss av med vårt tillgänglighetsfusk?

Sätt HTML-fontstorleken som en procentandel. Det är en procentandel av användarens standardstorlek för typsnitt i webbläsaren. En typisk metod är att ställa in HTML-teckensnittsstorleken på 62,5 %. Det beror på att 62,5 % av 16px (typisk standardstorlek för typsnitt i webbläsaren) är 10px. Det skulle fortfarande ge 1,6rem = 16px. Detta innebär nu att om användarens standardstorlek för typsnitt i webbläsaren ändras till t.ex. 20px, skulle 1,6rem nu motsvara 20px. Så om användaren vill ha större typsnitt, låt dem göra det. Glad designer. Glad utvecklare. Alla siffror är fortfarande lätta att arbeta med.

Det ideala scenariot skulle vara att låta HTML-teckensnittsstorleken vara 100 %, men det gör det lite svårare att räkna. Till exempel är 16px nu 1rem, 20px är 1,25rem, 24px är 1,5rem etc.

Sass/SCSS till undsättning

Att räkna ut alla dessa siffror i huvudet skulle vara ganska tidskrävande. Tack och lov behöver du inte oroa dig om du använder Sass/SCSS, LESS eller någon annan CSS-förprocessor. Du kan använda funktioner för att beräkna dessa saker åt dig.

Hur är det med EMs?

EMs fungerar till en början på ett liknande sätt som REMs, tills det kommer till nesting. Jag har aldrig varit ett fan av EMs, särskilt när det gäller teckenstorlekar. Ta till exempel en div med en typsnittsstorlek på 2em och lägg sedan till ett stycke med en typsnittsstorlek på 2em. Typsnittsstorleken för stycket är nu 2ems i förhållande till div:en. Jag tappar snabbt bort matten och vilken storlek som är vad, och det blir snabbt oöverskådligt. Detta är vad REMs löser – storleken hänvisar alltid tillbaka till roten.

Hur är det med media queries?

Så vi har fastställt att användningen av pixelvärden åsidosätter webbläsarens standardinställningar, så att helt enkelt konvertera alla pixelstorlekar till REMs är det bästa att göra, eller hur? Inte riktigt.

Detta blogginlägg belyser några av de viktigaste skillnaderna mellan att använda pixlar, EMs och REMs i mediaqueries (https://zellwk.com/blog/media-query-units/). Läs igenom och kom sedan tillbaka.

Sammanfattningsvis misslyckas både pixlar och REMs för media queries i olika webbläsare när man använder webbläsarzoom, och EMs är det bästa alternativet vi har. REMs misslyckas mycket mer än pixlar vid det här laget, så vi kommer att utesluta dem helt och hållet.

Det blir dock lite knepigare. Både EMs och pixlar har sina brister med media queries när det kommer till skillnaden mellan en decimalplats i den enheten. Om du råkar använda både min och max width media queries i samma kodblock kommer du att få problem så fort användaren börjar ändra sin webbläsares zoom eller standardtypsstorlek.

Här är några exempel:

Vi använder 6 decimaler eftersom vissa webbläsare inte visar någon skillnad mellan 2-5.d.p.

För tydlighetens skull använder vi en typsnittsstorlek på 10 px på kroppen för att göra matematiken lite tydligare.

Exempel 1: Webbläsarens zoom är inställd på 100 %, webbläsarens bredd är inställd på 640px

min-width: 64em = Hitmax-width: 63.99em = Missmax-width: 63.999999em = Hitmin-width: 640px = Hitmax-width: 639px = Missmax-width: 639.999999px = Miss

Exempel 1b: Webbläsarens zoom är inställd på 100 %, webbläsarens bredd är inställd på 639px

min-width: 64em = Missmax-width: 63.99em = Hitmax-width: 63.999999em = Hitmin-width: 640px = Missmax-width: 639px = Hitmax-width: 639.999999px = Hit

Så vi kan inte använda 6dp för EMs, eftersom det träffar båda mediafrågorna.

Exempel 2: Webbläsarens zoom är inställd på 110 %, webbläsarens bredd är 704px (eftersom 640px * 110 % = 704px)

min-width: 64em = Missmax-width: 63.99em = Missmax-width: 63.999999em = Hitmin-width: 640px = Missmax-width: 639px = Missmax-width: 639.999999px = Hit

Exempel 2b: Exempel 2: Webbläsarens zoom är inställd på 110 %, webbläsarens bredd är 705px

min-width: 64em = Hitmax-width: 63.99em = Missmax-width: 63.999999em = Missmin-width: 640px = Hitmax-width: 639px = Missmax-width: 639.999999px = Miss

Så vi kan inte använda 2dp för EMs. Så allt vi har kvar i det här skedet är 6dp-pixlar. Detta fungerar med webbläsarens zoom. Men…

Exempel 3: Webbläsarens zoom är inställd på 100 %, webbläsarens typsnittsstorlek är inställd på 20px, webbläsarens bredd är inställd på 800 (eftersom 640 * 125 % = 800)

min-width: 64em = Hitmax-width: 63.99em = Missmax-width: 63.999999em = Hit

Så återigen, 6dp EM:s är fortfarande inte tillgängliga. Och vi kan inte använda pixlar för media queries överhuvudtaget, eftersom de fortfarande aktiveras vid 640px/639px eftersom de ignorerar EMs/REMs.

Så vad är lösningen?

Det finns tyvärr inget svar. Tills webbläsarna löser avrundningsproblemen är vi lite fast.

Det enklaste acceptabla alternativet är att vi aldrig skapar en överlappning mellan min- och maxbredd i samma block. Exempel:

body { @media screen and (max-width: 63.99em) { background: blue; } @media screen and (min-width: 64em) { background: blue; }}

Problemet med ovanstående är att det finns vissa scenarier där båda mediaqueries träffas, eller båda ignoreras. Så det säkraste alternativet är att skriva något som:

body { background: blue; @media screen and (min-width: 64em) { background: blue; }}

Varför finns det ingen riktig lösning? Jag tror inte att tillräckligt många bryr sig. All statistik som säger att folk inte ändrar standardstorleken på typsnittet i webbläsaren är definitivt snedvriden. Alternativen i Chrome för att ändra standardtypsstorlek är nu väldigt begravda i de avancerade webbläsaralternativen.

Fallgropar

Det finns några fallgropar med det här tillvägagångssättet:

  • Om du är van vid att skriva både min-width- och max-width-mediaqueries i samma kodblock kommer det att ta längre tid.
  • Det ökar komplexiteten eftersom du måste åsidosätta CSS i den ena eller andra riktningen, i stället för att tala om för webbläsaren att använda alternativ A eller B.
  • Det ökar filstorleken på grund av dessa åsidosättanden. Inte mycket, men det är värt att överväga.

Avhängigt av projektet, vem som utvecklar det och olika andra faktorer som projektbudgetar (vi måste vara realistiska här) kan pixlar vara enklare och snabbare. Det kan också vara enklare och snabbare att ignorera tillgängligheten.

Håll dig i minnet vem du bygger webbplatser för.

Det är också värt att notera att det här blogginlägget är korrekt i skrivande stund, men med de ständiga uppdateringarna av hur webbläsare fungerar kan den här frågan komma att bli ett minne blott.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *