CSS position property defines how an element is positioned on the page:
/* Main position values */
.static { position: static; }
.relative { position: relative; top: 10px; }
.absolute { position: absolute; top: 0; left: 0; }
.fixed { position: fixed; top: 0; right: 0; }
.sticky { position: sticky; top: 20px; }The position property is like a coordinate system for elements! It defines how an element will be placed on the page and what it will be positioned relative to. 🗺️
Element stays in normal document flow:
.static-element {
position: static;
/* top, right, bottom, left are ignored */
}<div class="static-element">Normal element</div>Features:
top, right, bottom, left don’t workPositioning relative to its normal place:
.relative-element {
position: relative;
top: 20px;
left: 30px;
background: lightblue;
}<div>Element before</div>
<div class="relative-element">Shifted element</div>
<div>Element after</div>Features:
Positioning relative to nearest positioned parent:
.container {
position: relative;
width: 300px;
height: 200px;
border: 2px solid #333;
}
.absolute-element {
position: absolute;
top: 10px;
right: 10px;
width: 100px;
height: 50px;
background: coral;
}<div class="container">
<div class="absolute-element">Absolute</div>
</div>Features:
position ≠ static<html>Positioning relative to browser window:
.fixed-header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 60px;
background: #333;
color: white;
z-index: 1000;
}
.fixed-button {
position: fixed;
bottom: 20px;
right: 20px;
width: 60px;
height: 60px;
background: #007bff;
border-radius: 50%;
}<header class="fixed-header">Fixed header</header>
<button class="fixed-button">↑</button>Features:
Hybrid behavior of relative + fixed:
.sticky-nav {
position: sticky;
top: 0;
background: white;
border-bottom: 1px solid #ddd;
z-index: 100;
}
.sticky-sidebar {
position: sticky;
top: 20px;
height: fit-content;
}<nav class="sticky-nav">Sticky navigation</nav>
<aside class="sticky-sidebar">Sidebar</aside>Features:
relative until reaching thresholdfixed when scrolling.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
.modal {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border-radius: 8px;
}.tooltip-container {
position: relative;
display: inline-block;
}
.tooltip {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: black;
color: white;
padding: 5px 10px;
border-radius: 4px;
opacity: 0;
transition: opacity 0.3s;
}
.tooltip-container:hover .tooltip {
opacity: 1;
}.card {
position: relative;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
.badge {
position: absolute;
top: -10px;
right: -10px;
background: red;
color: white;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
}Elements with position ≠ static create positioning context:
.parent {
position: relative; /* Creates context */
}
.child {
position: absolute;
top: 0; /* Relative to .parent */
left: 0;
}The z-index property only works with positioned elements:
.layer-1 {
position: relative;
z-index: 1;
}
.layer-2 {
position: absolute;
z-index: 2; /* Above layer-1 */
}
.layer-3 {
position: fixed;
z-index: 999; /* Topmost */
}| Value | Document Flow | Relative To | Scrolling |
|---|---|---|---|
static | ✅ Stays | — | Scrolls |
relative | ✅ Stays | Its place | Scrolls |
absolute | ❌ Removed | Parent | Scrolls |
fixed | ❌ Removed | Viewport | Doesn’t scroll |
sticky | ✅ Stays* | Parent | Conditional |
❌ Wrong:
.element {
position: static;
top: 10px; /* Doesn't work */
}✅ Correct:
.element {
position: relative;
top: 10px;
}The position property is fundamental for creating complex layouts:
Proper use of positioning helps create intuitive and functional interfaces! 🎨