Position
Static, relative, absolute, fixed and sticky positioning in Tailwind — plus inset utilities, containing blocks, and the patterns that actually come up.
Positioning takes an element out of normal flow, or gives its children a reference point. Two utilities do most of the work: relative on a parent and absolute on a child.
Overview#
<div class="p-4">
<div class="relative mx-auto h-40 max-w-sm rounded-xl border-2 border-dashed border-gray-300 bg-gray-50">
<span class="absolute top-2 left-2 rounded bg-indigo-600 px-2 py-1 text-xs font-medium text-white">top-2 left-2</span>
<span class="absolute right-2 bottom-2 rounded bg-emerald-600 px-2 py-1 text-xs font-medium text-white">right-2 bottom-2</span>
<span class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded bg-gray-900 px-2 py-1 text-xs font-medium text-white">centred</span>
</div>
</div>Reference#
| Utility | Behaviour |
|---|---|
static | Default. In flow; top/right/bottom/left are ignored |
relative | In flow, but offsettable — and becomes a containing block for absolute children |
absolute | Out of flow, positioned against the nearest positioned ancestor |
fixed | Out of flow, positioned against the viewport |
sticky | In flow until it hits a threshold, then sticks |
Inset utilities#
| Utility | CSS |
|---|---|
top-4 right-4 bottom-4 left-4 | Individual offsets |
inset-4 | All four sides |
inset-x-4 / inset-y-4 | Horizontal / vertical pairs |
inset-0 | Fill the containing block |
-top-2 | Negative offset — pull outside the box |
top-1/2 | 50% of the containing block |
start-4 / end-4 | Logical, direction-aware |
v4.2 Logical insets inset-s-*, inset-e-*, inset-bs-* and inset-be-* map to inset-inline-start, inset-inline-end, inset-block-start and inset-block-end.
The containing block rule#
absolute positions against the nearest ancestor that is not static. If there is none, it positions against the initial containing block — usually the page.
<!-- ❌ The badge escapes to the page corner -->
<div class="border p-4">
<span class="absolute top-0 right-0">New</span>
</div>
<!-- ✅ relative gives the badge a reference -->
<div class="relative border p-4">
<span class="absolute top-0 right-0">New</span>
</div>Common patterns#
Centring absolutely#
<div class="relative h-40">
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">Centred</div>
</div>top-1/2 moves the element's top edge to the midpoint; the negative translate pulls it back by half its own size. If you control the layout, flex items-center justify-center is simpler.
Overlay on an image#
<figure class="relative mx-auto max-w-sm overflow-hidden rounded-xl">
<div class="h-40 bg-gradient-to-br from-indigo-500 to-purple-700"></div>
<div class="absolute inset-0 bg-gradient-to-t from-black/70 to-transparent"></div>
<figcaption class="absolute right-0 bottom-0 left-0 p-4">
<h3 class="font-semibold text-white">Northern Lights</h3>
<p class="text-sm text-white/80">Tromsø, Norway</p>
</figcaption>
</figure>inset-0 is the idiomatic way to make an overlay fill its parent.
Notification badge#
<div class="p-6">
<button class="relative rounded-lg border border-gray-300 p-2 hover:bg-gray-50">
<svg class="size-5 text-gray-700" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.4-1.4A2 2 0 0 1 18 14.2V11a6 6 0 1 0-12 0v3.2c0 .5-.2 1-.6 1.4L4 17h5m6 0v1a3 3 0 1 1-6 0v-1m6 0H9"/></svg>
<span class="absolute -top-1 -right-1 grid size-5 place-items-center rounded-full bg-red-600 text-[0.65rem] font-bold text-white">3</span>
<span class="sr-only">3 unread notifications</span>
</button>
</div>Negative insets (-top-1 -right-1) let the badge overhang the button.
Sticky header#
<header class="sticky top-0 z-40 border-b border-gray-200 bg-white/85 backdrop-blur">
…
</header>sticky needs three things to work:
- A threshold —
top-0alone is not enough; you must specify at least one offset. - A scrolling ancestor that is taller than the sticky element.
- No
overflow: hidden/autoon an ancestor between the element and the scroll container.
Sticky table header#
<div class="max-h-72 overflow-y-auto rounded-lg border border-gray-200">
<table class="w-full text-sm">
<thead class="sticky top-0 bg-gray-50">…</thead>
<tbody>…</tbody>
</table>
</div>Here the scroll container is the wrapper, and the header sticks inside it.
Fixed action button#
<button class="fixed right-6 bottom-6 z-50 rounded-full bg-indigo-600 p-4 text-white shadow-lg hover:bg-indigo-500">
<span class="sr-only">New message</span>
…
</button>Sticky vs fixed#
sticky | fixed | |
|---|---|---|
| Occupies space in flow | Yes | No |
| Positioned against | Nearest scrolling ancestor | Viewport (usually) |
| Scrolls away | Yes, once its parent has passed | No |
| Needs an offset | Yes | Yes, in practice |
| Right for | Section headers, table heads, sidebars | Modals, toasts, FABs |
Advanced example: a sticky sidebar#
<div class="mx-auto flex max-w-6xl gap-8 px-6">
<main class="min-w-0 flex-1">…long content…</main>
<aside class="hidden w-64 shrink-0 lg:block">
<div class="sticky top-24 space-y-2">
<p class="text-xs font-semibold tracking-wide text-gray-500 uppercase">On this page</p>
<nav class="space-y-1 text-sm">…</nav>
</div>
</aside>
</div>The sticky element is the inner div. Making the <aside> itself sticky would not work, because it is only as tall as its content.
Common mistakes#
absolutewith no positioned ancestor. Addrelativeto the intended parent.stickywithout an offset.stickyalone does nothing; it needstop-0or similar.overflow-hiddenon an ancestor of a sticky element. Silently breaks it.fixedinside a transformed ancestor. It becomes fixed to that ancestor, not the viewport.- Stacking issues from missing
z-index. Positioned elements create stacking contexts — see Overflow & Layering. - Forgetting that
absoluteshrinks to fit. An absolutely positioned element sizes to its content unless you set a width or opposing insets (inset-x-0).
Related topics#
- Overflow & Layering —
z-index,isolate, stacking contexts - Display — the layout mode underneath
- Transforms —
translatefor centring - Modals & Toasts — positioning in practice