Visibility utilities show or hide content in different ways. invisible hides an element but keeps its space, visible restores it, visually-hidden hides content on screen while keeping it for screen readers, and visually-hidden-focusable reveals it again when it receives keyboard focus.
1Visible and invisible
invisible hides an element but keeps its space; visible shows it again.
visibleinvisiblevisible<div class="d-flex gap-2">
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center visible">
<code class="small">visible</code>
</div>
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center invisible">
<code class="small">invisible</code>
</div>
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center visible">
<code class="small">visible</code>
</div>
</div>2Invisible versus d-none
Compare: invisible leaves a gap, d-none closes it.
AB invisibleCAB d-noneC<div class="d-grid gap-2">
<div class="d-flex gap-2">
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center">
<code class="small">A</code>
</div>
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center invisible">
<code class="small">B invisible</code>
</div>
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center">
<code class="small">C</code>
</div>
</div>
<div class="d-flex gap-2">
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center">
<code class="small">A</code>
</div>
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center d-none">
<code class="small">B d-none</code>
</div>
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center">
<code class="small">C</code>
</div>
</div>
</div>3Hidden label for an input
visually-hidden hides the label on screen while screen readers still announce it.
<div class="d-flex gap-2" style="max-width:22rem">
<label class="visually-hidden" for="ut-join-1263">Email address</label>
<input id="ut-join-1263" type="email" class="form-control" placeholder="Email address">
<button type="button" class="btn btn-primary">Join</button>
</div>4Skip link
visually-hidden-focusable shows a skip link only when it receives keyboard focus. Press Tab inside this example.
<div class="border rounded-3 p-2">
<a href="#ut-main-1264" class="visually-hidden-focusable btn btn-sm btn-primary">Skip to main content</a>
<nav class="small d-flex gap-3 py-1" aria-label="Demo">
<a href="#">Home</a><a href="#">Shop</a><a href="#">Help</a>
</nav>
<div id="ut-main-1264" class="bg-body-tertiary rounded-2 p-2 small">
Main content
</div>
</div>5Icon button with hidden text
The icon is aria-hidden and a visually-hidden span names the button.
<div class="d-flex gap-2">
<button type="button" class="btn btn-outline-secondary"><i class="bi bi-pencil" aria-hidden="true"></i><span class="visually-hidden">Edit</span></button>
<button type="button" class="btn btn-outline-secondary"><i class="bi bi-share" aria-hidden="true"></i><span class="visually-hidden">Share</span></button>
<button type="button" class="btn btn-outline-danger"><i class="bi bi-trash3" aria-hidden="true"></i><span class="visually-hidden">Delete</span></button>
</div>6Counter with context
A badge reads "5 unread messages" to screen readers while showing only the number.
<button type="button" class="btn btn-light border">Messages <span class="badge text-bg-primary">10<span class="visually-hidden"> unread messages</span></span></button>7Keep alignment with invisible icons
An invisible check icon keeps unchecked rows aligned with the checked one.
- Newest first
- Oldest first
- Most popular
<ul class="list-unstyled border rounded-3 mb-0 p-2" style="max-width:16rem">
<li class="px-2 py-1"><span class="text-primary me-2"><i class="bi bi-check-lg" aria-hidden="true"></i></span>Newest first</li>
<li class="px-2 py-1"><span class="invisible me-2"><i class="bi bi-check-lg" aria-hidden="true"></i></span>Oldest first</li>
<li class="px-2 py-1"><span class="invisible me-2"><i class="bi bi-check-lg" aria-hidden="true"></i></span>Most popular</li>
</ul>8Hidden table caption
A visually-hidden caption describes the table for assistive technology.
| City | Visits |
|---|---|
| Austin | 24.2k |
| Prague | 9.2k |
<table class="table table-sm small mb-0">
<caption class="visually-hidden">Monthly visits by city</caption>
<thead>
<tr>
<th scope="col">City</th>
<th scope="col" class="text-end">Visits</th>
</tr>
</thead>
<tbody>
<tr>
<td>Austin</td>
<td class="text-end">24.2k</td>
</tr>
<tr>
<td>Prague</td>
<td class="text-end">9.2k</td>
</tr>
</tbody>
</table>9Hidden section heading
A visually-hidden heading gives a visual-only card grid a name in the outline.
Featured services
<section>
<h3 class="visually-hidden">Featured services</h3>
<div class="row g-2 small">
<div class="col-4">
<div class="border rounded-3 p-2 text-center">
Nutrition plans
</div>
</div>
<div class="col-4">
<div class="border rounded-3 p-2 text-center">
Online coaching
</div>
</div>
<div class="col-4">
<div class="border rounded-3 p-2 text-center">
Recovery spa
</div>
</div>
</div>
</section>10Spinner with a hidden status
The spinner's text is visually-hidden inside role="status".
<div class="d-flex align-items-center gap-2">
<div class="spinner-border spinner-border-sm text-primary" role="status">
<span class="visually-hidden">Loading orders</span>
</div>
<span class="small text-body-secondary">Fetching the latest data</span>
</div>11Rating for screen readers
Stars are hidden from assistive tech and a visually-hidden text states the score.
<div>
<span class="text-warning" aria-hidden="true"><i class="bi bi-star-fill" aria-hidden="true"></i><i class="bi bi-star-fill" aria-hidden="true"></i><i class="bi bi-star-fill" aria-hidden="true"></i><i class="bi bi-star" aria-hidden="true"></i><i class="bi bi-star" aria-hidden="true"></i></span><span class="visually-hidden">Rated 3 out of 5</span> <span class="small">(74)</span>
</div>12Old and new price
visually-hidden words tell which price is the original and which the sale price.
Original price:$86.49Sale price:$55.43
<p class="mb-0"><span class="visually-hidden">Original price:</span><span class="text-decoration-line-through text-body-tertiary me-2">$86.49</span><span class="visually-hidden">Sale price:</span><span class="fw-bold text-danger fs-5">$55.43</span></p>13Reserved space for errors
An invisible error line keeps the form from jumping when the message appears.
<div style="max-width:22rem">
<label class="form-label" for="ut-tel-1265">Phone</label>
<input id="ut-tel-1265" type="tel" class="form-control" value="+1 (555) 864-1211">
<div class="small text-danger invisible">
Please enter a valid phone number.
</div>
<button type="button" class="btn btn-primary btn-sm">Next</button>
</div>14Current page in pagination
A visually-hidden "(current)" marks the active page for screen readers.
<nav aria-label="Results pages">
<ul class="pagination pagination-sm mb-0">
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item active" aria-current="page"><a class="page-link" href="#">2 <span class="visually-hidden">(current)</span></a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
</ul>
</nav>15External link hint
An outward arrow icon plus a visually-hidden note about the link destination.
<a href="#" class="icon-link">Aeroium Deck documentation <i class="bi bi-box-arrow-up-right" aria-hidden="true"></i><span class="visually-hidden"> (external site)</span></a>16Progress with hidden value
The progress bar shows the fill; the percentage is a visually-hidden text.
<div class="progress" role="progressbar" aria-label="Upload progress" aria-valuenow="29" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar" style="width:29%">
<span class="visually-hidden">29% uploaded</span>
</div>
</div>17Back to top link
A visually-hidden-focusable link at the end of a long page only shows for keyboard users.
Pause or change your membership any time, with no long contracts. More than sixty classes a week, from sunrise yoga to late-night spin.
Back to top<div class="border rounded-3 p-3 small">
<p class="mb-2">Pause or change your membership any time, with no long contracts. More than sixty classes a week, from sunrise yoga to late-night spin.</p>
<a href="#ut-main-1264" class="visually-hidden-focusable">Back to top</a>
</div>18Placeholder column
An invisible column keeps a three column layout balanced while one is empty.
colcolinvisible col<div class="row g-2">
<div class="col-4">
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center">
<code class="small">col</code>
</div>
</div>
<div class="col-4">
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center">
<code class="small">col</code>
</div>
</div>
<div class="col-4 invisible">
<div class="bg-primary-subtle border border-primary-subtle rounded-2 p-2 text-center">
<code class="small">invisible col</code>
</div>
</div>
</div>19Hidden legend
A visually-hidden legend names a radio group whose visual heading is elsewhere.
<fieldset>
<legend class="visually-hidden">Delivery speed</legend>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="ut-speed-1266" id="ut-std-1267" checked>
<label class="form-check-label" for="ut-std-1267">Standard</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="ut-speed-1266" id="ut-exp-1268">
<label class="form-check-label" for="ut-exp-1268">Express</label>
</div>
</fieldset>20Close button label
btn-close has no text, so it needs aria-label; a visually-hidden span is the alternative for custom close icons.
<div class="d-flex align-items-center gap-3 border rounded-3 p-2" style="max-width:22rem">
<span class="small flex-grow-1">Move more, stress less</span>
<button type="button" class="btn-close" aria-label="Close"></button>
<button type="button" class="btn btn-sm btn-light"><i class="bi bi-x-lg" aria-hidden="true"></i><span class="visually-hidden">Dismiss</span></button>
</div>