The position property is one of the most powerful tools in CSS for controlling exactly where elements appear on the page. While most elements follow normal document flow, positioning lets you break out of that flow to create overlays, tooltips, sticky headers, floating elements, and complex layered designs. Understanding positioning is essential for advanced layout control.
Position Property Overview
The position property determines how an element is positioned in the document. Once you set a position value other than static, you can use the offset properties (top, right, bottom, left) to move the element.
Position Values
| Property | Values | Description |
|---|---|---|
static | position: static | Default - normal document flow |
relative | position: relative | Positioned relative to normal position |
absolute | position: absolute | Positioned relative to nearest positioned ancestor |
fixed | position: fixed | Positioned relative to viewport (doesn't scroll) |
sticky | position: sticky | Toggles between relative and fixed |
/* Position with offset properties */
.element {
position: relative; /* or absolute, fixed, sticky */
top: 20px; /* Distance from top */
right: 30px; /* Distance from right */
bottom: 40px; /* Distance from bottom */
left: 50px; /* Distance from left */
}
/* You typically use either top OR bottom, and left OR right */
.element {
position: absolute;
top: 20px; /* Distance from top */
left: 30px; /* Distance from left */
}
/* Centering with positioning */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}Important: The offset properties (top, right, bottom, left) only work when position is set to something other than static. They have no effect on statically positioned elements.
position: static (Default)
Static is the default position for all elements. Elements are positioned according to the normal document flow, and offset properties have no effect.
/* Default positioning */
.element {
position: static; /* Default value */
/* top, right, bottom, left have NO EFFECT */
}
/* This is how elements normally behave */
div {
position: static; /* Default */
}
/* Static is rarely explicitly set - it's the default */position: static (Default)
Static positioning is straightforward—elements simply flow in the order they appear in the HTML. This is the normal behavior you've been working with throughout these tutorials.
position: relative
Relative positioning moves an element relative to its normal position in the document flow. The element still occupies its original space— other elements don't move to fill the gap.
/* Relative positioning */
.element {
position: relative;
top: 20px; /* Move 20px DOWN from normal position */
left: 30px; /* Move 30px RIGHT from normal position */
}
/* Element moves but original space is preserved */
/* Common uses */
/* 1. Slight adjustments */
.icon {
position: relative;
top: 2px; /* Align with text */
}
/* 2. Creating a positioned context for absolute children */
.container {
position: relative; /* Now absolute children position relative to this */
}
.container .badge {
position: absolute; /* Positions relative to .container */
top: 0;
right: 0;
}position: relative
Visual Representation of Relative Positioning
Relative Position Visual
🎯 Key Relative Positioning Concepts:
- Element moves from its normal position
- Original space is preserved (other elements don't shift)
- Creates positioning context for absolute children
- Most common use: positioning context, not for moving the element itself
position: absolute
Absolute positioning removes an element from the normal document flow and positions it relative to its nearest positioned ancestor (an ancestor with position: relative, absolute, or fixed). If no positioned ancestor exists, it positions relative to the document body.
/* Absolute positioning */
.element {
position: absolute;
top: 20px; /* 20px from top of positioned parent */
right: 30px; /* 30px from right of positioned parent */
}
/* Element is removed from document flow */
/* Other elements move up to fill the space */
/* Common pattern: relative parent + absolute child */
.container {
position: relative; /* Creates positioning context */
}
.badge {
position: absolute;
top: -10px;
right: -10px;
}
/* Centering with absolute */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Stretching to fill parent */
.overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}position: absolute with Offsets
Absolute Without Positioned Parent
Absolute Without Positioned Parent
Practical Example: Card with Badge
Product Card with Badges
Best Practice: Almost always give absolute elements a positioned parent (usually position: relative). This creates a predictable positioning context. The pattern of "relative parent + absolute child" is one of the most common in CSS.
position: fixed
Fixed positioning positions an element relative to the viewport (browser window). The element stays in the same position even when the page is scrolled. It's removed from document flow like absolute positioning.
/* Fixed positioning */
.element {
position: fixed;
top: 0; /* 0px from top of viewport */
right: 0; /* 0px from right of viewport */
}
/* Element doesn't scroll with page */
/* Common uses */
/* Fixed header */
header {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
z-index: 1000;
}
/* Fixed "back to top" button */
.back-to-top {
position: fixed;
bottom: 20px;
right: 20px;
}
/* Fixed sidebar */
.sidebar {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 250px;
}
/* Modal overlay */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
}position: fixed Examples
Fixed Navigation Bar
Fixed Navigation Bar
Fixed Positioning Gotcha: Fixed elements don't scroll with the page, which is perfect for headers and floating buttons. However, remember to add padding to your main content equal to the height of the fixed header, or content will be hidden behind it!
position: sticky
Sticky positioning is a hybrid between relative and fixed. The element behaves like relative positioning until it reaches a threshold (defined by top, right, bottom, or left), then it becomes fixed.
/* Sticky positioning */
.element {
position: sticky;
top: 0; /* Becomes fixed when scrolled to top */
}
/* Element is relative until scroll threshold, then fixed */
/* Common uses */
/* Sticky header */
header {
position: sticky;
top: 0;
z-index: 100;
}
/* Sticky table headers */
thead th {
position: sticky;
top: 0;
background: white;
}
/* Sticky sidebar */
.sidebar {
position: sticky;
top: 20px; /* 20px from top when stuck */
}
/* Requirements for sticky to work: */
/* 1. Parent must have height/scroll */
/* 2. At least one threshold (top/right/bottom/left) */
/* 3. Element must not be overflow: hidden parent */position: sticky (Multiple Levels)
Sticky Table Headers
Sticky Table Headers
Sticky Requirements: For sticky positioning to work: (1) The parent must allow scrolling, (2) You must specify at least one threshold (top, right, bottom, or left), (3) The element can't have an ancestor with overflow: hidden. If sticky isn't working, check these three things!
z-index and Stacking Context
When elements overlap (which happens with positioning), the z-index property controls which element appears on top. Higher z-index values appear in front.
/* Z-index controls stacking order */
.element {
position: relative; /* z-index only works on positioned elements */
z-index: 10; /* Higher = in front */
}
/* Z-index values */
.background {
z-index: 1; /* Behind */
}
.middle {
z-index: 10; /* Middle layer */
}
.foreground {
z-index: 100; /* In front */
}
/* Common z-index scale */
.content {
z-index: 1;
}
.dropdown {
z-index: 100;
}
.modal-overlay {
z-index: 1000;
}
.modal {
z-index: 1001;
}
.tooltip {
z-index: 10000;
}
/* Negative z-index */
.background-element {
z-index: -1; /* Behind parent */
}z-index Stacking Order
Stacking Context Example
Stacking Layers Example
📚 Z-Index Best Practices:
- Use a consistent scale (1, 10, 100, 1000, etc.)
- Document your z-index values (tooltips: 10000, modals: 1000, etc.)
- Only use z-index when elements actually overlap
- z-index only works on positioned elements
- Avoid z-index wars (50, 51, 52, 100, 101, 9999...)
Position Values Comparison
| Position | In Flow? | Positioned From | Scrolls? | Common Uses |
|---|---|---|---|---|
| static | ✅ Yes | Normal flow | ✅ Yes | Default behavior |
| relative | ✅ Yes (space reserved) | Normal position | ✅ Yes | Positioning context, minor adjustments |
| absolute | ❌ No | Nearest positioned ancestor | ✅ Yes (with parent) | Badges, tooltips, overlays |
| fixed | ❌ No | Viewport | ❌ No | Fixed headers, floating buttons, modals |
| sticky | ✅ Yes (until threshold) | Normal flow → Viewport | Hybrid | Sticky headers, table headers |
Key Takeaways
- static (default): Normal document flow, offset properties don't work
- relative: Positioned relative to normal position, space reserved, creates positioning context
- absolute: Removed from flow, positioned relative to nearest positioned ancestor
- fixed: Removed from flow, positioned relative to viewport, doesn't scroll
- sticky: Hybrid of relative and fixed, toggles at threshold
- Offset properties (top, right, bottom, left) only work with positioned elements
- Common pattern: relative parent + absolute child
z-indexcontrols stacking order (only works on positioned elements)- Fixed elements need body padding to avoid hiding content
- Sticky requires: scrolling parent, threshold value, no overflow: hidden ancestor
- Use positioning for overlays, badges, tooltips, fixed headers
- Always give absolute elements a positioned parent for predictability
What's Next?
Congratulations! You've completed the "Box Model & Sizing" section and now have a solid foundation in CSS fundamentals. You understand how elements are sized, displayed, and positioned—core skills for creating any layout.
In the next section, "Flexbox", we'll dive deep into modern CSS layout with Flexible Box Layout. You'll learn how to create flexible, responsive layouts with properties like justify-content, align-items, flex-direction, flex-wrap, and more. Flexbox revolutionized CSS layout, making it easy to create complex designs that were previously difficult or impossible.
Positioning is a powerful tool that lets you break out of normal document flow to create sophisticated layouts. Practice combining different position values to create modals, tooltips, sticky headers, and layered designs. Master positioning and you'll be able to implement virtually any design!