WebDev Story

WebDev Story: CSS Positioning

position, offset, stacking, overflow, sticky

12.0 The Position Property

By default every element participates in normal flow: block elements stack vertically, inline elements run horizontally. The position property lets an element step outside that flow and be placed precisely on the page.
Position values
Value Behavior
static Default. Element stays in normal flow. Offset properties (top, left, …) have no effect. Not a positioned element.
relative Stays in normal flow (space is reserved). Offset properties shift the element visually from that reserved position. Creates a containing block for absolute descendants.
absolute Removed from normal flow (no reserved space). Placed relative to its nearest positioned ancestor (any value other than static), or to the initial containing block if none exists.
fixed Removed from normal flow. Placed relative to the viewport; stays in place during scroll. Used for persistent headers, toolbars, and overlays.
sticky Hybrid: acts as relative until the element's scroll position reaches a threshold, then behaves like fixed within its scroll container. Requires at least one offset property.
/* element scrolls with the page until it reaches the top, then sticks */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
}

12.1 Offset Properties

top, right, bottom, and left set the distance between the element's edge and the corresponding edge of its containing block (or viewport for fixed). They have no effect on static elements.
/* center an absolutely-positioned element in its container */
.overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
The inset shorthand sets all four offsets at once, following the same top / right / bottom / left order as margin:
/* fill the containing block completely */
.backdrop {
  position: absolute;
  inset: 0;          /* top:0; right:0; bottom:0; left:0 */
}

12.2 The Containing Block

Percentage dimensions, offset properties, and absolute placement all resolve against an element's containing block. The rules differ by position value:
  • static / relative / sticky — containing block is the content area of the nearest block ancestor.
  • absolute — containing block is the padding area of the nearest ancestor whose position is not static.
  • fixed — containing block is the viewport (or the nearest ancestor with a transform, perspective, or filter property, which creates a new containing block).
The most common pattern: give a parent position: relative to anchor absolutely-positioned children inside it, without moving the parent itself.
.card {
  position: relative;   /* containing block for .badge */
}
.card .badge {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;        /* top-right corner of .card, not the page */
}

12.3 Stacking Context and z-index

By default the browser paints elements in document order: later elements appear on top of earlier ones. z-index overrides this order, but only for positioned elements (any value except static). Higher z-index values paint on top.
.modal        { position: fixed; z-index: 1000; }
.modal-overlay{ position: fixed; z-index: 999;  }
.tooltip      { position: absolute; z-index: 500; }

12.3.1 What Creates a Stacking Context

A stacking context is an independent layer that groups descendants for painting. Children of one stacking context are painted together and cannot interleave with siblings from another context, regardless of their z-index.
Properties that create a new stacking context
Property / Condition Notes
Root element (<html>)The root stacking context; all others nest within it.
positionstatic + z-indexautoThe most common case.
opacity < 1Even without explicit z-index.
transformnoneIncludes translate, rotate, scale, etc.
filternoneAlso affects fixed descendants (they become relative to this element).
will-change with a compositing propertye.g., will-change: transform.
isolation: isolateExplicit way to create a stacking context without other side effects.
contain: layout or paint or strictCSS Containment creates a stacking context.
A common gotcha: a tooltip or dropdown appears below a sibling even though it has a high z-index. This usually means its ancestor creates a stacking context with a lower z-index than the sibling. The fix is isolation: isolate on the problematic ancestor, or restructuring the DOM.

12.4 Overflow

When content is larger than its box, overflow controls what happens to the excess. Setting overflow to anything other than visible also creates a new block formatting context, which contains floats and prevents margin collapse.
Overflow values
Value Behavior
visibleDefault. Content renders outside the box; no clipping or scrollbar.
hiddenClips content at the box edge. No scrollbar. Use for masking effects.
scrollAlways shows scrollbars (even when content fits). Clips overflow.
autoShows scrollbars only when needed. Preferred for scrollable containers.
clipLike hidden but does not create a formatting context. Clips at overflow-clip-margin.
/* scrollable sidebar, never clips the sticky header */
.sidebar {
  overflow-y: auto;
  overflow-x: hidden;
  height: 100vh;
}

/* text truncation with ellipsis */
.label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
Use overflow-x and overflow-y individually to control each axis. Setting one axis to auto or hidden forces the other to auto if it is visible.

12.5 Common Positioning Patterns

Positioning recipe table
Pattern CSS
Center in container
.container { position: relative; }
.child {
  position: absolute;
  inset: 0;
  margin: auto;
  width: fit-content;
  height: fit-content;
}
Fixed full-screen overlay
.overlay {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 50%);
  z-index: 900;
}
Sticky section header
.section-header {
  position: sticky;
  top: 3rem;   /* clears a 3rem fixed site header */
  background: var(--light);
  z-index: 10;
}
Badge on a card
.card  { position: relative; }
.badge {
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
}
Tooltip above element
.host   { position: relative; }
.tooltip {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
}
Isolate stacking context
/* prevent child z-index from bleeding out */
.widget {
  isolation: isolate;
}

12.6 Tutorials

CSS Positioning Tutorials
Tutorial Type Why Use It
MDN: Positioning Beginner→Intermediate Step-by-step tutorial covering all five position values with live examples.
CSS-Tricks: position Reference Compact almanac entry with visual demos for each value.
MDN: Understanding z-index Intermediate Four-part series on stacking order, stacking contexts, and common z-index bugs.
MDN: overflow Reference Complete reference for overflow values, scroll containers, and text overflow.
MDN: CSS Containing Block Intermediate Explains how the containing block is determined for each position value.
web.dev: z-index and stacking contexts Intermediate Clear explanation of why z-index doesn't always work as expected.

12.7 References

CSS Positioning References
Resource Description
MDN: position Full reference for all position values, with syntax, formal definition, and browser compatibility.
MDN: inset Shorthand for top/right/bottom/left offset properties.
MDN: z-index Reference for z-index, including the stacking context interaction.
MDN: Stacking context Describes what stacking contexts are, how they are formed, and their painting order.
MDN: overflow All overflow values, overflow-x/y, text-overflow, and scroll container behavior.
W3C CSS2: Visual Formatting Model Formal specification for normal flow, positioning schemes, and containing blocks.