Positioning & Z-index
Place elements exactly where you want — overlapping, pinned to the corner, or stuck while scrolling.
What you will learn
- Use static, relative, absolute, fixed and sticky
- Offset with top/right/bottom/left
- Control stacking with z-index
The five position values
| Value | Behaviour |
|---|---|
static | Default — normal flow |
relative | Nudge from its normal spot; anchor for absolute children |
absolute | Positioned relative to the nearest positioned ancestor |
fixed | Pinned to the screen, stays while scrolling |
sticky | Normal until you scroll past, then sticks |
<style>
.card { position: relative; background:#e0e7ff; padding:24px; border-radius:12px; }
.badge {
position: absolute; top: 10px; right: 10px;
background:#ef4444; color:#fff; padding:4px 10px; border-radius:999px; font-size:12px;
}
</style>
<div class="card">
<span class="badge">NEW</span>
A card with an absolutely positioned badge in the corner.
</div>This is the classic “badge on a card” pattern, and it relies on two position values working together. The card has position: relative, which does not move it but turns it into the anchor for any absolutely-positioned children. The badge has position: absolute with top: 10px; right: 10px, so it pins itself 10px from the top-right of the card (its anchor), floating in the corner without disturbing the card text. Remove position: relative from the card and the badge would jump to the corner of the whole page instead.
<style>
.scroller { height: 130px; overflow: auto; border:1px solid #e6e8f0; border-radius:8px; }
.stick { position: sticky; top: 0; background:#4338ca; color:#fff; padding:10px; }
.scroller p { padding: 0 12px; }
</style>
<div class="scroller">
<div class="stick">I stick to the top — scroll the box!</div>
<p>Line 1</p><p>Line 2</p><p>Line 3</p><p>Line 4</p><p>Line 5</p><p>Line 6</p>
</div>Scroll inside the box and watch the blue bar. The bar uses position: sticky with top: 0, which means: behave normally until you scroll it to the top edge, then stick there while the rest scrolls underneath. This is exactly how a header that “follows you down the page” works. (overflow: auto on the container is what makes the box scrollable in the first place.)
z-index: who sits on top
When positioned elements overlap, z-index decides the stacking order — a higher number sits on top.
<style>
.stack { position: relative; height: 90px; }
.sq { position: absolute; width: 60px; height: 60px; border-radius: 8px; color:#fff; padding:6px; }
.back { background:#06b6d4; left: 0; top: 0; z-index: 1; }
.front { background:#ef4444; left: 30px; top: 20px; z-index: 2; }
</style>
<div class="stack">
<div class="sq back">z-index 1</div>
<div class="sq front">z-index 2</div>
</div>Both squares are absolutely positioned so they overlap. The red one sits on top of the cyan one purely because it has a higher z-index (2 beats 1). Swap the numbers and the cyan square would come forward instead. z-index only works on positioned elements (anything that is not static), which is why both squares are absolute here.
Tip: For absolute positioning to work inside a box, give the parent position: relative. The absolute child then positions against that parent, not the whole page.
Q. Which position value keeps an element pinned to the screen while you scroll?
✍️ Practice
- Put a “SALE” badge in the corner of a card using
relative+absolute. - Make a header
stickyso it stays at the top while scrolling.
🏠 Homework
- Add a sticky navigation bar and a corner badge to one of your projects.