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;
}
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 utstatic
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;
}
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;
}
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>
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;
}
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
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;
}
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;
}
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.
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;
}
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);
}
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;
.
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;
}
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;
}
Nu ärver #box2 egenskaperna position och left från #box1 vilket i praktiken innebär att #box2 får position: relative;
och left: 100px;
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;
}
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;
}
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å.
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.
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!