CSS Positioning
Hey,
This is my first article and I thought, why not talk about a topic that is both simple and complex when not properly understood. As you'll have read, we'll discuss positioning in CSS, and that immediately means the position: ...; property — so yes, this article will focus solely on this little property.
Without further ado let's get started. For this I created an index.html and a style.css file with a few elements.
In the HTML we have a div containing a header that contains a button, followed by a paragraph of about 2000 words...
<body>
<div class="container">
<header class="header">
<button>Click me !</button>
</header>
</div>
<p>lorem ...</p>
</body>
And in the CSS we have a small reset and a bit of color :)
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
height: 500px;
background: green;
}
.header {
background: blue;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem 0;
}
This gives us something like this (yes it's very ugly, I know):
The first thing to remember is that in CSS the position property can take 5 values:
position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;
We're going to go step by step and explore each one — don't worry!
position: static;
This is the easiest value to understand because, in fact, all the elements we create have this value by default. So this is the value our created elements (div, header, ul, p...) currently have.
position: relative;
OK... here it gets a bit weird, because if we set our header to position: relative; like this:
.header{
position: relative;
...
}
We see that nothing happens — the page stays intact, and the same goes for other elements. But then we wonder "WHY EVEN CREATE THIS POSITIONING IF IT'S THE SAME AS STATIC???" — well, they aren't the same, because this positioning and the next 3 we'll see give access to 4 additional properties that allow us to move our element:
top:;
left:;
bottom:;
right:;
Which mean respectively: top - left - bottom - right. This simply means we can now move our header with these properties:
.header {
position: relative;
top: 100px;
left: 50px;
...
}
You can see how our header moved. But position: relative isn't just for that — it'll be very useful when we talk about absolute positioning.
So we can say that if the
top - left - bottom - rightproperties are not used, thenstaticandrelativehave ALMOST the same role; as I said, it'll be useful withposition: absolute. ***
position: absolute;
This is where it gets a bit more complex. First, we'll remove the code we added to the header (only from the previous section) and add some text to our header (in the HTML).
...
<header class="header">
<p>Hello, I'm LN</p>
<button>Click me !</button>
</header>
...
Now we put position: absolute; on our button, like this:
... button {
position: absolute;
}
And it's complete chaos — our button moved in a strange way and is now overlapping our text. We wonder what really happened.
When an element is
position: absolute;(and evenrelative) it leaves the screen flow, but not the same way.
This image explains the phenomenon that just happened. Our element left the screen flow while 'removing' its place, which makes it floating. With relative it does leave the flow, but its place is preserved — that's why if we used relative instead of absolute on our button, nothing would change visually.
So our button left the screen flow, but that's not all. If you haven't forgotten, the position property gives access to 4 new properties — let's try something:
... button {
position: absolute;
bottom: 0;
}
Look at the bottom of your screen and you'll see your button:
And again we ask ourselves: "What just happened?" and I'll answer "It's magic! hahaha" — kidding, of course. As its name indicates, it's an absolute positioning, so it must position relative to something — and in this case it positions relative to our window (note: I didn't say body, but window). That's why it's at the bottom of our window and not at the bottom of our body (which is even further down — at the end of our paragraph). So how do we position our element relative to a specific element of our choosing? That's where position: relative; comes back into play. But first, here's exactly what position: absolute; does: > When an element is position: absolute;, it first looks to see if its parent is position: relative/absolute. If not, it moves up to its grandparent, then great-grandparent... and if it doesn't find any element in relative/absolute, it'll position relative to the window. This means that if it does find an element in relative/absolute, it'll position relative to that one.
I SAID
ABSOLUTEORRELATIVE
So in our case, if we want to position our button at the bottom of our green div, we just need to set it to relative:
.container {
position: relative;
height: 500px;
background: green;
}
And we're done :)
The last thing about absolute positioning (yes, that's already a lot) is: it doesn't only leave the screen flow but it also loses its dimensions (width, height). We didn't notice it because we just had a small button in absolute. So let's set our header to absolute:
.header{
position: absolute;
...
}
We notice several things: - The button no longer positions relative to the green div but to our header — and as I said (when an element is absolute it first looks if its parent is relative/absolute to position relative to it, before going to the parent of its parent and so on). - Our header lost its dimensions :( — but that's a consequence of this positioning, and it's easily fixable, in two ways even:
.header {
position: absolute;
width: 100%;
}
OR .header {
position: absolute;
left: 0;
right: 0;
}
> In the first case we tell the element to take 100% of available size, and in the second we ask it to go right (right: 0;) and also left (left: 0;), which makes it stretch — intuitive, isn't it? :)
I think we've covered this positioning. It's OK if you don't understand at first — with a bit of practice you'll see more clearly.
position: fixed;
For this section we'll go back to the CSS we had at the beginning of the article:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
height: 500px;
background: green;
}
.header {
position: relative;
background: blue;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 0;
}
Now we'll add this positioning to our button:
button {
position: fixed;
}
At first glance, the behavior is the same as position: absolute — it left the screen flow and positions relative to the header which is relative. But we're wrong. Try scrolling your screen and you'll notice something: the button stays at the top of the screen, it stays FIXED, and that's where I'll tell you that:
When an element is
position: fixed, it ALWAYS positions relative to our window while staying fixed at the place assigned to it (with: left - top - bottom - right). And it also leaves the screen flow while removing its position (likeposition: absolute;).
Remember well that when it's
absoluteit positions relative to the window but if we scroll, it keeps its positioning, which means the element will scroll too. But when it'sfixedit positions relative to the window and when we scroll, it updates its reference point so that it's always positioned relative to the current window (whereas inabsoluteit's just relative to the first window we see).
This positioning is mostly used for fixed navbars seen on some sites, but also for
overlayswhen creating modal boxes.
There's not much more to say about this positioning. We'll just update our code a bit, which will help us for the next part. So in CSS we should have:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
height: 500px;
background: green;
}
.header {
position: fixed;
left: 0;
right: 0;
background: blue;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 0;
}
And if you scroll all the way down, the header stays fixed:
position: sticky;
This is the positioning I find quite fun :) — you just need to understand:
When an element is
position: sticky;, it behaves likeposition: fixed;but only when it's still within its parent element.
Let me rephrase with our example:
If I set our header to
sticky, and I scroll, my header will be fixed only as long as my green div is still visible. So when my green div disappears, the header will leave with it.
If it's still not clear, let's practice — in our CSS, change the header positioning:
.header {
position: sticky;
...
}
And if you try, you'll see what I just said doesn't work — it actually feels more like position: static;. Well, that's not wrong, our header is missing one last property: top: 0; to tell it to always stay at the top. So we should have:
.header {
position: sticky;
top: 0;
left: 0;
right: 0;
background: blue;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 0;
}
And now you can test it and admire the beauty for yourself :) That's all for this positioning.
position: inherit;
It's true I said there were just 5 values — I lied a little :/ We also have this one, but it just means:
I take the same positioning as my parent element. So if my parent is absolute, I'm also absolute.
We've reached the end of this article and I hope it allowed you to learn more about this CSS property. If so, feel free to share on your networks and ask your questions if you didn't understand a particular point. So, see you in the next article, ciao! It was LN 👋
- Next article: Flexbox part 1
If you have feedback or questions,
feel free to reach out on Twitter (X) or by email.