The ability to position elements on a page is must-have for every web developer. And still, I see even experienced developers often times struggle with this a bit or google instantly. But if you take your time and get this right, you will be a CSS-positioning ninja βοΈ by the end of this post.
Video tutorial
If you prefer to watch it in a video format instead I created a tutorial on my YouTube channel, where I explain this on a living example:
The position CSS property
The position
property tells the browser how an element should be positioned on the page. By default the value of position is static
, but we can modify it to be any of the following values: relative
, absolute
, fixed
, sticky
. In this post I will go over each of them.
The base example
We will use a simple HTML markup which is really simple for better understanding. It contains a container div, and 3 child divs, that we will position throughout the examples.
I also added different colors to these child divs, so it will be easier to see the difference.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="./styles.css" />
<title>CSS positions</title>
<style>
.container {
background-color: lightblue;
padding: 20px;
}
.container > div {
padding: 15px;
}
.container span {
margin-bottom: 20px;
}
.first {
background-color: lightgreen;
}
.second {
background-color: lightcoral;
}
.third {
background-color: lightgoldenrodyellow;
}
</style>
</head>
<body>
<div class="container">
<span>Container</span>
<div class="first">First</div>
<div class="second">Second</div>
<div class="third">Third</div>
</div>
</body>
</html>
βΉοΈ If you want to play around with the code, feel free to use this CodeSandbox link.
Static
This is the default value of the position property. If the position of an element is static, the element will render in order, based on the position of it in the original document flow.
Relative
If we set the position of an element to relative, it will appear in the document as it would by default using static. The trick is that by setting position relative, we gain access to the following CSS properties: top
, left
, right
, bottom
. With these we can add an offset to the specific direction. So for example if we set left: 20px
. The element will be placed 20 pixel to the right. If we would have provided -20px it would push the content to the left with 20px.
Make the following changes:
.second {
background-color: lightcoral;
position: relative;
left: 20px;
}
Fixed
With fixed positioning we also have access to top
, left
, right
, bottom
properties. In this case the element is positioned relative to the browser window's viewport.
So if we set top 70px and left 20px on a fixed positioned element it will appear 70 pixels from the top of the viewport and 20px from the left edge of the viewport. Fixed positioning also removes the document from the normal document flow.
Modify the CSS:
.second {
background-color: lightcoral;
position: fixed;
left: 20px;
top: 70px;
}
Absolute
Absolute positioning is the one which can trick developers. It is working like the fixed positioning, but it is not positioned relatively to the viewport, but instead it is positioned based on the closest positioned element (which has position other than static
). If there are no positioned parents it will be positioned relative to the viewport (Same result as it would be with fixed
).
Make these changes to the CSS:
.second {
background-color: lightcoral;
position: absolute;
left: 20px;
top: 70px;
}
And we get the same result as with position fixed
:
If we add a position value to a parent, in this case we will add it to the container div, the absolutely positioned child will be positioned relatively to that. We often use relative position for the parent as it won't remove it from the standard document flow, and the parent will be placed in the site where it would have been without position: relative
.
Add position relative to the container:
.container {
background-color: lightblue;
padding: 20px;
position: relative;
}
Sticky
Using sticky
will position our element based on the user's scroll position. It toggles between position relative
and fixed
. We can provide the offsets using top
, left
, right
, bottom
. Until the specified offsets are met the element acts like a relatively psoitioned element, but when the scroll position is greater than the offset it "swithces" to position fixed and be positioned relatively to the viewport. It stays fixed until the user scrolls back to the opposite direction and the distance will be less than the offset, then it goes back to act like a relative positioned element again.
To be able to scroll add 3 times the height of the viewport to our container:
.container {
background-color: lightblue;
padding: 20px;
height: 300vh;
}
Add the sticky position and the top offset to the element:
.second {
background-color: lightcoral;
position: sticky;
top: 0;
}
Now, by default the page looks like as we haven't done anything. But if we scroll down, below the second div, it sticks to the top directly (because of the 0px offset, add more if you need), and scrolls with the content in that fixed position. If we scroll back to the top it will be placed in its original position.
And this is everything you'll ever need to position elements on a webpage like a pro.
If you want to learn more, consider following me on other platforms too π.
Where you can learn more from me?
I create education content covering web-development on several platforms, feel free to π check them out.
I also create a newsletter where I share the week's or 2 week's educational content that I created. No bullπ© just educational content.
π Links:
- πΊ Support free education and buy me a beer
- π¬ Join our community on Discord
- π§ Newsletter Subscribe here
- π₯ YouTube Javascript Academy
- π¦ Twitter: @dev_adamnagy
- π· Instagram @javascriptacademy
Top comments (5)
Thank you for this. Please why did the second div's width get smaller when you gave it a position of absolute?
Hi!
Because it removes the element from the standard document flow.
In a normal document flow if not overriden by CSS a div takes 100% of its parentβs container.
After the element is positioned absolutely and removed from the document flow, it takes a min eidth which is defined by the browser. If the content is larger than this width the it will take the required place to display its content.
So we have to specify the width of the absolutely positioned element manually.
Oh wow.
Cool, thanks a lot!
Nice article. Also a relevant quote from Devopedia: "We can also take out an element from its normal flow using CSS properties position and float." -- devopedia.org/css-design-patterns
Explained simply