Visibility
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">19<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 |
|---|---|
| Valencia | 13.7k |
| Austin | 18.8k |
<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>Valencia</td>
<td class="text-end">13.7k</td>
</tr>
<tr>
<td>Austin</td>
<td class="text-end">18.8k</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">
Travel insurance
</div>
</div>
<div class="col-4">
<div class="border rounded-3 p-2 text-center">
Hotel booking
</div>
</div>
<div class="col-4">
<div class="border rounded-3 p-2 text-center">
Holiday packages
</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">(14)</span>
</div>12Old and new price
visually-hidden words tell which price is the original and which the sale price.
Original price:$132.29Sale price:$69.60
<p class="mb-0"><span class="visually-hidden">Original price:</span><span class="text-decoration-line-through text-body-tertiary me-2">$132.29</span><span class="visually-hidden">Sale price:</span><span class="fw-bold text-danger fs-5">$69.60</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) 882-9816">
<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">Nimbus 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="78" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar" style="width:78%">
<span class="visually-hidden">78% 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.
Every hotel on our list is visited and reviewed by our own travel team. Clear prices, honest advice and no surprises along the way.
Back to top<div class="border rounded-3 p-3 small">
<p class="mb-2">Every hotel on our list is visited and reviewed by our own travel team. Clear prices, honest advice and no surprises along the way.</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">Pack your bags, we will do the rest</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>