Position
Position utilities set position (static, relative, absolute, fixed, sticky) and place absolute children with top-*, bottom-*, start-* and end-* at 0, 50 or 100. translate-middle, translate-middle-x and translate-middle-y centre an element on its point, which is how badges and status indicators sit on buttons and avatars.
1Edge positions
top-0, top-50, top-100 with start-0, start-50, start-100 place absolute children on a grid of nine points.
<div class="position-relative bg-body-tertiary border rounded-3" style="height:180px">
<span class="position-absolute bg-primary text-white rounded-2 px-2 small top-0 start-0">1</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-0 end-0">2</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-50 start-50">3</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small bottom-50 end-50">4</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small bottom-0 start-0">5</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small bottom-0 end-0">6</span>
</div>2Centre with translate-middle
translate-middle shifts an element back by half its size so its centre sits on the point.
<div class="position-relative bg-body-tertiary border rounded-3 m-3" style="height:180px">
<span class="position-absolute bg-primary text-white rounded-2 px-2 small top-0 start-0 translate-middle">TL</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-0 start-50 translate-middle">T</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-0 start-100 translate-middle">TR</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-50 start-0 translate-middle">L</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-50 start-50 translate-middle">C</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-50 start-100 translate-middle">R</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-100 start-0 translate-middle">BL</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-100 start-50 translate-middle">B</span> <span class="position-absolute bg-primary text-white rounded-2 px-2 small top-100 start-100 translate-middle">BR</span>
</div>3Notification badge on a button
position-relative on the button, translate-middle on the counter at top-0 start-100.
<div class="d-flex gap-4 pt-2">
<button type="button" class="btn btn-primary position-relative"><i class="bi bi-envelope-fill" aria-hidden="true"></i> Inbox <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">88<span class="visually-hidden"> unread messages</span></span> </button>
<button type="button" class="btn btn-outline-secondary position-relative" aria-label="Alerts"><i class="bi bi-bell-fill" aria-hidden="true"></i> <span class="position-absolute top-0 start-100 translate-middle p-1 bg-danger border border-light rounded-circle"><span class="visually-hidden">New alerts</span></span> </button>
</div>4Online indicator on an avatar
The indicator sits at bottom-0 end-0 of a position-relative wrapper.
<div class="d-flex gap-3">
<span class="position-relative d-inline-block"><img src="../assets/img/avatar-1.svg" alt="Finn Silva" width="64" height="64" class="rounded-circle"><span class="position-absolute bottom-0 end-0 bg-success border border-3 border-white rounded-circle" style="width:18px;height:18px"><span class="visually-hidden">Online</span></span></span> <span class="position-relative d-inline-block"><img src="../assets/img/avatar-2.svg" alt="Ravi Sato" width="64" height="64" class="rounded-circle"><span class="position-absolute bottom-0 end-0 bg-warning border border-3 border-white rounded-circle" style="width:18px;height:18px"><span class="visually-hidden">Busy</span></span></span> <span class="position-relative d-inline-block"><img src="../assets/img/avatar-3.svg" alt="Freya Okafor" width="64" height="64" class="rounded-circle"><span class="position-absolute bottom-0 end-0 bg-secondary border border-3 border-white rounded-circle" style="width:18px;height:18px"><span class="visually-hidden">Offline</span></span></span>
</div>5Count badge on an avatar
A number badge at top-0 start-100 with translate-middle on a square avatar.
<span class="position-relative d-inline-block mt-2"> <img src="../assets/img/avatar-10.svg" alt="Amara Duarte" width="56" height="56" class="rounded-3"> <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-primary border border-2 border-white">5</span> </span>6Ribbon on a card
An absolutely placed label at top-0 end-0 of a card.
<div class="position-relative border rounded-4 overflow-hidden" style="max-width:18rem">
<img src="../assets/img/product-9.svg" alt="Canvas tote" class="w-100 d-block"> <span class="position-absolute top-0 end-0 text-bg-danger px-3 py-1 small fw-semibold" style="border-bottom-left-radius:var(--bs-border-radius)">-48%</span>
<div class="p-3">
<div class="fw-medium">
Wool scarf
</div>
<div class="small text-body-secondary">
$16.19
</div>
</div>
</div>7Stretched link
stretched-link on the link makes the whole position-relative card clickable.
The new secure payments brings every detail in view at a fair price.
Read the story<div class="position-relative border rounded-3 p-3" style="max-width:22rem">
<div class="fw-semibold">
New season, new favourites
</div>
<p class="small text-body-secondary">The new secure payments brings every detail in view at a fair price.</p>
<a href="#" class="stretched-link small">Read the story</a>
</div>8Sticky top inside a scroll area
sticky-top keeps a header visible while its scroll container moves.
The new hand-checked quality makes customers coming back from the very first day. A honest plan guides new ideas to life from the very first day.
Our 30-day returns keeps every detail in view on any device. The new hand-checked quality gives time back in your day wherever you are.
A friendly plan keeps new ideas to life wherever you are. Our free shipping lets data easy to understand without the usual hassle.
The new hand-checked quality shows you focused on what matters for teams of every size. The new carbon-neutral delivery gives every detail in view all year round.
<div class="border rounded-3 overflow-auto" style="height:170px">
<div class="sticky-top bg-body-secondary px-3 py-2 fw-semibold small">
Section A (sticky-top)
</div>
<p class="px-3 small">The new hand-checked quality makes customers coming back from the very first day. A honest plan guides new ideas to life from the very first day.</p>
<p class="px-3 small">Our 30-day returns keeps every detail in view on any device. The new hand-checked quality gives time back in your day wherever you are.</p>
<p class="px-3 small">A friendly plan keeps new ideas to life wherever you are. Our free shipping lets data easy to understand without the usual hassle.</p>
<p class="px-3 small mb-0">The new hand-checked quality shows you focused on what matters for teams of every size. The new carbon-neutral delivery gives every detail in view all year round.</p>
</div>9position-sticky with a custom offset
position-sticky plus top-0 on a table header row inside a scroll box.
| Item | Price |
|---|---|
| Wool scarf | $79.57 |
| Wool scarf | $57.68 |
| Canvas tote | $59.14 |
| Running cap | $70.99 |
| Canvas tote | $77.57 |
| Wool scarf | $61.10 |
<div class="border rounded-3 overflow-auto" style="max-height:170px">
<table class="table table-sm mb-0">
<thead class="position-sticky top-0">
<tr>
<th scope="col" class="bg-body-tertiary">Item</th>
<th scope="col" class="bg-body-tertiary text-end">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Wool scarf</td>
<td class="text-end">$79.57</td>
</tr>
<tr>
<td>Wool scarf</td>
<td class="text-end">$57.68</td>
</tr>
<tr>
<td>Canvas tote</td>
<td class="text-end">$59.14</td>
</tr>
<tr>
<td>Running cap</td>
<td class="text-end">$70.99</td>
</tr>
<tr>
<td>Canvas tote</td>
<td class="text-end">$77.57</td>
</tr>
<tr>
<td>Wool scarf</td>
<td class="text-end">$61.10</td>
</tr>
</tbody>
</table>
</div>10Caption over an image
position-absolute bottom-0 start-0 with margin places a label on the photo corner.
<div class="position-relative d-inline-block rounded-4 overflow-hidden" style="max-width:24rem">
<img src="../assets/img/photo-9.svg" alt="Singapore" class="w-100 d-block"> <span class="position-absolute bottom-0 start-0 m-3 badge text-bg-light"><i class="bi bi-geo-alt-fill" aria-hidden="true"></i> Cape Town</span>
</div>11Play button centred on a video
top-50 start-50 translate-middle centres the play button on the poster image.
<div class="position-relative rounded-4 overflow-hidden" style="max-width:26rem">
<img src="../assets/img/wide-1.svg" alt="Video poster" class="w-100 d-block">
<button type="button" class="btn btn-light rounded-circle position-absolute top-50 start-50 translate-middle shadow fs-3 d-flex align-items-center justify-content-center" style="width:64px;height:64px" aria-label="Play"><i class="bi bi-play-fill" aria-hidden="true"></i></button>
</div>12Step progress with positioned dots
A line with translate-middle steps positioned at start-0, start-50 and start-100.
<div class="px-3 py-4">
<div class="position-relative" style="height:4px">
<div class="bg-body-secondary w-100 h-100 rounded-pill">
</div>
<div class="position-absolute top-0 start-0 bg-primary h-100 w-50 rounded-pill">
</div>
<span class="position-absolute top-50 start-0 translate-middle btn btn-sm btn-primary rounded-pill" style="width:2rem;height:2rem">1</span> <span class="position-absolute top-50 start-50 translate-middle btn btn-sm btn-primary rounded-pill" style="width:2rem;height:2rem">2</span> <span class="position-absolute top-50 start-100 translate-middle btn btn-sm btn-secondary rounded-pill" style="width:2rem;height:2rem">3</span>
</div>
</div>13Close button in the corner
A btn-close at top-0 end-0 with a small margin.
<div class="position-relative border rounded-3 p-3 pe-5 bg-body-tertiary">
<button type="button" class="btn-close position-absolute top-0 end-0 m-2" aria-label="Close"></button>
<div class="fw-semibold">
Quality goods delivered to your door
</div>
<div class="small">
The new easy exchanges helps the whole team on the same page in just a few clicks.
</div>
</div>14Icon inside an input
An icon at top-50 translate-middle-y on the start of a padded input.
<div class="position-relative" style="max-width:22rem">
<span class="position-absolute top-50 start-0 translate-middle-y ms-3 text-body-secondary"><i class="bi bi-search" aria-hidden="true"></i></span>
<label class="visually-hidden" for="ut-q-1254">Search</label>
<input id="ut-q-1254" type="search" class="form-control ps-5" placeholder="Search Accessories">
</div>15Tooltip arrow label
A label positioned above an element with bottom-100 start-50 translate-middle-x.
<div class="pt-5 text-center">
<span class="position-relative d-inline-block"> <span class="position-absolute bottom-100 start-50 translate-middle-x mb-2 text-bg-dark rounded-2 px-2 py-1 small text-nowrap">16 saved</span>
<button type="button" class="btn btn-outline-primary"><i class="bi bi-bookmark-fill" aria-hidden="true"></i> Save</button>
</span>
</div>16Fixed and sticky classes (preview)
fixed-top, fixed-bottom and sticky-top attach bars to the viewport; here they are previewed as static boxes with position-static.
fixed-top - pins a bar to the top of the viewportsticky-top - sticks after scrolling to itfixed-bottom - pins a bar to the bottomsticky-md-top - sticky from md up<div class="d-grid gap-2 small">
<div class="position-static text-bg-dark rounded-2 p-2">
<code class="text-white">fixed-top</code> - pins a bar to the top of the viewport
</div>
<div class="position-static text-bg-secondary rounded-2 p-2">
<code class="text-white">sticky-top</code> - sticks after scrolling to it
</div>
<div class="position-static text-bg-dark rounded-2 p-2">
<code class="text-white">fixed-bottom</code> - pins a bar to the bottom
</div>
<div class="position-static text-bg-secondary rounded-2 p-2">
<code class="text-white">sticky-md-top</code> - sticky from md up
</div>
</div>17Overlay covering a card
position-absolute top-0 start-0 w-100 h-100 covers the card with a loading layer.
The new member prices brings every detail in view in just a few clicks. A fast team connects complex tasks into simple steps for teams of every size.
<div class="position-relative border rounded-3 p-3 overflow-hidden" style="max-width:22rem">
<div class="fw-semibold">
Inside the calm journey
</div>
<p class="small mb-0">The new member prices brings every detail in view in just a few clicks. A fast team connects complex tasks into simple steps for teams of every size.</p>
<div class="position-absolute top-0 start-0 w-100 h-100 bg-body bg-opacity-75 d-flex align-items-center justify-content-center">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading</span>
</div>
</div>
</div>18Map pin
A pin positioned at percentage offsets with bottom-50 and translate-middle-x.
<div class="position-relative rounded-4 overflow-hidden" style="max-width:26rem">
<img src="../assets/img/wide-6.svg" alt="Map of Valencia" class="w-100 d-block"> <span class="position-absolute top-50 start-50 translate-middle text-danger fs-2 lh-1"><i class="bi bi-geo-alt-fill" aria-hidden="true"></i></span> <span class="position-absolute bottom-0 end-0 m-2 badge text-bg-light">Prague</span>
</div>19Vertical centre on one side
top-50 end-0 translate-middle-y places a next arrow on the side of a slider.
<div class="position-relative rounded-4 overflow-hidden" style="max-width:26rem">
<img src="../assets/img/photo-7.svg" alt="Everyday essentials, beautifully made" class="w-100 d-block">
<button type="button" class="btn btn-light btn-sm rounded-circle position-absolute top-50 start-0 translate-middle-y ms-2" aria-label="Previous"><i class="bi bi-chevron-left" aria-hidden="true"></i></button>
<button type="button" class="btn btn-light btn-sm rounded-circle position-absolute top-50 end-0 translate-middle-y me-2" aria-label="Next"><i class="bi bi-chevron-right" aria-hidden="true"></i></button>
</div>20Corner tag on a pricing card
A badge at top-0 start-50 translate-middle sits on the top border.
<div class="pt-3">
<div class="position-relative border border-2 border-primary rounded-4 p-4 text-center" style="max-width:16rem">
<span class="position-absolute top-0 start-50 translate-middle badge rounded-pill text-bg-primary px-3">Best value</span>
<div class="small">
Yearly
</div>
<div class="fs-3 fw-bold">
$257.63
</div>
</div>
</div>