Choose the coordinate system before setting offsets
position determines how a box is placed and which containing block its offsets use. top, right, bottom and left do not make sense in isolation; first identify the positioning mode and the relevant ancestor or viewport.
A badge attached to a card
.card { position: relative; padding: 2rem 1rem 1rem; }
.card__badge {
position: absolute;
top: 0.5rem;
right: 0.5rem;
}
.site-header {
position: sticky;
top: 0;
z-index: 10;
background: white;
}The card establishes the intended containing block for the absolutely positioned badge. The badge is out of normal flow, so the card's top padding reserves room for it. The sticky header remains in normal flow but can stick once its threshold is reached.
Five modes
- static: normal positioning; offsets generally do not apply.
- relative: visually offset from its normal position while its original layout space remains.
- absolute: removed from normal flow and positioned against its containing block.
- fixed: commonly positioned against the viewport, though certain ancestors such as transformed elements can establish its containing block.
- sticky: combines normal-flow placement with sticking within scrolling/containment constraints.
Why sticky may not stick
Check that an inset such as top:0 exists, that the element has room to move, and which ancestor establishes scrolling. An overflow setting on an ancestor can change the relevant scroll container. Sticky does not allow an element to escape the end of its containing region.
Avoid covering content
A fixed header occupies no normal-flow space, so the page may need deliberate offset space. A sticky/fixed element can obscure anchor targets and keyboard focus. Use scroll-margin-top on target sections when appropriate and test at large text sizes.
Practice
- Remove position:relative from the card and identify the badge's new containing block.
- Compare a relative offset with an absolute position by observing neighboring flow.
- Test a sticky header inside a short scrolling panel and on the page.
- Zoom to 200% and check that the badge and header do not cover essential text.