CSS Tutorial
CSS Position
The position property controls how an element is placed on the page and whether the offset properties top, right, bottom, and left have any effect. Understanding its five values unlocks overlays, badges, sticky headers, and precise placement.
The position property
By default every element is positioned static, meaning it follows the normal document flow. Changing position lets you shift an element relative to its normal spot, relative to an ancestor, or relative to the browser window. The offset properties (top, right, bottom, left) only take effect when position is set to something other than static.
The five position values
| Value | Positioned relative to | Leaves a gap? |
|---|---|---|
| static | Normal flow (default) | n/a — offsets ignored |
| relative | Its own normal position | Yes, original space kept |
| absolute | Nearest positioned ancestor | No, removed from flow |
| fixed | The browser viewport | No, removed from flow |
| sticky | Scroll position within its container | Yes, toggles between relative and fixed |
relative vs absolute
In the demo, the container is position: relative so it becomes the reference for its absolutely positioned child. The blue badge is pushed 10px from the top-right corner of the container, and the green box is nudged from its own original position while leaving its gap behind.
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; padding: 20px; }
.container {
position: relative;
height: 150px;
background: #e2e8f0;
padding: 12px;
}
.badge {
position: absolute;
top: 10px;
right: 10px;
background: #2563eb;
color: white;
padding: 6px 10px;
border-radius: 6px;
}
.moved {
position: relative;
top: 20px;
left: 30px;
background: #16a34a;
color: white;
padding: 8px;
width: 140px;
}
</style>
</head>
<body>
<div class="container">
<span class="badge">absolute</span>
<div class="moved">relative: nudged 20px down, 30px right</div>
</div>
</body>
</html>fixed and sticky
A fixed element stays glued to the viewport as you scroll. A sticky element scrolls normally until it reaches a set offset, then locks in place. Scroll the demo below to see the sticky header cling to the top.
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; margin: 0; }
.header {
position: sticky;
top: 0;
background: #7c3aed;
color: white;
padding: 14px;
font-weight: bold;
}
.tall { height: 600px; padding: 16px; background: #f1f5f9; }
</style>
</head>
<body>
<div class="header">Sticky header — scroll down!</div>
<div class="tall">
<p>Scroll this box. The purple header stays pinned to the top.</p>
</div>
</body>
</html>A common pattern: set the parent to position: relative and the child to position: absolute so the child is placed relative to that parent instead of the whole page.
Key points
- Offsets (top/right/bottom/left) do nothing on position: static.
- relative nudges an element from its normal spot but keeps its original space.
- absolute removes the element from flow and positions it against the nearest positioned ancestor.
- fixed pins to the viewport; sticky switches between relative and fixed as you scroll.
