Positioning
position property accepts five values: static, relative, absolute, fixed, and sticky.
Most elements follow the normal document flow — block elements stack vertically, inline elements sit side by side. Positioning lets you step outside that flow and place elements exactly where you need them.
static (default)
Every element is position: static by default. It follows normal document flow and is not affected by top, right, bottom, or left.
.box {
position: static; /* default — no need to write this */
}
relative
The element stays in normal flow but can be nudged using offset properties. The space it originally occupied is preserved.
.nudged {
position: relative;
top: 10px; /* move down 10px from its normal position */
left: 20px; /* move right 20px */
}
position: relative is also used to create a positioning context for absolutely positioned children.
absolute
The element is removed from normal flow and positioned relative to its nearest ancestor that has a non-static position. If no such ancestor exists, it positions relative to the page.
.card {
position: relative; /* positioning context */
}
.badge {
position: absolute;
top: 12px;
right: 12px;
}
The most common pattern: set position: relative on a parent and position: absolute on a child to pin the child to a corner or edge of the parent.
fixed
The element is removed from normal flow and positioned relative to the viewport. It stays in place when the page scrolls — ideal for sticky headers, floating buttons, and overlays.
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
background: white;
border-bottom: 1px solid #e5e7eb;
}
sticky
A hybrid of relative and fixed. The element scrolls normally until it hits a threshold, then sticks in place.
.section-header {
position: sticky;
top: 0; /* sticks when it reaches the top of the viewport */
background: white;
z-index: 10;
}
z-index
When positioned elements overlap, z-index controls which one appears on top. Higher values sit in front of lower values.
.modal {
position: fixed;
z-index: 1000;
}
.overlay {
position: fixed;
z-index: 999;
}
.navbar {
position: sticky;
z-index: 100;
}
z-index only works on elements with a position other than static.
Centering with absolute positioning
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
This is a classic trick — offset by 50% then pull back by half the element's own size using transform.
Have anything to say about this lesson?
Your feedback helps improve these tutorials. If something was confusing or missing, let us know.