Chapter 1.7☕ 16 min read

Positioning & Layout Flow

Control exact element placement with relative, absolute, fixed, and sticky positioning. Master the art of precise layout control.

01Position Properties — The Five Types

The position property controls how an element is positioned in the document flow. Each type serves different layout purposes.

Value Description Use Case
static Default. Normal document flow. Offset properties don't work. Normal page content — 95% of elements are static
relative Positioned relative to its normal position. Still takes up space in flow. Slight offset adjustments, anchor for absolute children
absolute Removed from normal flow. Positioned relative to nearest positioned ancestor. Overlays, modals, tooltips, precise placement
fixed Positioned relative to viewport. Stays in place during scrolling. Navbars, chat widgets, sticky CTAs, back-to-top buttons
sticky Hybrid of relative and fixed. Sticks when reaching scroll threshold. Section headers, table headers, sidebars that snap
/* Static — default, normal flow */
.static-box { position: static; }

/* Relative — offset from normal position, keeps space */
.relative-box {
  position: relative;
  top: 20px;
  left: 30px;
}

/* Absolute — removed from flow, relative to positioned ancestor */
.absolute-box {
  position: absolute;
  top: 0;
  right: 0;
}

/* Fixed — relative to viewport, stays on scroll */
.fixed-header {
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 100;
}

/* Sticky — normal until threshold, then fixed */
.sticky-header {
  position: sticky;
  top: 0;
  background: white;
  z-index: 10;
}
02Offset Properties — Fine-tune Position

Once positioned, use top, right, bottom, left to fine-tune element placement. These work with relative, absolute, fixed, and sticky.

Property Effect
top: 20px Moves element down from top edge of containing block
right: 15px Moves element left from right edge of containing block
bottom: 10px Moves element up from bottom edge of containing block
left: 25px Moves element right from left edge of containing block
inset: 10px Shorthand for top, right, bottom, left (all sides)
top: 50%; left: 50%;
transform: translate(-50%, -50%)
Perfect centering — works for any element size
/* Perfect centering — works for any element size */
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1000;
}

/* Corner anchoring */
.badge {
  position: absolute;
  top: -10px;
  right: -10px;
  z-index: 1;
}

/* Full-screen overlay */
.overlay {
  position: fixed;
  inset: 0;                    /* top:0; right:0; bottom:0; left:0 */
  background: rgba(0,0,0,0.5);
  z-index: 999;
}
03Z-index with Positioning — Stacking Control

Z-index only works on positioned elements (not static). Controls which elements appear on top when they overlap.

Level Value Example
Emergency z-index: 9999 Critical UI — modals, overlays (use very sparingly)
High z-index: 100 Modals, popups, full-screen overlays
Medium z-index: 10 Dropdowns, tooltips, sticky headers
Low z-index: 1 Slight elevation — badges, decoration
Behind z-index: -1 Backgrounds, shadows behind content
Default z-index: auto Same as parent stacking context

Stacking Context: When you set z-index on a positioned element, it creates a new stacking context. Children with z-index can't appear above elements outside the parent's stacking context, no matter how high their z-index is. Every positioned element with a non-auto z-index creates a new stacking context.

04Fixed vs Sticky — Practical Use Cases

Understanding when to use fixed versus sticky positioning for common UI patterns.

Pattern Position Behavior
Fixed header position: fixed; top: 0; Always visible at top — navigation bars, top banners
Sticky header position: sticky; top: 0; Scrolls with content then sticks — section headers, table headers
Fixed CTA position: fixed; bottom: 0; Always visible at bottom — chat widgets, call-to-action bars
Sticky sidebar position: sticky; top: 80px; Scrolls within parent then sticks — side navigation, table of contents
/* Fixed navbar — always at top */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 60px;
  background: #1e293b;
  color: white;
  z-index: 100;
}

/* Sticky section header — sticks on scroll */
.section-header {
  position: sticky;
  top: 60px;                 /* Below the fixed navbar */
  background: #fff7ed;
  padding: 16px;
  z-index: 50;
  border-bottom: 2px solid #f97316;
}

/* Fixed chat widget — bottom right */
.chat-widget {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 1000;
}

/* Sticky sidebar */
.sidebar {
  position: sticky;
  top: 80px;
  height: fit-content;
}
05Exercise — Positioning Playground

Write CSS below and experiment with all position types. See how each affects layout.

1

Open VS Code. Create positioning-practice.html.

2

Use the starter code and experiment:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Positioning Practice</title>
  <style>
    .container { position: relative; height: 300px; background: #f3f4f6; padding: 20px; border-radius: 8px; margin-bottom: 20px; }
    .static-box { position: static; background: #f97316; color: white; padding: 15px; margin: 10px 0; }
    .relative-box { position: relative; background: #3b82f6; color: white; padding: 15px; top: 10px; left: 10px; }
    .absolute-box { position: absolute; background: #10b981; color: white; padding: 15px; top: 20px; right: 20px; }
    .sticky-box { position: sticky; top: 10px; background: #ec4899; color: white; padding: 15px; z-index: 10; }
  </style>
</head>
<body>
  <div class="sticky-box">📌 I'm sticky — scroll to see me stick!</div>
  <div class="container">
    <div class="static-box">Static — normal flow</div>
    <div class="relative-box">Relative — offset from normal</div>
    <div class="absolute-box">Absolute — in top-right corner</div>
  </div>
  <p style="margin-top:800px">Scroll down to see sticky behavior!</p>
</body>
</html>

Try these experiments:

Done — Key Points:

  • static = default (normal flow). relative = offset but keeps space. absolute = out of flow.
  • fixed = relative to viewport (scroll ignores it). sticky = scrolls then sticks on threshold.
  • ✅ Offset properties (top, right, bottom, left) only work on positioned elements — not static.
  • ✅ Perfect centering: top: 50%; left: 50%; transform: translate(-50%, -50%)
  • ✅ Z-index only works on positioned elements. Higher value = on top.
  • ✅ Sticky positioning: relative until scroll threshold, then fixed. Great for section headers.
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase