Accessibility & Performance
Bootstrap 3 gets you a working, responsive TrailMap fast — but "it renders on every screen size" isn't the same as "everyone can actually use it," and "it loads" isn't the same as "it loads fast." This lesson covers both in one pass: the accessibility work Bootstrap does not do for you, and the real performance cost of the bundle you're shipping.
Part 1: Accessibility — What Bootstrap Bakes In
Some accessibility behavior ships with Bootstrap's components already. The Modal plugin, for
example, renders with role="dialog" out of the box:
<div class="modal fade" id="trailModal" role="dialog" aria-labelledby="trailModalLabel">
...
</div>
That's a real head start, but it only covers the components you didn't hand-build yourself. Anything you assemble from raw markup — a Glyphicon-only button, an icon used purely for decoration — needs the ARIA attributes added by hand.
aria-hidden on Decorative Glyphicons
A Glyphicon is just a font character rendered through a <span>. When it carries no
meaning on its own — it's sitting next to text that already says the same thing — screen readers
shouldn't announce it at all. Mark it aria-hidden="true":
<!-- decorative: the button already says "Search Trails" -->
<button class="btn btn-primary">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Search Trails
</button>
.sr-only for Icon-Only Buttons
When the button has no visible text — just an icon, to save space — the Glyphicon is now the
only clue to what the button does, so it can't be hidden. Instead, pair aria-hidden="true"
on the icon with a .sr-only span that gives screen readers a real label:
<!-- icon-only: needs a screen-reader-only label -->
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-heart" aria-hidden="true"></span>
<span class="sr-only">Save trail to favorites</span>
</button>
display:none (that would hide it
from screen readers too). It positions the text off-screen with an absolute position and a 1px clip, so
it stays in the accessibility tree while being invisible to sighted users.Still Your Job: Focus, Contrast, Alt Text, Heading Order
None of Bootstrap's baked-in roles cover these — they depend on the actual content and design choices you make, so the framework can't do them for you:
| Concern | What you have to do |
|---|---|
| Focus states | Don't strip Bootstrap's default focus outline with a blanket outline:none override — keyboard users need to see where focus is |
| Color contrast | A custom @brand-primary (see the LESS Customization lesson) can look great and still fail WCAG contrast against white text — check the ratio after every recolor |
| Meaningful alt text | A trail photo's alt should describe the trail ("Sunrise Ridge summit view"), not restate the filename or say "image" |
| Logical heading order | Don't skip from <h1> to <h4> because it "looked right" visually — screen reader users navigate by heading level |
TrailMap Audit: The Navbar's Toggle Button
Revisit the collapsed navbar toggle from the earlier Navbar lesson. The three stacked bars are pure decoration — the button already needs a text label for anyone who can't see the icon-bars at all:
<!-- before: icon-bars with no accessible label -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#trailNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- after: aria-hidden on the bars, sr-only label on the button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#trailNavbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar" aria-hidden="true"></span>
<span class="icon-bar" aria-hidden="true"></span>
<span class="icon-bar" aria-hidden="true"></span>
</button>
.sr-only span when trimming markup
down.Part 2: Performance — What the Full Bundle Actually Costs
The CDN links at the top of every page in this track load the entire framework: all of
bootstrap.min.css, all of bootstrap.min.js, and (if you add it) the full
Glyphicons icon font — dozens of glyphs you'll never reference, shipped to every visitor regardless.
| Full CDN bundle | Trimmed custom LESS build |
|---|---|
| Every component's CSS, used or not (grid, all button variants, carousel, affix, tooltips...) | Import only the LESS mixins/components TrailMap actually uses via @import in your own file |
| Full Glyphicons font file, for maybe 6 icons in use | Subset the icon font, or skip Glyphicons for components that don't need them |
All jQuery plugins bundled together in one bootstrap.min.js | Bootstrap 3's individual plugin files can be concatenated selectively if you're not using, say, Affix or Carousel |
The other lever is your own CSS: every override you write on top of Bootstrap is extra weight the browser has to parse in addition to the framework's rules. Fewer, more targeted overrides (or better — LESS variable changes that need no override CSS at all) keep the page's total stylesheet size down.
col-xs-*, Panels/Wells/Thumbnails, Affix, and more — gets pulled into one
migration checklist in Migrating to Bootstrap 4.