6. Moment06 - Responsiv design

I det förra momentet så märkte vi att det ställs en del krav på oss att skapa webbsidor som ser bra ut i flera olika användaragenter. Vi skall nu lära oss responsiv design för att kunna styra hur webbsidor skall visas upp på en laptop, en tablet och en smartphone.

Exempeluppgiften

Genom hela detta moment kommer jag visa hur de olika teknikerna används genom att använda en exempeluppgift. Denna exempeluppgift har några år på nacken och har följt med från en tidigare skola där jag jobbade då. Sidan kommer i uppgiften refereras till samlingssidan.

6.1 Momentets mål

I varje moment så jobbar vi mot ett eller flera mål som skolverket har satt upp i varje kurs.

6.1.1 Centralt innehåll

  • Processen för ett webbutvecklingsprojekt med målsättningar, planering, specifikation av struktur och design, kodning, optimering, testning, dokumentation och uppföljning.
  • Märkspråk och deras inbördes roller, syntax och semantik – där det huvudsakliga innehållet är standarderna för HTML och CSS samt orientering om Ecmaskript och dokumentobjektsmodellen (DOM).
  • Teckenkodning, begrepp, standarder och handhavande.
  • Bilder och media med alternativa format, optimering och tillgänglighet.
  • Riktlinjer för god praxis inom webbutveckling.
  • Interoperabilitet genom att följa standarder och testa på olika användaragenter.
  • Applikationer som fungerar oberoende av val av användaragent, operativsystem eller hårdvaruplattform och hur tillgänglighet uppnås även för användare med funktionsnedsättning.
  • Kvalitetssäkring av applikationens funktion och validering av kodens kvalitet.
  • Terminologi inom området webbutveckling.

6.2 Responsiv design

Responsiv design handlar om att anpassa webbsidorna till olika användaragenter. Tidigare har utvecklare byggt olika sidor för olika enheter, kanske har du någon gång blivit överflyttad till m.coolasidan.nu när du går in på coolasidan med en mobiltelefon. Det där är en rest från hur det såg ut tidigare när det tekniskt var svårare att utveckla för flera olika enheter samtidigt. Idag är det inte speciellt svårt och idag strävar man efter mer och mer sömlösa övergångar mellan olika agenter. Dessutom kan vi se att appar allt oftare får ge vika för välutvecklade sidor för webben.

En stående smartphone har en ganska smal bild, en liggande smartphone är nästan lika bred som en stående tablet och en liggande tablet kan visa lika många pixlar som en laptop. Detta innebär att vi måste ta hänsyn till vårt förändrade förhållningssätt till hur vi använder webbsidor.

Som så mycket inom webbutveckling så går utvecklingen väldigt fort. De som jobbar i branschen är ofta väldigt insatta i teknikerna och vet precis vad som är det senaste och det som är mest effektivt för tillfället. Det jag vill att du lär dig i detta moment är själva konceptet kring responsiv design. De tekniker jag använder i övningarna kommer säkerligen fungera i flera år framåt men de kommer hela tiden nya tekniker och lösningar. Förstår du dock varför och hur du behöver tänka så är du mottaglig för den nya tekniken.

6.2.1 Övning genom exempel

Jag visar med ett exempel. För några år sedan, på en tidigare skola, så startade vi kursen Webbutveckling01 med att gemensamt bygga det vi då kallade för en samlingssida. Denna samlingssida skulle bli en utgångspunkt för att redovisa uppgifter i flera olika kurser inom webb/programmering. Här hittar du min version av denna filen. Naturligtvis har jag skruvat till den lite extra så att vi har lite jobb att göra för att få sidan att bli responsiv. Validering av html- och css-kod går utan problem, tillgänglighetsvalideringen går också bra. Om vi gör ett test på mobilvänligheten så får vi däremot underkänt.

Validering av mobilvänlighet

bild

Fast skall vi vara ärliga så anser Bing att webbsidan är godkänd utifrån mobilvänlighet trots att den underkänner fyra av fem tester. Jag hade iaf inte godkänt denna sidans mobilvänlighet.

En viktig sak att tänka på när du jobbar med de olika tjänsterna är att de är en vägledning, ibland så visar de upp sidan fel och du kan inte återskapa exakt samma utseende i din mobil, din tablet eller i ett utvecklarläge. Det ger dock bra hjälp för det mesta. Du kan ju också välja att kika på sidan genom olika användaragenter genom webbläsarens utvecklarläge, som vi kikade på i förra momentet.

Webben vimlar av mer eller mindre bra tjänster, här vill jag visa en som inte validerar koden men som på ett enkelt sätt visar hur din sida ser ut i fyra olika agenter på samma gång, amiresponsive. Bild på hur min samlingssida ser ut hittar du nedan, länken hittar du här.

Am I responsive?

bild

6.3 Relativa enheter

På samlingssidan så har jag använt mig av enheter som har absoluta längder, i mitt fall px som står för pixlar. Jag har t.ex. talat om att bredden på main-elementet skall vara 1200px vilket den alltid kommer vara oavsett hur bred skärmen är. Pixel är ju ett mått på den minsta enhet som kan visas på en skärm. Beroende på upplösningen på skärmen så kan det visas fler pixlar i bredd. Pt är en annan absolut enhet som vi använt för att bestämma storlek på t.ex. en font-size.

6.3.1 em och rem

em är en relativ enhet som är kopplad till teckensnittsstorleken hos det element där den används. Om du använder em för att definiera en storlek, kommer den storleken att vara relativ till teckensnittsstorleken av elementets förälder. Till exempel, om en förälder har en teckensnittsstorlek på 20pt, kommer 1em att motsvara 20pt inom det barnet. Detta gör em användbart för responsiv design, eftersom storlekar kan anpassas dynamiskt beroende på föräldraelementets storlek. En nackdel är att användningen av em kan bli komplicerad i nästlade strukturer, eftersom varje nivå av nästling kan förändra basstorleken.

rem, som står för "Root EM", är också en relativ enhet, men den är alltid relaterad till rootelementets (<html>) teckensnittsstorlek. Oavsett var i dokumentet rem används, refererar den alltid till storleken på root-elementets teckensnitt. Om teckensnittsstorleken för <html> är 16pt, kommer 1rem alltid att vara 16pt. Detta gör rem enklare att använda och mer förutsägbar än em i komplexa layouter, eftersom storleken inte påverkas av föräldraelementens teckensnittstorlek. rem är särskilt användbart för att bygga konsistenta och lättanpassade gränssnitt, där du vill att alla marginaler, padding och dimensioner ska vara konsekventa i hela applikationen.

Kodexempel: em och rem

html {
    font-size: 12pt;  /* Sätter grundfontstorleken för hela dokumentet */
}

h2 {
    font-size: 1.5rem; /* 1.5 gånger root-elementets fontstorlek */
}

div {
	font-size: 1.1rem; /* 1.1 gånger root-elementets fontstorlek */
}

div.h2 {
	font-size: 1.2em; /* 1.2 gånger div-elementets fontstorlek */
}

Em och rem används främst för text, och instruktioner relaterade till text som t.ex. margin och padding men kan egentligen användas som instruktion till vilket element som helst.

6.3.2 %, vw, vh

När vi vill bestämma storlekar på våra element som inte har med textstorlek att göra så har vi tidigare använt pixlar som enhet. Pixlar har den nackdelen att den är väldigt statisk och bryr sig inte om hur bred skärmen är. För att jobba med relativa enheter för att styra någonting utifrån skärmens storlek så är det bättre att använda sig av enheterna procent (%), viewport width (vw) och viewport height (vh). Viewport hänvisar till det synliga området på en webbläsares fönster eller skärm där webbsidan visas.

vw relaterar till bredden på din skärm/webbläsare och 100vw motsvarar hela bredden.

Det går att blanda enheter precis som man vill men naturligtvis har det sina konsekvenser om man inte har koll på vad man gör.

Blandade enheter

En sida med blandade enheter

Här blandas både vw, % och px för att styra olika elements bredd. Det finns tillfällen då detta kommer fungera jättebra, t.ex. om skärmen är 625px bred så fungerar det perfekt. Men när skärmen är 1280px eller 360px så kommer det se konstigt ut eller så finns ingen responsivitet alls.

Så tipset är att inte blanda allt för mycket, men det lär vi oss på vägen.

Vw är relativt smidigt att jobba med men vh är inte lika smidigt. Jag brukar inte rekommendera att styra webbsidornas design utifrån höjden på användaragenten utan låta webbsidans innehåll och bredd få styra. Ju mer du vill styra utifrån höjden desto mer kommer du också inse att vh inte räcker fullt ut. Då kan vmin och vmax också vara bra att ha koll på.

Use these instead of vh (Kevin Powell)

Mer info om de olika enheterna kan du hitta här.

6.3.3 Övning genom exempel

Dags att ge sig på samlingssidan, jag kommer att ersätta alla storlekar med vw, vh och rem. Det jag vill få fram är att sidan skall se likadan ut i fullskärm som tidigare men att den skall skalas ner och behålla proportionerna även på en mindre skärm. Jag är medveten om att mobilvänligheten kanske inte blir så mycket bättre på en väldigt liten skärm men jag vill inte att någon del av sidan skall befinna sig utanför skärmen som det är just nu.

Borders, padding och margin har ofta små värden och här kan det vara aktuellt att använda px. Det gäller att prova sig fram lite. Våra koder är ju validerade så vi har inte gjort något fel så här långt, nu gäller det bara att skapa den upplevelsen av sidan som vi vill åt.

Den uppdaterade filen hittar du här. Välj att visa sidkällan för att se all kod, vill du på ett enkelt sätt se skillnaden på den tidigare koden så använd tjänsten diffnow.com.

När vi testar mobilvänligheten så får jag samma resultat som tidigare.

Validering av mobilvänlighet

bild

Det går naturligtvis att se att sidan inte är helt perfekt men det som vi ser är att på smalare skärmar så byter våra section-element rad när de inte får plats vilket gör att hela sidan aldrig blir bredare än skärmens bredd. Vi ser också på bilden nedan att på smartphonen så visas bara ett section-element i bredd eftersom det inte får plats med två stycken i bredd som det gör på skärmen för en tablet. Utseendemässigt är jag inte helt nöjd med hur header-elementet visas upp på en smartphone, men det får vara så för tillfället.

Am I responsive?

bild

Uppgift: Använda relativa enheter

Nu vill jag att du gör en uppgift där du förändrar en befintlig sida så att den blir responsiv mha av relativa enheter. Troligtvis finns det en del saker som går att förbättra vad det gäller responsiviteten för projektet MarkDown eller för Skogssidan? Du får gärna välja ett annat projekt men att välja en sida som redan är ok, eller nära på ok, kommer inte utveckla dina förmågor. Oavsett vilket projekt du väljer så vill jag inte att du använder Paolos Webb att jobba med.

Det är inte helt säkert att denna tekniken räcker för att göra exakt det du vill, jobba då vidare med nästa avsnitt som heter media query för att få större möjligheter att lösa designen som du vill.

I detta moment skall skall totalt minst två olika tekniker användas och redovisas, kika på Redovisning av Moment06 längst ner på denna sidan för att se vad som förväntas lämnas in. Du väljer själv om just denna uppgiften skall vara en av de som redovisas.

6.4 Media query

I detta avsnitt ska vi titta på två viktiga delar:

  • hur webbläsaren på mobila enheter tolkar sidans bredd (viewport)
  • hur vi med hjälp av @media kan ändra designen vid olika skärmstorlekar

Tillsammans gör dessa tekniker det möjligt att styra när och hur designen ska förändras.

6.4.1 Viewport

Innan vi börjar använda media queries behöver vi förstå begreppet viewport. Viewport är den yta som webbläsaren använder för att visa webbsidan.

På en dator motsvarar viewporten oftast webbläsarfönstrets storlek. På mobila enheter fungerar det annorlunda. Om ingen viewport är angiven kommer mobilen ofta att låtsas att webbsidan är mycket bredare än skärmen, vilket gör att sidan skalas ned och visas förminskad.

För att tala om för webbläsaren hur sidan ska visas använder vi en meta-tagg i <head>:

Kodexempel: viewport meta-tag

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Detta innebär att:

  • width=device-width gör att sidans bredd anpassas efter enhetens faktiska bredd
  • initial-scale=1.0 gör att sidan visas i normal storlek utan att vara in- eller utzoomad

Detta är den rekommenderade standardinställningen och den som ska användas i dina projekt om inget särskilt skäl finns.

6.4.1.1 Alternativa inställningar (och varför de oftast inte används)

Det finns fler inställningar som kan anges i viewport-taggen, till exempel:

  • maximum-scale och minimum-scale – begränsar hur mycket användaren kan zooma
  • user-scalable=no – förhindrar att användaren zoomar
  • fasta bredder, till exempel width=800

Dessa inställningar används sällan eftersom de ofta försämrar användarupplevelsen och tillgängligheten. Att hindra användaren från att zooma kan till exempel göra sidan svår att läsa för personer med nedsatt syn.

I denna kurs använder vi därför alltid standardlösningen och fokuserar istället på att skapa en design som fungerar bra oavsett skärmstorlek.

6.4.2 @media query

När viewporten är korrekt inställd kan vi använda media queries för att anpassa designen efter olika skärmstorlekar och visningssätt. Media queries gör det möjligt att låta vissa CSS-regler gälla endast när ett eller flera villkor är uppfyllda.

Det är viktigt att förstå att media queries inte ersätter din vanliga CSS. De används istället för att justera och förändra delar av designen när förutsättningarna ändras, till exempel när skärmen blir smalare.

Kodexempel: använda @media query i CSS

@media screen and (max-width: 599px) { }

@media är nyckelordet som inleder en media query.

screen anger vilken typ av media reglerna gäller för. screen betyder att reglerna gäller när sidan visas på en skärm. Ett vanligt alternativ är print, som används när sidan ska anpassas för utskrift.

and (max-width: 599px) betyder att reglerna endast gäller om viewportens bredd är högst 599 pixlar.

För att hela villkoret ska vara uppfyllt måste alltså sidan visas på en skärm och ha en bredd på max 599px. Inom måsvingarna skriver du de CSS-regler som ska gälla i just detta fallet.

6.4.2.1 Hur ska man tänka när man använder media queries?

Ett vanligt nybörjarmisstag är att försöka skapa en helt ny design i varje media query. Det leder ofta till mycket dubbel kod och gör designen svår att underhålla.

Tänk istället så här:

  • Skriv först de globala CSS-reglerna som gäller för alla skärmstorlekar
  • Använd @media för att ändra det som behöver ändras
  • Undvik att skriva om CSS som redan fungerar

Media queries används alltså för att göra undantag, inte för att bygga om hela sidan från början.

Det finns flera villkor som kan användas i media queries. Du kan till exempel styra designen baserat på:

  • skärmens bredd eller höjd
  • om enheten är i liggande eller stående läge
  • om sidan visas på skärm eller ska skrivas ut

Som vanligt kommer vi långt med tanken less is more. Försök att hålla dina regler så enkla som möjligt och undvik onödigt många brytpunkter. W3Schools listar flera olika alternativ och exempel på sidan CSS Media Queries.

6.4.2.2 Mobile first – ett alternativt arbetssätt

I exemplen hittills har vi utgått från en större skärm och anpassat designen när skärmen blir mindre. Ett annat vanligt arbetssätt är mobile first.

Mobile first innebär att du:

  • först designar sidan för små skärmar
  • sedan förändrar layouten när bredden blir större

Detta görs oftast genom att använda min-width istället för max-width. Båda sätten fungerar, men mobile first ger ofta bättre kontroll över designen och gör det lättare att upptäcka problem tidigt.

Ett vanligt problem i början

Det är vanligt att man överarbetar media queries när man är ny. Om du till exempel vill skapa tre varianter av en webbsida ska du inte skriva all CSS tre gånger.

Skriv istället de globala reglerna först och ändra bara det som faktiskt behöver ändras i respektive media query.

  • Koden blir kortare och mer lättläst.
  • Det blir enklare att ändra designen senare.

Hur många media queries du behöver beror helt på vilken typ av webbsida eller applikation du skapar. Det vanligaste är dock att arbeta med minst tre olika skärmbredder.

Att försöka anpassa sig efter exakta skärmupplösningar är oftast inte en bra idé. Upplösningar förändras hela tiden och ser dessutom väldigt olika ut beroende på enhet. Därför är det bättre att följa etablerad praxis och göra som många andra webbutvecklare gör.

Följ länken och titta på olika förslag på responsive breakpoints och välj de brytpunkter som passar ditt projekt bäst.

StatCounter Global Stats - Screen Resolution Market Share

Source: StatCounter Global Stats - Screen Resolution Market Share

6.4.2.3 Övning genom exempel

Nu ska vi titta på ett konkret exempel på hur man kan arbeta med @media. I detta exempel utgår vi från samlingssidan och gör stegvisa justeringar av designen beroende på skärmens storlek.

Jag kommer att:

  • ändra bakgrundsfärg på header- och footer-elementen beroende på skärmbredd
  • justera hur kursrutorna (section) visas i tabletläge så att de hamnar under varandra
  • anpassa textstorleken i header på smartphone, där den annars blir för stor

Syftet är inte att skapa en perfekt mobilversion, utan att visa hur media queries kan användas för att stegvis förbättra layouten när förutsättningarna ändras.

Am I responsive?

bild

Den uppdaterade filen hittar du här. Välj att visa sidkällan för att se all kod. Vill du på ett enkelt sätt se skillnaden mot den tidigare versionen kan du använda tjänsten diffnow.com.

Att bli duktig på media queries kommer vara grundläggande för att du skall kunna skapa bra webbsidor med full responsivitet. Erfarenhet av tekniker får du genom att använda den och att lära sig av andra. Här finns två filmer som på ett bra sätt visar hur man använder tekniken. Den andra filmen tar ett bredare perspektiv på hela området men där finns det bra lärdomar att dra av det han pratar om.

Tutorial: Learn CSS Media Query in 7 Minutes

Här går han verkligen igenom konceptet med media queries och ger dig en bra bas att sedan undersöka vidare på egen hand.

Tutorial: 5 simple tips to making responsive layouts the easy way

I denna filmen hittar du många bra tips, lite flexbox och sedan några bra tips på modern css som vi normalt sett inte jobbar med under denna kursen. Uppskattar du denna filmen så har han en gratiskurs där han går på djupet med responsiv design.

Uppgift: Använda media queries

Det här är lite svårare än den förra uppgiften och det kan ofta kännas lite pilligt att anpassa webbsidan på flera olika sätt. Men det är också bra träning och om du vill nå de högre betygen på denna kursen så behöver du behärska detta arbetet.

Välj ett lämpligt projekt som du vill förändra med media queries, kanske är det återigen MarkDown eller Skogssidan som behöver lite kärlek? Oavsett vilken webbsida/webbprojekt du väljer så undvik Paolos webb även denna gången.

Här kan det förenkla att göra skisser för de olika varianter av sidor du vill använda, så ett tips är att bestämma dig för vilka breakpoints du vill använda dig av och sedan göra en bra skiss på de olika varianterna. Ta dig inte vatten över huvudet, det räcker långt att göra en sida i två varianter; dels desktopvarianten och sedan en mobilanpassad variant. Får du sedan tid så kan du ju skissa på, och bygga, den varianten där emellan.

6.4.3 Fördjupning: CSS-variabler

CSS-variabler (även kallade custom properties) är ett sätt att lagra värden som kan återanvändas på flera ställen i din CSS-kod. De fungerar ungefär som variabler i programmering och kan göra din kod både tydligare och enklare att underhålla.

Detta avsnitt är en fördjupning. Du måste inte använda CSS-variabler i dina projekt, men om du har god koll på grunderna i CSS kan de hjälpa dig att skriva mer strukturerad och lättförståelig kod.

6.4.3.1 Grundprincip

En CSS-variabel skapas genom att ge den ett namn som börjar med --. Variablerna placeras oftast i selektorn :root, vilket innebär att de blir tillgängliga i hela dokumentet.

Kodexempel: skapa och använda CSS-variabler

:root {
  --primary-color: #2c7be5;
  --secondary-color: #f4f4f4;
  --padding-large: 2rem;
}

header {
  background-color: var(--primary-color);
  padding: var(--padding-large);
}

main {
  background-color: var(--secondary-color);
}

I exemplet ovan definieras färger och avstånd på ett ställe. Om du vill ändra en färg eller ett avstånd behöver du bara göra det i :root, istället för att leta upp samma värde på flera ställen i koden.

6.4.3.2 Varför använda CSS-variabler?

  • Du slipper upprepa samma värden i flera regler
  • Det blir enklare att ändra designen i efterhand
  • Koden blir tydligare och mer lättläst

CSS-variabler förändrar alltså inte vad din kod gör, utan hur den är organiserad.

6.4.3.3 CSS-variabler tillsammans med media queries

En stor fördel med CSS-variabler är att de fungerar mycket bra tillsammans med media queries. Istället för att ändra många olika CSS-regler i en media query kan du ändra värdet på en eller flera variabler.

Exempel: ändra variabler i en media query

:root {
  --header-bg: #333;
  --header-font-size: 2.5rem;
}

header {
  background-color: var(--header-bg);
  font-size: var(--header-font-size);
}

@media screen and (max-width: 600px) {
  :root {
    --header-bg: #555;
    --header-font-size: 1.8rem;
  }
}

I detta exempel ändras endast variablerna i media queryn. Alla element som använder variablerna uppdateras automatiskt, utan att du behöver skriva om deras CSS-regler.

6.4.3.4 När passar CSS-variabler?

CSS-variabler passar extra bra när du:

  • arbetar med färgteman
  • vill justera avstånd eller textstorlekar för olika skärmstorlekar
  • har många liknande värden i din CSS

För mindre projekt eller enklare övningar kan vanlig CSS fungera utmärkt. CSS-variabler är ett verktyg – inte ett krav.

6.4.3.5 Samlingssidan med CSS-variabler

Nu är det dags att ge sig på samlingssidan igen, men denna gång med fokus på CSS-variabler. Själva utseendet på sidan är i stort sett identiskt med tidigare versioner, men sättet vi organiserar vår CSS-kod på har förändrats.

Istället för att skriva färger, storlekar och avstånd direkt i varje CSS-regel har vi nu samlat dessa värden som variabler i :root. Det gör att vi kan styra stora delar av designen från ett och samma ställe.

Detta förändrar inte hur sidan ser ut i fullskärmsläge, men det gör det betydligt enklare att justera designen för olika skärmstorlekar. När vi kombinerar CSS-variabler med media queries kan vi till exempel ändra färger, textstorlekar eller bredder genom att ändra ett fåtal värden, istället för att skriva om många regler.

Precis som tidigare är sidan inte fullt mobilanpassad på mycket små skärmar, men målet här är inte att skapa en perfekt mobilvy. Fokus ligger istället på att ingen del av sidan hamnar utanför skärmen och att koden blir mer strukturerad och lättare att vidareutveckla.

Den uppdaterade filen hittar du här. Välj att visa sidkällan för att se all kod. Vill du på ett enkelt sätt jämföra denna version med den tidigare kan du använda tjänsten diffnow.com.

När vi testar mobilvänligheten får vi i princip samma resultat som tidigare. Skillnaden ligger alltså inte i slutresultatet, utan i hur koden är uppbyggd och hur lätt den är att förändra.

Fördjupningsuppgift (valfri)

Om du har god koll på CSS och media queries kan du nu förbättra din kod genom att använda CSS-variabler.

Välj ett lämpligt projekt som du vill förändra med media queries, kanske är det återigen MarkDown eller Skogssidan som behöver lite kärlek? Oavsett vilken webbsida/webbprojekt du väljer så undvik Paolos webb även denna gången. Sedan skall du:

  • ersätta återkommande färger med CSS-variabler
  • ersätta minst ett avstånd eller en textstorlek med en variabel
  • använda en media query för att ändra minst en variabel vid en viss skärmbredd

Fokusera på att göra koden tydligare och mer lätt att ändra – inte på att bygga en helt ny design.

6.5 Flexbox och Grid

Två andra verktyg som är relevanta när vi jobbar med responsiv design är Flexbox och Grid vilket är tekniker som vuxit fram för att skapa mer funktionalitet till CSS.

Flexbox, eller Flexible Box Layout, är en teknik som är användbar för att hantera layouter i en riktning, antingen en layout som består av flera rader eller kolumner. CSS Grid Layout är användbart om du vill bygga en tvådimensionell layout med både rader och kolumner.

6.5.1 Flexbox

Här kommer ett exempel på flexbox där tre element placeras ut jämnt inom ett föräldraelement. Detta är en design som inte alltid är så smidig utan flexbox men som görs relativt enkelt med flexbox.

flexbox.html

<!DOCTYPE html>
<html>
<head>
  <title>Flexbox</title>
  <style>
  .flex-container {
    display: flex;
    background-color: blueviolet;
    justify-content: space-around;
  }

  .flex-item {
    background-color: CornflowerBlue;
    padding: 10px;
    color:white;
    min-height: 100px;
    width: 25vw;
    margin: 10px;
    text-align: center;
  }
  </style>
</head>
<body>
  <div class="flex-container">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>  
  </div>
</body>
</html>

Resultatet

Detta var bara ett exempel på hur man kan använda flexbox. Det går utmärkt att lösa hela denna kursen utan att kunna använda flexbox men som allt annat vi gör i denna kursen så handlar det om att lära oss ett antal verktyg och den som behärskar flest verktyg kommer ha bättre möjligheter att välja det verktyg som bäst, snabbast eller effektivast löser uppgiften. Därför bestämmer du själv vilka tekniker du vill lära dig och vilka resurser du vill använda för att nå målen i denna kursen.

Dags för lite resurser, först två tutorials som jag gillar.

Learn flexbox the easy way (Kevin Powell)

Learn Flexbox CSS in 8 minutes (Slaying The Dragon)

Sedan tre generatorer där du relativt enkelt kan bygga upp flexboxregler. Testa och se om det är någon av dessa du gillar.

Flexbox froggy är ett spel där du lär dig flexbox genom att flytta runt grodor.

Slutligen så finns det i Inspekteraren i Chrome en möjlighet att klicka på flexsymbolen och leka med flexregler om du har skapat en sida och givit dina element flexlayout.

6.5.2 Grid

Dags för lite Grid, först visar jag med ett enkelt med ganska användbart exempel.

grid.html

<!DOCTYPE html>
<html>
  <head>
    <title>Grid</title>
    <style>
    .grid-container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
      gap: 10px;
      background-color: Tomato;
      padding: 10px;
    }
    .grid-item {
      background-color: LightSalmon;
      border: 1px solid rgba(0, 0, 0, 0.8);
      padding: 20px;
      font-size: 30px;
      text-align: center;
    }
    </style>
  </head>
  <body>
    <div class="grid-container">
      <div class="grid-item">1</div>
      <div class="grid-item">2</div>
      <div class="grid-item">3</div>  
      <div class="grid-item">4</div>
      <div class="grid-item">5</div>
      <div class="grid-item">6</div>
    </div>
  </body>
</html>

Resultatet

Lite bredare variant...

... och en lite smalare.

Här går det alltså att ställa in så att alla sex rutorna får plats på bredden för en stor skärm och sedan alla varianter ner tills det endast är en rutas bredd på den smalaste mobilskärmen.

Lite resurser, först två tutorials.

Learn CSS Grid the easy way (Kevin Powell)

0:00 / 0:15 Learn CSS Grid - A 13 Minute Deep Dive (Slaying The Dragon)

Även för grid finns det generatorer online som kan vara användbara, här kommer två exempel.

Grid garden är ett spel där du lär dig grid genom att flytta runt grödor i en trädgård.

Även med grid så finns det möjlighet att leka lite med inställningar i Chromes Inspekteraren. Klicka på gridsymbolen och lek med olika gridinställningar om du har skapat en sida och givit dina element layout för grid.

6.5.3 Flexbox i kombination med grid

Det går kanske att se användningsområde för både flexbox och grid, men hur fungerar de ihop? Kolla på detta exemplet!

flexbox_grid.html

<!DOCTYPE html>
<html lang="sv">
<head>
    <meta charset="UTF-8">
    <title>Exempel på Flexbox och Grid</title>
    <style>
        body {
            margin: 0;
            font-family: Arial, sans-serif;
        }

        div {
            display: grid;
            grid-template-columns: 1fr;
            grid-template-rows: auto 1fr auto;
            grid-template-areas: 
                "header"
                "main"
                "footer";
            height: 100vh;
        }

        header {
            grid-area: header;
            background-color: #4CAF50;
            color: white;
            text-align: center;
            padding: 1rem;
        }

        main {
            display: flex;
            grid-area: main;
        }

        .content {
            flex-grow: 2;
            background-color: #f2f2f2;
            padding: 1rem;
        }

        .sidebar {
            flex-grow: 1;
            background-color: #ddd;
            padding: 1rem;
        }

        footer {
            grid-area: footer;
            background-color: #333;
            color: white;
            text-align: center;
            padding: 1rem;
        }
    </style>
</head>
<body>
    <div>
        <header>Header</header>
        <main>
            <section>Huvudinnehåll</section>
            <aside class="sidebar">Sidokolumn</aside>
        </main>
        <footer>Footer</footer>
    </div>
</body>
</html>

Resultatet

Här skapas ett div-element som fyller ut hela skärmen både på höjden och bredden, div-elementet har grid-layout. main-elmentet som ramar in elementen med huvudinnehåll och sidokolumn styrs av flex-layout.

Det fungerar alltså helt utmärkt att blanda dessa tekniker.

6.5.4 Flexbox, grid och media query

Även om vi kan göra mycket med flexbox och grid var och en för sig och ännu mer när de samarbetar så finns det tillfällen då det ändå inte räcker. I detta exempel så bygger jag vidare på det tidigare men lägger också till media queries för att jag vill styra sidokolumnen så att den hamnar ovanför huvudelementet i en mobiltelefon.

flexbox_grid.html

<!DOCTYPE html>
<html lang="sv">
<head>
    <meta charset="UTF-8">
    <title>Exempel på Flexbox och Grid med Media Query</title>
    <style>
        body {
            margin: 0;
            font-family: Arial, sans-serif;
        }

        div {
            display: grid;
            grid-template-columns: 1fr;
            grid-template-rows: auto 1fr auto;
            grid-template-areas: 
                "header"
                "main"
                "footer";
            height: 100vh;
        }

        header {
            grid-area: header;
            background-color: #4CAF50;
            color: white;
            text-align: center;
            padding: 1rem;
        }

        main {
            display: flex;
            flex-direction: row;
            grid-area: main;
        }

        section {
            flex-grow: 2;
            background-color: #f2f2f2;
            padding: 1rem;
        }

        aside {
            flex-grow: 1;
            background-color: #ddd;
            padding: 1rem;
        }

        footer {
            grid-area: footer;
            background-color: #333;
            color: white;
            text-align: center;
            padding: 1rem;
        }

        /* Media Query för skärmar smalare än 600px */
        @media screen and (max-width: 600px) {
            main {
                flex-direction: column-reverse; /* Ändra ordningen för flex-items */
            }
            aside{
                max-height: 60px;
            }
        }
    </style>
</head>
<body>
    <div>
        <header>Header</header>
        <main>
            <section>Huvudinnehåll</section>
            <aside>Sidokolumn</aside>
        </main>
        <footer>Footer</footer>
    </div>
</body>
</html>

Resultatet

Återigen ett bevis på att ju fler verktyg vi kan hantera desto bättre lösningar kan vi skapa.

Uppgift: Flexbox & grid

Uppgiften blir att leka lite med flexbox och/eller grid. Bygg en ny sida, ändra en gammal eller använd någon av resureserna som länkas ovan bara för att testa teknikerna lite. En dag är de kanske dessa tekniker du behöver använda för att bygga en lösning på det bästa sättet?

6.6 Ramverk

Nästa teknik vi skall kika på är ramverk som hjälper oss väldigt mycket när vi skall göra responsiva webbsidor. Ett ramverk är färdigskriven CSS-kod som används i dina html-filer för att skapa webbsidor. Det finns många fördelar med att använda ramverk då koden används av många användare vilket gör att tekniken ofta är testad på ett bra sätt vilket i sin tur gör att applikationernas funktionalitet blir stabil. Det finns mängder av ramverk som fokuserar på olika saker, vissa är väldigt stora och har instruktioner för alla möjliga komponenter, vissa är mindre och är mer fokuserade på vissa saker och så finns det de ramverken som endast har fokus på att lösa responsiviteten på en hemsida.

Det utvecklas hela tiden nya ramverk, både från grunden, men också ramverk som utvecklas vidare från andra ramverk. Ett av de ramverken som varit stora länge och som alla webbutvecklare kommer i kontakt med är Bootstrap, som också är ett av de ramverk som är mest omfattande. Bootstrap har en väldigt bra dokumentation med mängder av kodexempel men det kanske är ett något stort kliv att direkt lära sig detta.

Jag har istället valt att vi skall testa ett något enklare ramverk som heter Materialize css. När jag pratar om ett enkelt ramverk så är det naturligtvis relativt. Alla ramverk har sin uppsättning av regler och så länge man följer dessa så kommer sidan fungera som det är tänkt. Nackdelen med ramverk är ofta att de kräver lite arbete och tid att komma över tröskeln för att få allt att fungera. Alla regler gör det enkelt att tappa bort sig och gå vilse om man inte är strukturerad i sitt kodande. Jag har valt detta ramverk att testa då det finns en väldigt bra tutorial för att testa lite på ramverket.

På ramverkets hemsida så finns all info som kommer behövas. Den grundläggande html-strukturen finns att hämta och sedan handlar det om att hämta kod för olika komponenter och pussla ihop din sida. Det tar en liten stund att komma in i det men när du förstår hur det är uppbyggt så handlar det om att klippa, klistra och ändra. Ett tips från coachen är att se till att koden är korrekt indenterad annars kommer du gå vilse när du skall flytta element eller placera ut nya element i din befintliga struktur.

6.6.1 Övning genom exempel

Jag kommer bygga om samlingssidan med hjälp av Materialize css och det finns en film som gör nästan samma sak som jag vill göra.

Tutorial: Introduktion till Materialize.css

Samlingssidan skapad med Materialize css hittar du här och så här ser sidan ut när jag är klar. Det mesta ser bra ut förutom kursrubriken Webbserverprogrammering01 som har blivit för lång. Detta lägger jag ingen energi på nu, men hade jag lämnat in denna uppgift så hade det inte varit godkänt.

Här kommer koden att skrivas om så mycket att det inte är någon mening att jämföra denna version med tidigare versioner av samlingssidan.

Am I responsive?

bild

Uppgift: Använda ramverk

Det här är ännu lite svårare än de tidigare uppgifterna men om du tycker att det är kul med webbutveckling och vill lära dig att arbeta med ramverk för att snabbt bygga snygga webbsidor så är det värt att göra denna uppgiften.

Gör uppgiften genom att förändra din landing page, något av dina tidigare projekt, kanske Markdown-projektet eller Skogssidan, eller en helt ny applikation. Undvik dock även denna gång Paolos Webb. Fokus ligger på att du jobbar med tekniken.

6.6.2 Att välja ramverk

I tidigare avsnitt har jag nämnt två ramverk, Bootstrap och Materialize.css, men det finns naturligtvis många fler. Ju mer van du blir vid att skapa webbsidor desto mer sannolikt är det att du någon gång väljer att lägga grunden med ett CSS-ramverk.

Syftet med exemplen i detta avsnitt är inte att du skall lära dig alla dessa ramverk, utan att du skall se hur samma HTML-struktur kan byggas upp på olika sätt beroende på vilket verktyg man använder. Vissa ramverk är mycket lätta och ger bara en stabil grund, medan andra innehåller färdiga komponenter, grid-system och färgscheman.

En del ramverk är mobile-first, andra är mer desktop-first. I vissa fall räcker det nästan helt med färdiga klasser, i andra behöver man komplettera med egen CSS. Det är viktigt att förstå att ramverket inte ersätter dina kunskaper i HTML och CSS – det bygger ovanpå dem.

Söker du efter best css framework kommer du att hitta mängder av sidor som rankar olika alternativ. Vilket ramverk som är "bäst" beror dock helt på sammanhanget och på vad du själv trivs med att arbeta i.

Att hitta ett ramverk som du behärskar gör att du kan arbeta snabbare, skapa en mer enhetlig design och lägga mer fokus på innehåll och funktionalitet. Samtidigt är det en styrka att kunna bygga utan ramverk – då förstår du vad som faktiskt händer bakom kulisserna.

Här nedan hittar du samlingssidan byggd i flera olika ramverk:

Du har nu sett hur samma webbsida kan byggas med hjälp av flera olika CSS-ramverk. Resultatet blir i grunden liknande, men arbetssättet och strukturen skiljer sig åt.

I denna kurs är målet inte att du skall bli expert på ett specifikt ramverk, utan att du skall förstå principerna bakom dem:

  • hur grid-system fungerar
  • hur responsiv design kan lösas på olika sätt
  • hur färdiga klasser påverkar struktur och layout
  • och hur du kan kombinera ramverk med egen CSS

När du känner dig trygg i grunderna kan du själv börja experimentera och kanske hitta ett ramverk som passar just dig. Det viktigaste är inte vilket ramverk du väljer – utan att du förstår varför du väljer det.

Top CSS Frameworks to check out in 2021

En bra genomgång av 10 ramverk, kanske blir du intresserad av att kika vidare på andra ramverk. Det finns tid att testa på egen hand, ramverk kommer du med största sannolikhet använda både senare i denna kursen och i kommande kurser. Hitta gärna din favorit. Även om filmen börjar få några år på nacken så är dessa ramverk fortfarande relevanta.

6.7 DOM

Svårare avsnitt

Detta avsnitt är av lite svårare karraktär och är inte obligatoriskt för något betyg på kursen. Det du kommer lära dig i avsnittet kan dock hjälpa dig om du vill bygga applikationer med ett css-ramverk som grund men ändå ha möjligheten att lägga till egna css-instruktioner i den befintliga koden.

Du har tidigare lärt dig att skapa klasser och id'n till våra html-element för att kunna formatera dessa med css-instruktioner. När vi jobbar med ramverk så finns det ju redan klasser skapade från ramverket. Du kanske har märkt att det ofta anges flera klasser till de olika elementen, detta beror på att man väljer att lagra lite instruktioner i varje klass och anropar flera klasser för att få till designen som vi vill ha den. Alternativet är att skapa fler specialicerade klasser men det skulle också innebära att det skulle växa och bli oändligt många klasser med instruktioner i vårt ramverk.

Hur skall vi tänka när vi skall lägga till egna instruktioner tillsammans med de instruktioner som redan finns. Ett alternativ är att skapa egna klasser och sedan lägga till dessa ihop med de klasser som redan används. Ett annat alternativ är att lära sig använda DOM-strukturen.

6.7.1 DOM-strukturen

Document Object Model, förkortat DOM, är ett plattforms- och språkoberoende gränssnitt för åtkomst och dynamiskt uppdatering av ett dokuments innehåll, struktur och formatering.
(Wikipedia, 2015-02-03, http://sv.wikipedia.org/wiki/Document_Object_Model)

För att förstå uppbyggnaden så kikar vi på hur en tidgare version av kursolle var strukturerad.

Kursolle tidig version

DOM-modell för denna sidan.

De gula <section>-elementen finns inte i dokumentet men vi behöver använda dem för att förstå upplägget med DOM, vi antar att de finns i vår sida.

Nu ser vi att <section>-taggen är "child" i olika parent-selektorer. Vi kan nu välja att formattera dessa på olika sätt.

Flera selektorer med samma inställningar

section, p, .enKlass, #ettId { }

Alla dessa selektorer kommer nu att formateras på samma sätt oavsett var i DOM-strukturen de befinner sig.

En selektor som är barn inuti en annan selektor, oavsett nivå

article header { }
aside section { }

Här styr man specifika selektorer som kan finnas på olika "barnnivåer" inom en viss selektor. Tänk att <nav> också har en selektor som barn, då kommer båda <section>-elementen inom <aside class="sidebar1"> att påverkas.

En selektor som är direkt barn till en annan selektor, dvs endast nivån under

article > header { }
div > h2 { }

Här är det viktigt att elementet/selektorn är direkt underställd ett annat element/selektor, alltså en ren förälder-barn-relation.

Dubbel klasselektor

html
<div class="card-content white-text"></div>
css
.card-content.white-text { }

Om man väljer att anropa två klasser i samma element så kan vi skapa en selektor för detta. Då är det viktigt att denna selektorn skrivs ihop, annars anses den andra selektorn vara ett barn till den första.

Pseudoklasser

a:hover { }
tr:nth-child(even) { }
article > div:first-of-type { }

En pseudo-class används för att definiera ett speciellt tillstånd för ett element t.ex. när musen förs över ett element samt att besökta och ej besökta länkar visas på olika sätt.

Pseudoelement

div > h1::first-letter {font-size: 2em; }
Ett pseudo-element används för att styla en specifik del av ett element. Det kan t.ex. användas för att formatera den första bokstaven av ett element.

Om vi vill förlita oss på bara DOM så skapar du så "rena" taggar som möjligt utan att skapa en mängd klasser och id:n. Exempeluppgiften lite längre fram i avsnittet bygger bara på rena taggar. Ramverken bygger ju oftast på en stor mängd klasser. Hur du väljer att bygga upp dina projekt avgör du själv, men oavsett hur du tänker och väljer så är det viktigt att ha en bra struktur och att vara konsekvent.

Ju fler sätt du lär dig desto enklare är det att välja rätt sätt vid rätt tillfälle.

Uppgift: Designa sida med DOM [klicka för att visa]

Här finns ett kodexempel som du kan spara på din egen dator och genom att ändra i css-filen få en känsla för vad som händer om du ändrar denna. Kolla främst på de taggar som finns flera gånger och som påverkas olika beroende på vilken föräldertagg den har.

dom.html [klicka för att visa]

<!DOCTYPE html>
<html lang="sv">
  <head>
    <meta charset="UTF-8">
    <title>Domexempel</title>
    <link rel="stylesheet" href="dom.css">
  </head>
  <body>
    <article>
      <header>
        Header i article
      </header>
      <h1>h1 i article</h1>
      <div>
        <h1>h1 i div</h1>
      </div>
      <section>
        <header>
          Header i section
        </header>
        <h1>h1 i section</h1>
        <div>
          <h1>h1 i div</h1>
        </div>
        <div>
          <h1>h1 i div</h1>
          <div>
            <h1>h1 i div-div</h1>
          </div>
        </div>
      </section>
      <section>
        <h1>h1 i section</h1>
        <div>
        </div>
      </section>
      <section>
        <h1>h1 i section</h1>
        <div>div!
        </div>
      </section>
      <section>
        <h1>h1 i section</h1>
        <section>
          <h1>h1 i section-section</h1>
          <div>Div</div>
        </section>
      </section>
    </article>
  </body>
</html>

dom.css [klicka för att visa]

@charset "UTF-8";

article {
    background-color: white;
    border: 1px solid black;
    padding: 10px;
    float: left;
}

h1 {
  text-align: center;
}

section {
    width: 120px;
    border: 2px solid red;
    float: left;
    padding: 10px;
    margin-left: 10px;
}

section > section{
  padding: 0px;
  margin: 0px;
}

article div {
    background-color: #CCC;
}

body, section>div {
    background-color: #DDD;
}

article header {
    text-align: left;
    font-weight: bold;
}

article > header {
    text-align: center;
    color: red;
    font-size: 30px;
}

section:nth-child(even) {
    border-color: lime;
}

article div:first-of-type {
    margin-bottom: 20px;
    padding: 0px;
    font-weight: bold;
    color: orange;
}

div > div > h1 {
    text-transform: uppercase;
}

div > div > h1::first-letter {
    font-size: 2em;
}

Resultatet [klicka för att visa]

Testa nu att ändra bakgrundsfärgen på div:en som ligger i en annan div, eller gör texten blå i den där h1-taggen som ligger i en section-tagg som ligger i en annan section-tagg.

Genom att träna på att använda DOM så kan du sedan lösa det i skarp läge där du behöver in och justera i ett ramverk som du kanske inte har stenkoll på i början.

6.8 Redovisning

Inlämningsuppgift: Redovisning av Moment06

Minst två uppgifter skall göras och redovisas enligt ovan, men det är fritt att använda ännu fler tekniker. Minst en av uppgifterna skall vara gjort med ramverk. Länka till sidorna du har skapat och presentera uppgiften/uppgifterna i inlägg på din wordpressida. Det är bättre att göra en mindre sida (dock inte en landing page med endast en rubrik, tre länkar, och en bild) och bygga om denna med de olika teknikerna för att kunna jämföra än att göra en större sida på endast ett sätt.

När du redovisar så visa på skärmdumpar för det resultat du fick vid första läget, beskriv kortfattat vad du har förändrat och sedan så gör du en skärmdump som visar att du har löst problemet. Använd båda tjänsterna, bings mobilvänlighetstest och amiresponsive.

Om du har använt flera tekniker så beskriv kortfattat hur du uppfattar dem och hur enkla/svåra/kluriga de var att arbeta med.

6.8.1 Frivilliga uppgifter

Nu är du förmodlingen ganska duktig på html och css så nu tror jag att du har lite egna idéer på vad du skulle kunna utveckla vidare. Att testa ett nytt ramverk gör dig både bredare och djupare i din kunskap. Kanske är det läge att testa att bygga om en befintlig webbsida, undvik dock Paolos Webb, i ett nytt ramverk?