CSS Position
The position property controls how an element is placed in the document. Use it for special cases: sticky navbars, overlays, tooltips, and badges. For general page layout, use Flexbox or Grid instead.
There are five position values: static, relative, absolute, fixed, and sticky.
position: static
static is the default. The element follows normal document flow. The offset properties (top, right, bottom, left) have no effect.
You rarely need to write this explicitly. It only comes up when overriding another rule.
.element {
position: static;
}
position: relative
The element stays in normal flow but can be shifted using offset properties. The shift is relative to where the element would naturally sit. Other elements are not affected; the space is still reserved.
.shifted {
position: relative;
top: 10px;
left: 20px;
}
position: relative is also used to create a positioning context for absolutely positioned children.
position: absolute
The element is removed from normal flow. It is positioned relative to its nearest ancestor that has a position value other than static. If no such ancestor exists, it positions relative to the viewport.
.card {
position: relative; /* creates the positioning context */
}
.badge {
position: absolute;
top: 8px;
right: 8px;
}
Common uses: badges on cards, tooltips, dropdown menus, custom select overlays.
position: fixed
The element is positioned relative to the viewport and stays in place when the page scrolls.
.navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
Common uses: navigation bars that stay at the top, floating action buttons, cookie banners.
position: sticky
Sticky is a hybrid of relative and fixed. The element behaves like relative until the user scrolls to a threshold, then it sticks like fixed until its parent scrolls out of view.
You must set at least one of top, right, bottom, or left for sticky to work.
.section-heading {
position: sticky;
top: 0;
background-color: white;
}
Common uses: table headers, section headings that stay visible while scrolling through that section, sidebars.
z-index
When positioned elements overlap, z-index controls which one appears on top. Higher values sit in front of lower ones. The default is 0.
z-index only works on positioned elements (anything other than static).
.modal {
position: fixed;
z-index: 300;
}
.navbar {
position: sticky;
z-index: 100;
}
Practical patterns
Sticky navbar
.navbar {
position: sticky;
top: 0;
z-index: 100;
background-color: white;
}
Modal overlay
.overlay {
position: fixed;
inset: 0; /* shorthand for top: 0; right: 0; bottom: 0; left: 0 */
background-color: rgba(0, 0, 0, 0.5);
z-index: 200;
}
Badge on a card
The parent needs position: relative so the badge positions relative to it rather than the viewport.
.card {
position: relative;
}
.badge {
position: absolute;
top: 8px;
right: 8px;
}
What to read next
- CSS Flexbox : one-dimensional layout with rows and columns
- CSS Grid : two-dimensional layout for full page structure