absolute positioning
position: absolute removes an element from the normal flow and positions it relative to its nearest positioned ancestor (usually set with position: relative). Absolutely positioned elements don't take up space and can overlap other elements. This is ideal for overlays, modals, tooltips, and any element that needs precise positioning independent of the flow.
How absolute positioning works
/* Absolute positioning — out of flow */
position: absolute;
top: 50px; /* 50px from top of containing block */
right: 20px; /* 20px from right of containing block */
/* Element is removed from normal flow */
/* Other elements don't account for its space */
/* It's positioned relative to nearest positioned ancestor */
<!-- Example structure -->
<div class="parent">
<div class="child absolute">Absolutely positioned</div>
<div class="sibling">Sibling (not affected)</div>
</div>
.parent {
position: relative; /* creates containing block */
width: 300px;
height: 200px;
}
.child {
position: absolute;
top: 50px;
left: 100px;
/* Positioned 50px from parent's top, 100px from left */
}
.sibling {
/* Not affected by absolute positioning of child */
/* Renders as if absolute element doesn't exist */
}Finding the containing block
For absolutely positioned elements, the containing block is determined by the nearest ancestor with a position value other than static. If no ancestor is positioned, the containing block is the viewport (or document root).
<!-- Without positioned ancestor -->
<html>
<body>
<div class="static-parent">
<div class="absolute-child">I'm positioned relative to viewport</div>
</div>
</body>
</html>
.static-parent {
width: 300px;
/* position: static (default) */
/* NOT a containing block */
}
.absolute-child {
position: absolute;
top: 50px;
left: 100px;
/* Positioned 50px from viewport top, 100px from viewport left */
}
<!-- With positioned ancestor -->
<div class="relative-parent">
<div class="absolute-child">I'm positioned relative to parent</div>
</div>
.relative-parent {
position: relative; /* creates containing block */
width: 300px;
height: 200px;
}
.absolute-child {
position: absolute;
top: 50px;
left: 100px;
/* Now positioned 50px from parent top, 100px from parent left */
}Absolute positioning removes elements from flow
This is the key difference from relative positioning. Absolutely positioned elements don't take up space, so siblings move up to fill the gap.
<!-- Three divs stacked -->
<div>Normal 1</div>
<div class="absolute">Absolute (out of flow)</div>
<div>Normal 2</div>
.absolute {
position: absolute;
top: 50px;
left: 100px;
width: 200px;
height: 100px;
}
/* Visual layout */
[Normal 1]
[Normal 2] ← moved up because absolute element removed from flow
(Absolute floats above)
/* Space is NOT preserved for absolute element */
/* Next element moves up immediately */Positioning with offset properties
/* Position from all four corners */
.positioned {
position: absolute;
top: 20px; /* 20px from top */
right: 30px; /* 30px from right */
bottom: 40px; /* 40px from bottom */
left: 50px; /* 50px from left */
}
/* Position from specific corners */
.top-left {
position: absolute;
top: 10px;
left: 10px;
}
.top-right {
position: absolute;
top: 10px;
right: 10px;
}
.bottom-left {
position: absolute;
bottom: 10px;
left: 10px;
}
.bottom-right {
position: absolute;
bottom: 10px;
right: 10px;
}
/* Center positioning */
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* Translate offsets by half of element's own size */
}
/* Stretch to fill containing block */
.fill {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* Covers entire containing block */
}Size constraints with absolute positioning
Absolutely positioned elements can be sized with width/height, or by using opposite offset properties (top + bottom, left + right) to stretch.
/* Explicit width and height */
.modal {
position: absolute;
width: 500px;
height: 300px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Stretch with opposite offsets */
.overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
/* Stretches to cover entire containing block */
}
/* Stretch horizontally, explicit height */
.banner {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 50px;
/* Stretches width, fixed height */
}
/* Stretch vertically, explicit width */
.sidebar {
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 250px;
/* Fixed width, stretches height */
}Practical absolute positioning patterns
/* Badge on image */
.image-container {
position: relative;
display: inline-block;
width: 200px;
height: 200px;
overflow: hidden;
}
.badge {
position: absolute;
top: 10px;
right: 10px;
background: #f44336;
color: white;
padding: 4px 8px;
border-radius: 12px;
}
/* Modal dialog */
.modal-backdrop {
position: fixed; /* covers viewport */
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.modal {
position: absolute;
background: white;
border-radius: 8px;
padding: 30px;
max-width: 500px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}
/* Close button in corner */
.close-button {
position: absolute;
top: 10px;
right: 10px;
background: none;
border: none;
font-size: 24px;
cursor: pointer;
}
/* Tooltip below trigger element */
.tooltip {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
margin-bottom: 10px;
background: #333333;
color: white;
padding: 8px 12px;
border-radius: 4px;
white-space: nowrap;
}
.tooltip::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: #333333;
}Inline elements with absolute positioning
When you apply position: absolute to an inline element, it becomes block-like and respects width/height properties.
<!-- Inline element -->
<span>Just a span</span>
span {
display: inline;
width: 100px; /* ignored */
height: 50px; /* ignored */
}
<!-- Same span, absolutely positioned -->
<span class="positioned">Positioned span</span>
.positioned {
position: absolute;
width: 100px; /* NOW works */
height: 50px; /* NOW works */
/* Absolute positioning makes inline elements respect sizing */
}