CSS Position
Position Values at a Glance
| Value | In Flow? | Positioned Relative To | Use Case |
|---|---|---|---|
static | Yes | N/A (default) | Normal flow |
relative | Yes | Its own normal position | Nudging, anchor for absolutes |
absolute | No | Closest positioned ancestor | Overlays, tooltips, badges |
fixed | No | Viewport | Sticky headers, FABs |
sticky | Yes (until stuck) | Scroll container | Scroll-aware headers, sidebars |
position: relative
The element stays in normal flow but can be offset from its original position using top, right, bottom, left. The space it originally occupied is preserved.
Most common use: setting position: relative on a parent so that absolute-positioned children reference it.
position: absolute
Removes the element from document flow. It positions relative to the closest ancestor that has position: relative, absolute, or fixed. If no positioned ancestor exists, it falls back to the viewport.
Golden rule: always pair position: absolute on the child with position: relative on the parent.
position: fixed
Like absolute, but positioned relative to the viewport. It stays in the same spot even when scrolling. Removed from document flow.
Use for persistent navigation, floating action buttons, and cookie banners. Remember to add padding or margin to the body so content is not hidden behind the fixed element.
position: sticky
A hybrid: behaves like relative until the user scrolls past a threshold, then it “sticks” like fixed. Unlike fixed, it stays inside its parent — when the parent scrolls out, the sticky element goes with it.
Gotcha: sticky requires the parent to be taller than the sticky element. It will not work if the parent has overflow: hidden or overflow: auto.
Common Patterns
Overlay / Modal Backdrop
Tooltip Positioned Above Element
Sticky Table Header
Frequently Asked Questions
relative keeps the element in the document flow and offsets it from its normal spot. absolute removes it from the flow entirely and positions it relative to the nearest positioned ancestor. If no ancestor is positioned, it uses the viewport.sticky when you want an element to scroll normally, then stick at a threshold — it stays within its parent. Use fixed when you want the element to always be visible at the same viewport position, regardless of scrolling.position: relative. Without a positioned ancestor, absolute elements reference the viewport. Add position: relative to the parent and make sure you set top/left/right/bottom offsets.