CSS Positioning Basics
Understanding how to position elements with static, relative, absolute, fixed, and sticky positioning
CSS Positioning Basics
CSS positioning defines how elements are placed within a web page. Understanding positioning is essential for creating complex layouts, overlays, navigation bars, and precisely placed elements.
Every element has a position property that controls how it's positioned in the document flow.
Position Types Overview
| Position | Description |
|---|---|
static | Default positioning, follows normal document flow |
relative | Positioned relative to its normal position |
absolute | Positioned relative to closest positioned ancestor |
fixed | Positioned relative to viewport, stays in place when scrolling |
sticky | Relative until scroll threshold, then becomes fixed |
Static Positioning
Static is the default position for all elements. Elements appear in the normal document flow, one after another.
<!DOCTYPE html>
<html>
<head>
<style>
div {
border: 1px solid black;
padding: 10px;
margin: 10px;
background-color: lightblue;
}
</style>
</head>
<body>
<div>Box 1</div>
<div>Box 2</div>
<div>Box 3</div>
</body>
</html>
Key characteristics:
- Elements stack vertically (for block elements) or horizontally (for inline elements)
top,right,bottom,leftproperties have no effect- This is how elements behave by default
You rarely need to explicitly set position: static since it's the default.
Relative Positioning
Relative positioning moves an element relative to where it would normally appear, without affecting the layout of surrounding elements.
<!DOCTYPE html>
<html>
<head>
<style>
div {
border: 1px solid black;
padding: 10px;
margin: 10px;
background-color: lightblue;
}
.relative {
position: relative;
top: 20px;
left: 30px;
background-color: lightcoral;
}
</style>
</head>
<body>
<div>Box 1</div>
<div class="relative">Box 2 (Relative)</div>
<div>Box 3</div>
</body>
</html>
Box 2 is shifted 20px down and 30px right from its normal position.
Important details:
- The element's original space is preserved in the layout
- Other elements don't move to fill the gap
- The element appears shifted visually, but the layout acts as if it's still in its original position
- Uses
top,right,bottom,leftto shift position
Offset properties:
top: 20px- Moves element 20px downleft: 30px- Moves element 30px to the rightbottom: 10px- Moves element 10px upright: 15px- Moves element 15px to the left
Common use case: Slightly adjusting element positions without disrupting layout.
Absolute Positioning
Absolute positioning removes the element from the normal document flow and positions it relative to its closest positioned ancestor (any parent with position other than static).
<!DOCTYPE html>
<html>
<head>
<style>
.container {
position: relative;
width: 300px;
height: 200px;
border: 2px solid black;
margin: 20px auto;
background-color: lightgray;
}
.absolute {
position: absolute;
top: 50px;
left: 50px;
background-color: pink;
padding: 10px;
border: 1px solid red;
}
</style>
</head>
<body>
<div class="container">
<p>Container with Relative Positioning</p>
<div class="absolute">Absolutely Positioned Element</div>
</div>
</body>
</html>
The pink box is positioned 50px from the top and 50px from the left of the .container element.
Key characteristics:
- Element is removed from document flow - other elements act as if it doesn't exist
- No space is reserved for it in the layout
- Positioned relative to the nearest ancestor with
position: relative,absolute,fixed, orsticky - If no positioned ancestor exists, it's positioned relative to the
<body>
Common pattern - Positioned parent:
.parent {
position: relative; /* Creates positioning context */
}
.child {
position: absolute; /* Positioned within parent */
top: 0;
right: 0;
}
This is the most common pattern - set a parent to position: relative (which doesn't move it) to create a positioning context for absolute children.
Use cases:
- Tooltips and dropdowns
- Overlays and modals
- Icons positioned within containers
- Image badges or labels
Fixed Positioning
Fixed positioning removes the element from the document flow and positions it relative to the viewport (browser window). It stays in place even when scrolling.
<!DOCTYPE html>
<html>
<head>
<style>
.fixed {
position: fixed;
top: 10px;
right: 10px;
background-color: lightgreen;
padding: 20px;
border: 2px solid black;
z-index: 1000;
}
.content {
height: 2000px;
padding: 20px;
}
</style>
</head>
<body>
<div class="fixed">Fixed Box - Scroll to see me stay!</div>
<div class="content">
<h2>Fixed Positioning Example</h2>
<p>Scroll down and notice the green box stays in the same viewport position.</p>
<p>This content simulates a long page...</p>
</div>
</body>
</html>
Key characteristics:
- Always positioned relative to the viewport, not any parent element
- Stays in place while scrolling
- Removed from document flow (no space reserved)
top,right,bottom,leftare relative to the viewport edges
Common use cases:
- Navigation bars that stay visible while scrolling
- "Back to top" buttons
- Chat widgets
- Cookie consent banners
- Floating action buttons
Important note: Fixed elements are positioned relative to the viewport, so position: relative on a parent has no effect.
Sticky Positioning
Sticky positioning is a hybrid between relative and fixed. The element behaves as relative until you scroll to a specified threshold, then it becomes fixed.
<!DOCTYPE html>
<html>
<head>
<style>
.spacer {
height: 300px;
background: lightgray;
padding: 20px;
}
.sticky {
position: sticky;
top: 10px;
background: yellow;
padding: 10px;
border: 2px solid orange;
}
</style>
</head>
<body>
<div class="spacer">
<h2>Scroll down to see sticky behavior</h2>
<p>The yellow box below will stick when it reaches 10px from the top of the viewport.</p>
</div>
<div class="sticky">I become sticky when you scroll!</div>
<div class="spacer">
<p>Keep scrolling...</p>
<p>The sticky element stays fixed at the top until you scroll back up or reach the end of its container.</p>
</div>
</body>
</html>
How it works:
- Element scrolls normally (like
relative) until... - It reaches the specified threshold (
top: 10px) - Then it "sticks" in place (like
fixed) - When you scroll back up, it unsticks and returns to relative behavior
Key characteristics:
- Switches between
relativeandfixedbehavior based on scroll position - Must specify at least one of:
top,right,bottom, orleft - Sticks within its parent container only (won't stick beyond parent's boundaries)
- Maintains its space in the document flow
Common use cases:
- Table headers that stick while scrolling table data
- Section headings in long articles
- Navigation menus that stick after scrolling past the hero section
- Sidebar elements that stick until you reach the end of content
The z-index Property
When elements overlap (common with absolute, fixed, or relative positioning), z-index controls which element appears on top.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
position: absolute;
border: 2px solid black;
}
.box1 {
background-color: red;
top: 50px;
left: 50px;
z-index: 1;
}
.box2 {
background-color: blue;
top: 80px;
left: 80px;
z-index: 2;
}
.box3 {
background-color: green;
top: 110px;
left: 110px;
z-index: 3;
}
</style>
</head>
<body>
<div class="box box1">Z: 1</div>
<div class="box box2">Z: 2</div>
<div class="box box3">Z: 3</div>
</body>
</html>
How z-index works:
- Higher numbers appear on top
- Only works on positioned elements (not
static) - Negative values are allowed
- Default value is
auto(order depends on HTML structure)
Common z-index values:
.modal-backdrop { z-index: 1000; }
.modal { z-index: 1001; }
.dropdown { z-index: 100; }
.navbar { z-index: 10; }
Positioning Offset Properties
All positioned elements (except static) can use these properties:
.positioned {
position: absolute;
top: 20px; /* Distance from top edge */
right: 30px; /* Distance from right edge */
bottom: 10px; /* Distance from bottom edge */
left: 15px; /* Distance from left edge */
}
Important rules:
topandbottomcan conflict - typically use one or the otherleftandrightcan conflict - typically use one or the other- Values can be
px,%,em,rem, etc. - Negative values pull the element in the opposite direction
Centering with Absolute Positioning
A common pattern for centering absolutely positioned elements:
<!DOCTYPE html>
<html>
<head>
<style>
.container {
position: relative;
width: 400px;
height: 300px;
border: 2px solid black;
background-color: lightgray;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border: 1px solid black;
}
</style>
</head>
<body>
<div class="container">
<div class="centered">Perfectly Centered!</div>
</div>
</body>
</html>
How this works:
top: 50%; left: 50%positions the top-left corner at the centertransform: translate(-50%, -50%)shifts the element back by half its own width and height- Result: the element's center aligns with the container's center
Quick Reference
| Position | Document Flow | Positioned Relative To | Scrolls? |
|---|---|---|---|
static | In flow | Normal position | Yes |
relative | In flow | Its normal position | Yes |
absolute | Out of flow | Nearest positioned ancestor | Yes |
fixed | Out of flow | Viewport | No |
sticky | In flow | Varies (relative → fixed) | Varies |
Best Practices
Use relative for small adjustments:
.icon {
position: relative;
top: 2px; /* Slight vertical alignment */
}
Use absolute for overlays:
.badge {
position: absolute;
top: -5px;
right: -5px;
}
Use fixed for persistent UI:
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
}
Use sticky for scrolling context:
.table-header {
position: sticky;
top: 0;
}
Always set a positioning context:
When using absolute, set the parent to position: relative to control where the element is positioned:
.parent {
position: relative; /* Positioning context */
}
.child {
position: absolute; /* Positioned within parent */
}
Consider z-index hierarchy: Plan your z-index values to avoid conflicts. Use a scale like 10, 100, 1000 to leave room for adjustments.
