Elements flow naturally. Setting top, left, etc. has no effect on static elements.
Position Values at a Glance
position: static
Default. Elements follow normal document flow.
position: relative
Offset from normal position. Space preserved.
position: absolute
Removed from flow. Positioned to ancestor.
position: fixed
Fixed to viewport. Stays on scroll.
position: sticky
Hybrid. Relative until scroll threshold.
Static Position (Default)
position: static is the default value. Elements appear in the normal document flow and ignore top, right, bottom, left, and z-index properties.
.element {
position: static; /* default - top/right/bottom/left ignored */
}Relative Position
position: relative offsets the element from its normal position. The original space is preserved in the document flow.
The green box moves 30px down and 20px right from where it would normally be. The dashed outline shows its original position in the flow.
Key Insight
Relative positioning moves the visual rendering but keeps the element's space in the flow. Other elements don't fill the gap left behind.
.relative-box {
position: relative;
top: 30px; /* moves down */
left: 20px; /* moves right */
}Absolute Position
position: absolute removes the element from normal flow and positions it relative to its nearest positioned ancestor (or the viewport if none exists).
Absolute elements position themselves relative to the demo container (which has position: relative). The center box uses the transform: translate(-50%, -50%) centering technique.
Positioning Context
An absolutely positioned element looks for the nearest ancestor with position set to relative, absolute, fixed, or sticky. If none found, it positions to the viewport.
.parent { position: relative; }
.absolute-child {
position: absolute;
top: 20px;
right: 20px;
}
/* Center technique */
.centered {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
}Fixed Position
position: fixed positions the element relative to the viewport. It stays in place even when the page scrolls.
Click to show a fixed position element in the bottom-right corner
Fixed elements are removed from document flow and positioned relative to the viewport. Common uses: navigation bars, floating action buttons, cookie notices.
.fixed-button {
position: fixed;
bottom: 30px;
right: 30px;
z-index: 1000;
}Sticky Position
position: sticky is a hybrid between relative and fixed. The element behaves as relative until a scroll threshold is met, then becomes fixed.
Scroll down to see the sticky header in action...
This content scrolls normally beneath the sticky header.
The header will stick to the top of its scroll container when you scroll past it.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.
Sticky positioning is perfect for section headers, navigation, and table headers.
Unlike fixed positioning, sticky elements remain within their parent container.
Keep scrolling to see it stick!
When you scroll back up, it returns to its normal position in the flow.
This creates a natural, intuitive user experience.
The purple header sticks to the top when scrolling. Unlike fixed, it stays within its container bounds.
Sticky Requirements
Sticky positioning requires: 1) A scroll container (parent with overflow: auto/scroll), 2) A threshold (top, bottom, etc.), and 3) The parent must have sufficient height to scroll.
.sticky-header {
position: sticky;
top: 0; /* sticks at top of scroll container */
}Z-Index Stacking
The z-index property controls the stacking order of positioned elements. Higher values appear in front of lower values.
Each box overlaps the previous one. The purple box (z-index: 3) appears on top because it has the highest stack order.
.layer-1 { position: absolute; z-index: 1; }
.layer-2 { position: absolute; z-index: 2; }
.layer-3 { position: absolute; z-index: 3; }Inset Shorthand
The inset property is a shorthand for top, right, bottom, and left. It simplifies creating full-coverage overlays and positioned containers.
(20px from all edges)
Using inset: 20px is equivalent to setting top, right, bottom, and left all to 20px.
.box { inset: 20px; } /* all sides */
.box { inset: 10px 20px; } /* vertical | horizontal */
.overlay { position: fixed; inset: 0; } /* full viewport */