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 text-bg-primary rounded-2 px-2 small top-0 start-0">1</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-0 end-0">2</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-50 start-50">3</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small bottom-50 end-50">4</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small bottom-0 start-0">5</span> <span class="position-absolute text-bg-primary 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 text-bg-primary rounded-2 px-2 small top-0 start-0 translate-middle">TL</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-0 start-50 translate-middle">T</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-0 start-100 translate-middle">TR</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-50 start-0 translate-middle">L</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-50 start-50 translate-middle">C</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-50 start-100 translate-middle">R</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-100 start-0 translate-middle">BL</span> <span class="position-absolute text-bg-primary rounded-2 px-2 small top-100 start-50 translate-middle">B</span> <span class="position-absolute text-bg-primary 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" aria-hidden="true"></i> Inbox <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">84<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="Lucas Fischer" 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="Nora Ibrahim" 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="Mateo Kim" 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-7.svg" alt="Amara Novak" 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">10</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="Python basics" 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(--ui-border-radius)">-24%</span>
<div class="p-3">
<div class="fw-medium">
Python basics
</div>
<div class="small text-body-secondary">
$25.18
</div>
</div>
</div>7Stretched link
stretched-link on the link makes the whole position-relative card clickable.
Study groups and a friendly forum keep you motivated along the way.
Read the story<div class="position-relative border rounded-3 p-3" style="max-width:22rem">
<div class="fw-semibold">
Learn from people who do the job
</div>
<p class="small text-body-secondary">Study groups and a friendly forum keep you motivated along the way.</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.
Every course is built around hands-on projects you can add to your portfolio. The mobile app downloads lessons, so you can learn on the train.
Guided learning paths take you from beginner to job-ready step by step. Mentors review your projects and give feedback within two days.
We listen first, then build a plan around what you actually need. Short quizzes after each lesson help new knowledge stick.
Earn a certificate at the end of each course and share it with employers. Clear prices, honest advice and no surprises along the way.
<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">Every course is built around hands-on projects you can add to your portfolio. The mobile app downloads lessons, so you can learn on the train.</p>
<p class="px-3 small">Guided learning paths take you from beginner to job-ready step by step. Mentors review your projects and give feedback within two days.</p>
<p class="px-3 small">We listen first, then build a plan around what you actually need. Short quizzes after each lesson help new knowledge stick.</p>
<p class="px-3 small mb-0">Earn a certificate at the end of each course and share it with employers. Clear prices, honest advice and no surprises along the way.</p>
</div>9position-sticky with a custom offset
position-sticky plus top-0 on a table header row inside a scroll box.
| Item | Price |
|---|---|
| Data analysis | $46.14 |
| Python basics | $44.87 |
| Public speaking | $27.60 |
| Copywriting | $58.72 |
| Web development | $13.86 |
| Project management | $82.11 |
<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>Data analysis</td>
<td class="text-end">$46.14</td>
</tr>
<tr>
<td>Python basics</td>
<td class="text-end">$44.87</td>
</tr>
<tr>
<td>Public speaking</td>
<td class="text-end">$27.60</td>
</tr>
<tr>
<td>Copywriting</td>
<td class="text-end">$58.72</td>
</tr>
<tr>
<td>Web development</td>
<td class="text-end">$13.86</td>
</tr>
<tr>
<td>Project management</td>
<td class="text-end">$82.11</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="https://images.unsplash.com/photo-1565598611425-45b0878bdd0b?auto=format&fit=crop&w=1200&h=800&q=70" alt="Toronto" 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" aria-hidden="true"></i> Kyoto</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="https://images.unsplash.com/photo-1523240795612-9a054b0db644?auto=format&fit=crop&w=1600&h=700&q=70" 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">
Knowledge that moves you forward
</div>
<div class="small">
Friendly people answer your questions quickly, by phone, chat or email.
</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 Development">
</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">33 saved</span>
<button type="button" class="btn btn-outline-primary"><i class="bi bi-bookmark" 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-reset">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-reset">sticky-top</code> - sticks after scrolling to it
</div>
<div class="position-static text-bg-dark rounded-2 p-2">
<code class="text-reset">fixed-bottom</code> - pins a bar to the bottom
</div>
<div class="position-static text-bg-secondary rounded-2 p-2">
<code class="text-reset">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.
We measure success by how many students come back and tell their friends. Instructors are working professionals who teach what they use every day.
<div class="position-relative border rounded-3 p-3 overflow-hidden" style="max-width:22rem">
<div class="fw-semibold">
Tips for learning while working full time
</div>
<p class="small mb-0">We measure success by how many students come back and tell their friends. Instructors are working professionals who teach what they use every day.</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="https://images.unsplash.com/photo-1758270705518-b61b40527e76?auto=format&fit=crop&w=1600&h=700&q=70" alt="Map of Cape Town" 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">Melbourne</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="https://images.unsplash.com/photo-1523240795612-9a054b0db644?auto=format&fit=crop&w=1200&h=800&q=70" alt="Your next career starts here" 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">
$218.35
</div>
</div>
</div>