The position Property
position controls how an element is placed in the document, and works together with top, right, bottom, and left to offset it.
Position Values
| Value | Behavior |
|---|---|
| static | Default. Normal document flow; top/left/etc. have no effect |
| relative | Stays in normal flow, but can be offset from its normal position |
| absolute | Removed from flow, positioned relative to nearest positioned ancestor |
| fixed | Removed from flow, positioned relative to the viewport, stays put when scrolling |
| sticky | Acts relative until a scroll threshold, then sticks like fixed |
relative Positioning
<style>
.shifted {
position: relative;
top: 10px;
left: 20px;
background: #ffeaa7;
display: inline-block;
padding: 10px;
}
</style>
<div class="shifted">Shifted 10px down, 20px right from its normal spot</div>absolute Positioning
An absolutely positioned element is removed from normal flow and positioned relative to its nearest ancestor that has a position other than static — commonly used for badges, tooltips, and dropdown menus.
absolute Inside relative
<style>
.card {
position: relative;
width: 200px;
height: 100px;
background: #eef4fb;
border: 1px solid steelblue;
}
.badge {
position: absolute;
top: 8px;
right: 8px;
background: crimson;
color: white;
padding: 2px 8px;
border-radius: 999px;
font-size: 12px;
}
</style>
<div class="card">
<span class="badge">New</span>
Card content
</div>fixed and sticky
fixed keeps an element pinned to the viewport regardless of scrolling — common for sticky headers or "back to top" buttons. sticky behaves like relative until the page scrolls past a threshold, then behaves like fixed within its parent.
sticky Header
<style>
.scroll-area {
height: 150px;
overflow-y: auto;
border: 1px solid #ccc;
}
.sticky-header {
position: sticky;
top: 0;
background: steelblue;
color: white;
padding: 8px;
}
</style>
<div class="scroll-area">
<div class="sticky-header">Sticky Header</div>
<p style="padding: 0 8px;">Scroll inside this box...</p>
<p style="padding: 0 8px;">More content...</p>
<p style="padding: 0 8px;">Even more content...</p>
<p style="padding: 0 8px;">Keep scrolling...</p>
</div>absolute Needs a Positioned Ancestor
If no ancestor has position: relative, absolute, or fixed, an absolutely positioned element is placed relative to the entire page — a very common source of unexpected layout bugs.
Best Practice
Always pair position: absolute with a nearby position: relative parent that acts as its containing box, so the offset behaves predictably.