The position property in CSS is one of the most confusing for beginners. Understanding the difference between relative, absolute, fixed, and sticky is very important because each behaves quite differently. This article explains each value with real examples so it's easy to understand.
The Values of the Position Property
CSS has five values for the position property:
static— the default value, follows the normal document flowrelative— shifted relative to its normal positionabsolute— positioned relative to a positioned ancestorfixed— positioned relative to the viewport (browser window)sticky— a combination of relative and fixed
The top, right, bottom, and left properties are used together with position (except static) to set the element's offset.
position: static (Default)
This is the default value of every element. The element follows the normal HTML document flow and is not affected by top, right, bottom, or left.
.element {
position: static; /* default, no need to write it */
}
position: relative
The element stays in the normal document flow, but can be shifted from its original position. The space the element occupies in the normal flow is preserved (not lost).
.box-relative {
position: relative;
top: 20px; /* shift 20px down from the original position */
left: 30px; /* shift 30px right from the original position */
background: #dbeafe;
padding: 16px;
}
Important: position: relative also serves as an anchor for child elements with position: absolute.
position: absolute
The element is removed from the normal document flow (other elements don't account for its presence). Its position is determined relative to the nearest ancestor that has a position other than static. If there is none, it will be relative to <html>.
<div class="parent">
<div class="child-absolute">Badge</div>
<p>This is the parent content</p>
</div>
<style>
.parent {
position: relative; /* anchor for the absolute element */
background: #f0fdf4;
padding: 20px;
width: 200px;
}
.child-absolute {
position: absolute;
top: 8px;
right: 8px;
background: #ef4444;
color: white;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
}
</style>
This example is a very common pattern: placing a badge/label in the corner of a card.
position: fixed
The element is positioned relative to the viewport (browser window), not the document. The element stays in the same place even when the page is scrolled. It's removed from the normal document flow.
.navbar-fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #1e293b;
color: white;
padding: 16px 32px;
z-index: 100;
}
/* Add padding-top to the body so content isn't hidden by the navbar */
body {
padding-top: 60px;
}
Fixed Example: A Scroll to Top Button
<button class="btn-top" onclick="window.scrollTo(0,0)">⇧ Top</button>
<style>
.btn-top {
position: fixed;
bottom: 24px;
right: 24px;
background: #3b82f6;
color: white;
border: none;
border-radius: 50%;
width: 48px;
height: 48px;
font-size: 20px;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
</style>
position: sticky
The element behaves like relative until it reaches a certain position while scrolling, then "sticks" like fixed. Very useful for table headers or navigation that sticks while scrolling.
.table-header {
position: sticky;
top: 0;
background: #1e293b;
color: white;
z-index: 10;
}
.sticky-sidebar {
position: sticky;
top: 80px; /* sticks 80px from the top of the viewport */
align-self: flex-start;
}
Comparison Summary
- static — normal position, can't be shifted with top/left/right/bottom
- relative — shifted from its original position, stays in the normal flow, can be an anchor for absolute
- absolute — out of the normal flow, positioned relative to a positioned ancestor
- fixed — out of the normal flow, positioned relative to the viewport, doesn't move when scrolling
- sticky — a mix of relative and fixed, sticks when scrolled past a certain point
The z-index Property
When an element is positioned (not static), you can use z-index to control which element's stacking appears on top:
.modal {
position: fixed;
z-index: 1000;
}
.overlay {
position: fixed;
z-index: 999;
}
.navbar {
position: fixed;
z-index: 100;
}
Conclusion
Understanding the CSS position property is the key to mastering web layout. Remember the formula: use relative as an anchor, absolute for elements floating inside a container, fixed for elements always visible on the screen, and sticky for elements that stick while scrolling. By understanding these differences, you can solve almost any positioning challenge in web development.