Egenskapen position

Typer av positionering

CSS-egenskapen position används för att kontrollera positioneringen av element på en webbsida. Den gör det möjligt att specificera hur ett element ska placeras i förhållande till sitt omgivande innehåll eller andra element.

Det finns fem huvudsakliga värden för positionsegenskapen: static, relative, absolute, fixed & sticky. Sedan finns det också position: inherit som man ibland kan behöva använda. Varje värde motsvarar olika typer av positionering och genom att ha kunskap om och kunna kombinera dessa så kan man göra ganska avancerade CSS-baserade layouter. Kolumner och layouter överlag är det numera vanligare att man väljer flexbox och/eller css grid, Detta kommer vi att titta på senare. Även när man använder dessa layoutmetoder är det dock bra att kunna hantera position då det ger en designfrihet för enskilda element.

Position: static

Detta är standardpositionen för element där de placeras i det normala flödet på dokumentet. De påverkas inte av top, bottom, left eller right-egenskaperna. Detta är ett block-elements standardpositionering. I exemplet nedan kommer tre boxar att hamna ordnade under varandra i samma ordning som de skrivs i htmlkoden.

<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>

#box1 {
 position: static;
 width: 200px;
 height: 200px;
 background: turquoise;
}
#box2 {
 position: static;
 width: 200px;
 height: 200px;
 left: 150px;
 background: tomato;
}
#box3 {
 position: static;
 width: 200px;
 height: 200px;
 background: gold;
}
Se exempel 1

Position: relative

En relativ positionering gör så att du kan flytta ett element relativt sin normala position utan att störa layouten för andra element. Du kan använda relative-positionering för att justera elementets position genom att använda top, bottom, left eller right-egenskaperna. Dessutom skapar vi på detta sätt ett internt koordinatsystem... men mer om det strax.

Om vi tar föregående exempel och bara byter ut static mot relative så kommer allt att se ut precis som tidigare:
#box1 {
 position: relative;
 width: 200px;
 height: 200px;
 background: turquoise;
}
#box2 {
 position: relative;
 width: 200px;
 height: 200px;
 background: tomato;
}
#box3 {
 position: relative;
 width: 200px;
 height: 200px;
 background: gold;
}
Se exempel 2

Om vi nu väljer att lägga till en left: 150px; på vår andra div(#box2) så kommer den att flyttas 150 pixlar från vänster utifrån dess ursprungsposition.

#box2 {
 position: relative;
 width: 200px;
 height: 200px;
 background: tomato;
}
Se exempel 3

Här påverkas alltså bara #box2 av förflyttningen, #box3 påverkas inte utav att det har skett en förflyttning i tidigare element utan har kvar sin ursprungsposition. Det beror på att dessa ligger på samma nivå i strukturen. För att vi ska kunna dra nytta utav relative och dess nya koordinatsystem så måste dess vara överordnade (förälder) eller underliggande (barn) element. Det här blir mycket tydligare med exempel. Om vi väljer att placera #box2 inom #box1 med samma csskod så kommer box2 att hamna 200px till vänster om dess ursprungsposition alltså samma position som #box1:

<div id="box1">
 <div id="box2"></div>
</div>
<div id="box3"></div>
Se exempel 4

Om vi istället ändrar HTML-koden så att #box3 ligger inuti #box2 så kommer #box3 att placeras på samma koordinater som #box2 vilket gör att #box2 inte syns för att den ligger under #box3.

<div id="box1"></div>
<div id="box2">
 <div id="box3"></div>
</div>

För att det ska bli ännu tydligare vad som händer så krymper vi #box3 en aning när muspekaren åker över den med :hover

#box3:hover {
 width: 150px;
 height: 150px;
}
Se exempel 5

Här är ett bra läge att experimentera lite genom att på olika element sätta olika positioneringar för att se vad som händer

Experimentera och prova på egen hand

Ta koden som använts i exemplen här ovanför och experimentera med att sätta positioneringar på de olika div-elementen. Notera var dessa positioneringar utgår ifrån och vilka element som blir påverkade.

left: 150px; förflyttar elementet 150 pixlar från vänster. Hur fungerar top:, right:, och bottom:?

Vad händer med barn-elementet(child) när du ändrar position på ett föräldraelement(parent)?

Prova att ändra i HTML-dokumentet för att se hur positioneringen fungerar när strukturen förändras, vad händer t.ex. om du sätter #box3 inuti #box2 som är inuti #box1?

Det här sättet att jobba med relative är något som är vanligare att man använder i kombination med position:absolute vilket vi tittar på härnäst.

Position: absolute

Till skillnad från static och relative så tillåter en absolute positionering att du positionerar elementet vart som helst, oberoende av det normala flödet i koden. Detta innebär att den inte påverkar eller påverkas av övriga element.

Det den har gemensamt med relative är att man styr den med hjälp av offsetkommandona top, right, bottom och left. Du kan till exempel säga att ett element ska ha följande offset-egenskaper: top:50px; left:100px och ditt element kommer att sitta 50 pixlar från toppen och 100 pixlar från vänster utifrån dokumentet eller ett överliggande koordinatsystem.

Här kommer ett första exempel med fyra boxar som tidigare.

<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>

Dessa positioneras absolute i varje hörn av webbläsaren med följande csskod:

#box1 {
 position: absolute;
 top: 0;
 left: 0;
 width: 200px;
 height: 200px;
 background: turquoise;
}
#box2 {
 position: absolute;
 top: 0;
 right: 0;
 width: 200px;
 height: 200px;
 background: tomato;
}
#box3 {
 position: absolute;
 bottom: 0;
 left: 0;
 width: 200px;
 height: 200px;
 background: gold;
}
#box4 {
 position: absolute;
 bottom: 0;
 right: 0;
 width: 200px;
 height: 200px;
 background: yellowgreen;
}
Se exempel 6

Genom att skala om webbläsarfönstret så blir det tydligt att se att boxarna "sitter fast" i hörnen. Blir webbläsarfönstret nog litet så att boxarna tar i varandra så kan man observera att de inte bryr sig om att de krockar, de kommer att överlappa varandra. Vilken som hamnar överst styrs av ordningen de har lästs in i html-dokumentet. Detta kan kontrolleras med hjälp av z-index något vi kommer att titta på strax.

Precis som relative så skapar absolute ett nytt koordinatsystem. För att exemplifiera detta så kan vi lägga de fyra boxarna inom en div vid namn #box5:

<div id="box5">
 <div id="box1"></div>
 <div id="box2"></div>
 <div id="box3"></div>
 <div id="box4"></div>
</div>

#box5 ger vi en bredd på 600px och en höjd på 600px, en ljusgrå bakgrundsfärg, centrerar den på skärmen samt ger den egenskapen relative:

#box5 {
 position: relative;
 width: 600px;
 height: 600px;
 margin: auto;
 background: lightgray;
}
Se exempel 7

Eftersom de färgade boxarna (#box1 - #box4) nu befinner sig inuti ett element som har position: relative så positioneras boxarna utifrån förälderns koordinatsystem. Man kan säga att elementet <body> har position: relative redan från början vilket gör att alla relativa och absoluta positioneringar kommer normalt sett att utgå från bodyns koordinatsystem. Men när man skapar egna element med relativ positionering så kommer alla barn till det elementet att förhålla sig till detta koordinatsystem istället för bodyns.

Experimentera och prova på egen hand

Ta koden som använts i exemplen här ovanför och experimentera med att sätta positioneringar på de olika div-elementen. Notera var dessa positioneringar utgår ifrån och vilka element som blir påverkade. Prova även negativa värden.

Vad händer när du positionerar absoluta element ovanför varandera? Vilket av dem ligger ovanpå och varför?

Vad händer om du bara sätter ett offset-värde (top, right, bottom eller left) på ett absolut positionerat element?

Prova att ändra i HTML-dokumentet för att se hur positioneringen påverkas av nästlade element.

Absolut positionering går att använda även när det gäller att skapa flytande layouter (anpassar sig efter fönstrets storlek) men det kan vara lite besvärligt och bör skapas med modernare metoder som t.ex. flexbox eller CSS grid vilket vi ska titta på senare.

I och med att vi definierar två eller alla fyra utav offset-egenskaperna och ingen bredd eller höjd så kan vi skapa en flytande layout. Nedan bygger vi ut föregående exempel med två boxar till:

<div id="box5">
 <div id="box1"></div>
 <div id="box2"></div>
 <div id="box3"></div>
 <div id="box4"></div>
</div>
<div id="box6">
 <div id="box7"></div>
</div>

Därefter ändrar vi koden för #box5 samt lägger till css för #box6 och #box7

#box5 {
 position: absolute;
 top: 0;
 left: 0;
 right: 40%;
 bottom: 0;
 background: lightgray;
}
#box6 {
 position: absolute;
 top: 0;
 left: 60%;
 right: 0;
 bottom: 0;
 background: tan;
}
#box7 {
 position: absolute;
 inset: 80px 50px 100px 80px;
 background: antiquewhite;
}
Se exempel 8

inset: i #box7 här ovan fungerar ungefär som padding: men för offset-positionering. Det innebär att man med hjälp av inset kan sätta top, right, bottom och left med en enda kodrad.

Position: fixed och Position: sticky

Fixed påminner om position: absolute, men den stora skillnaden är att den alltid utgår från webbläsarfönstret (viewport). Den sitter alltså fortfarande kvar exempelvis längst ner på sidan fast ni scrollar. Se nedanstående exempel så kommer det att bli tydligare. I det här fallet så innehåller dokumentet massor av text och #box1 är fixerad längst ner i webbläsarfönstret. HTML-koden i det här fallet är liknade första exemplet i positon: absolute, men med text inuti. CSS-koden ser ut som följande:

#box1 {
 position: fixed;
 bottom: 0;
 left: 0;
 right: 0;
 height: 100px;
 background: turquoise;
}
#box2, #box4 {
 position: relative;
 width: 200px;
 margin: auto;
 padding: 2em;
 background: rgba(255,99,71,0.80);
}
#box3 {
 position: sticky;
 width: auto;
 top: 0;
 padding: 2em;
 background: slategray;
}
#box4 {
 background: rgba(50,205,50,0.80);
}
Se exempel 9

När man scrollar på sidan så ser ni att det turkosa elementet stannar i botten av webbläsarfönstret. Genom att sätta både left: 0; och right: 0; så täcker vi hela bredden på fönstret. Fixed fungerar alltså precis som absolute när det kommer till hantering av offset-egenskaper och av den anledningen kan vi göra på det här sättet.

Det grå elementet som har position: sticky; kommer att behålla sin position i det normala flödet tills dess att den når top: 0; då övergår den till att bete sig som om den hade position: fixed;.

Experimentera och prova på egen hand

Det grå elementet, i exempel 9, har en bredd på auto vilket normalt sett ska täcka hela bredden, men i exemplet så kan man se att det är en liten bit kvar ut till kanterna, fundera på vad detta kan bero på och försök att fixa problemet så att en bredd på auto (eller 100vw eller 100%, vilket borde bli samma resultat) går hela vägen ut i kanten

Ta reda på vad som händer om man på sin sticky sätter top: 50px; eller bottom: 0;. Hur fungerar det?

Vad händer med en sticky som inte har någon offset-egenskap (top, right, bottom, left)?

Notera att både det turkosa och gråa elementet hamnar bakom övriga element då de har sitt "fixerade" värde. Vi ska strax återkomma till detta exempel och fixa det, men först ska vi prata lite om den sista typen av positionering.

Position: inherit

Mycket inom CSS beror på arv, det betyder att element kan ärva egenskaper som är satta på andra element. Till exempel så om man sätter color för att ändra textfärgen på ett element så kommer barn till detta element att få samma textfärg. Position är en egenskap som inte ärvs naturligt, alltså att den får samma egenskaper som sin förälder. Dock kan man tvinga fram detta för position och även för dess offset-egenskaper genom att skriva inherit. Nedanstående exempel innehåller en box vid namn #box2 som ligger inuti #box1:

#box1 {
 position: relative;
 left: 100px;
 width: 250px;
 height: 250px;
 background: turquoise;
}
#box2 {
 width: 100px;
 height: 100px;
 background: tomato;
}
Se exempel 10

Genom att lägga till position:inherit och left:inherit på #box2 kan vi se till att den ärver dessa egenskaper från dess förälder.

#box2 {
 position: inherit;
 left: inherit;
 width: 100px;
 height: 100px;
 background: tomato;
}
Se exempel 11

Nu ärver #box2 egenskaperna position och left från #box1 vilket i praktiken innebär att #box2 får position: relative; och left: 100px;

Experimentera och prova på egen hand

Undersök vad som händer med #box2 om ni ändrar värdena på #box1:s width- och left-värden.

Om vi inte ärver positionegenskapen, vad händer då, och varför?

Z-index

Egenskapen z-index är en egenskap som kontrollerar djupet av element i din webbsida. Lite som att tänka på ditt webbinnehåll som att de ligger i olika lager. Element med ett högre z-index visas ovanpå element med ett lägre z-index. En sak att komma ihåg är dock att z-index inte fungerar på element med position: static; vilket som vi lärt oss tidigare på den här sidan är grundformateringen för normala blockelement. därför är det viktigt att de element som man vill stapla (stacka) på varandra har antingen position: relative, absolute, fixed eller sticky.

En annan viktig sak att nämna är att varje gång du bestämmer ett z-index (förutom om du sätter z-index: auto;) så skapas vad som kallas för en ny staplingskontext (eng: stacking context). Denna påverkar bara syskon (siblings) till elementet som du vill stapla, vilket medför att du bara kan bestämma i vilke ordning element ska visas bland syskon, inte barn-element (child). Detta kan vara lite besvärligt att förklara så vi gör ett litet exempel:

<div id="box1"></div>
<div id="box2">
 <div id="box3"></div>
</div>

Till detta kopplar vi lite enkel CSS:

#box1 {
 position: absolute;
 top: 10px;
 left: 10px;
 width: 200px;
 height: 200px;
 background: turquoise;
}
#box2 {
 position: absolute;
 top: 30px;
 left: 30px;
 width: 200px;
 height: 200px;
 background: tomato;
}
#box3 {
 position: absolute;
 top: 20px;
 right: 5px;
 width: 100px;
 height: 100px;
 background: gold;
}
Se exempel 12

Detta ger oss grunden för att visa hur det normalt ser ut utan att vi laggt till z-index. Nu vill vi att #box1 ska ligga över #box2 så vi använder oss av z-index och lägger till följande:

#box1 {
 ...
 z-index: 3;
}
#box2 {
 ...
 z-index: 2;
}
#box3 {
 ...
 z-index: 5;
}
Se exempel 13

Som ni kan se i exemplet så ligger nu #box1 över #box2 och #box3. #box1 ligger ovanför #box3 än fast z-index på #box3 är större än för #box1. Detta beror på att den gula rutan (#box3) är ett barn (child) till den röda rutan och när jag skriver z-index: 5; för #box3 så skapas en ny staplingskontext (stacking context) för #box3 och dess syskon (den har inga i exemplet) och därför kan den inte påverka den staplingskontext som redan skapats av #box1.

Tänk också på att normalt sett så påverkas ordningen av i vilken ordning objekten lagts in i html-koden. Det kan ibland innebära att element där man inte satt ett z-index kan hamna ovanför element med höga z-index värden, men då vet du ni i alla fall vad det troligtvis beror på.

Experimentera och prova på egen hand

Gå tillbaka till exempel 9 och ändra koden med hjälp av z-index så att både fixed och sticky elementen ligger ovanför de scrollande elementen.

gör ett eget exempel med ett antal överlappande boxar och bestäm en ordning för hur de ska visas som inte har med vilken ordning de defineras i html-dokumentet att göra. Undersök sedan hur detta påverkas om du lägger till element som har position: static;

Kombinera och positionera element

Med hjälp av det du läst och lärt dig av positioneringar på den här sidan så kan du nu börja bygga upp egna block eller till och med designa hela sidor med olika positioneringar. Men för att skapa layout för hela sidor så finns det bättre verktyg för att hantera detta. Positionering är däremot väldigt effektivt att använda för att bygga upp delar av sidor som man sedan kanske vill repetera på flera ställen.

Experimentera och prova på egen hand

Titta på detta exempel. Här använder vi oss av relativa och absoluta positioneringar för att bygga upp block som ska repeteras på en butikssida.

Använd de kunskaper du lärt dig ocm positionering och skapa ett eget block som du kan kopiera med olika innehåll.


Har du läst det som stått på den här sidan och experimenterat med exemplen som jag visat så borde du nu ha en ganska bra förståelse över hur man positionerar element i och runt varandra. Det kan ibland vara ganska svårt att välja rätt positionering på sina element. Men genom att göra misstag så lär man sig lösningar, så skriv kod, lär dig av dina misstag och ha kul!