Positioning
The position property takes an element out of the normal flow, or nudges it within it. It's how badges sit on corners, headers stick to the top, overlays cover the screen and tooltips appear next to their trigger.
static (the default)
Statically positioned elements follow normal document flow. The offset properties top, right, bottom and left have no effect on them.
relative
A relatively positioned element is offset from where it would normally be, but its original space is kept — neighbours don't move. Its most common use is not moving anything at all, but acting as the containing block for absolutely positioned children.
absolute
An absolutely positioned element is removed from the flow — other elements act as if it isn't there — and placed relative to its nearest positioned ancestor (any ancestor with a position other than static). If there isn't one, it's placed relative to the page. That's why the position: relative on the parent matters.
Filling a container
inset: 0 is shorthand for top: 0; right: 0; bottom: 0; left: 0 — stretching the element to cover its containing block.
fixed
A fixed element is positioned relative to the viewport and stays in place when the page scrolls — floating buttons, cookie banners, modal backdrops. (In this demo it's fixed to the scrolling box, because the box has a transform; any ancestor with a transform, filter or certain other properties becomes the containing block for fixed elements — a common surprise.)
sticky
A sticky element behaves normally until scrolling would move it past its offset (top: 0), then it sticks — until its parent scrolls out of view. Sticky needs an offset, and fails if an ancestor has overflow: hidden.
Summary
| Value | In normal flow? | Positioned relative to |
|---|---|---|
static | Yes | — |
relative | Yes (space kept) | Its own normal position |
absolute | No | Nearest positioned ancestor |
fixed | No | The viewport |
sticky | Yes, until it sticks | Its scroll container |
Anchor positioning
A newer feature, anchor positioning, lets an element position itself relative to any other element — like a tooltip next to its button — and flip automatically if it would go off-screen:
.trigger {
anchor-name: --help;
}
.tooltip {
position: absolute;
position-anchor: --help;
top: anchor(bottom);
left: anchor(center);
translate: -50% 6px;
position-try-fallbacks: flip-block;
}
It's supported in recent Chromium browsers and arriving elsewhere; until it's everywhere, popover libraries handle this with JavaScript.
Use positioning sparingly
For page layout, use Flexbox and Grid. Absolute positioning removes elements from the flow, so they don't make room for each other and can overlap at different screen sizes. Keep it for overlays, badges, decorations and pop-ups.