A Bootstrap HTML template in one file

Two tags from a CDN and a page of standard markup. Bootstrap gives you finished components, which is the opposite trade from a utility framework, and it suits internal pages well.

A Bootstrap HTML template is one file with two external references: the stylesheet in the head, and the JavaScript bundle before the closing body tag.

Here is a complete starter with a navbar, a card grid and a table.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Weekly report</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-body-tertiary">

  <nav class="navbar navbar-expand-lg bg-white border-bottom">
    <div class="container">
      <span class="navbar-brand mb-0 h1">Weekly report</span>
      <span class="text-secondary small">Week 38</span>
    </div>
  </nav>

  <main class="container py-4">

    <div class="row g-3 mb-4">
      <div class="col-12 col-md-4">
        <div class="card h-100">
          <div class="card-body">
            <p class="text-secondary small mb-1">Active accounts</p>
            <p class="fs-3 fw-semibold mb-0">1,284</p>
          </div>
        </div>
      </div>
      <div class="col-12 col-md-4">
        <div class="card h-100">
          <div class="card-body">
            <p class="text-secondary small mb-1">Open tickets</p>
            <p class="fs-3 fw-semibold mb-0">37</p>
          </div>
        </div>
      </div>
      <div class="col-12 col-md-4">
        <div class="card h-100">
          <div class="card-body">
            <p class="text-secondary small mb-1">Median first reply</p>
            <p class="fs-3 fw-semibold mb-0">42m</p>
          </div>
        </div>
      </div>
    </div>

    <h2 class="h6 mb-2">By team</h2>
    <div class="table-responsive">
      <table class="table table-sm table-striped align-middle bg-white">
        <thead>
          <tr><th scope="col">Team</th><th scope="col">Tickets</th><th scope="col">Trend</th></tr>
        </thead>
        <tbody>
          <tr><td>Billing</td><td>14</td><td><span class="badge text-bg-success">down</span></td></tr>
          <tr><td>Onboarding</td><td>12</td><td><span class="badge text-bg-danger">up</span></td></tr>
        </tbody>
      </table>
    </div>

  </main>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
The template rendering with a navbar, three cards and a striped table.
The template rendering with a navbar, three cards and a striped table.

The classes that are doing the work

Class Job Note
container Centres content, sets gutters container-fluid for full width
row and col-* The twelve column grid Columns must sit inside a row
col-md-4 Three across from medium width up Full width below that breakpoint
g-3 Gap between grid items Goes on the row, not the column
card and card-body The card shell and its padding h-100 makes a row of cards equal height
table-responsive Horizontal scroll on narrow screens Wrap the table, do not style it
badge text-bg-success Small status label Pairs colour and contrast correctly

The row wrapper is the one to remember. Columns without a row lose their gutters and widths, which reads as a broken grid when it is only a missing div.

Do you need the JavaScript bundle

Only for components that move. The stylesheet alone covers a large amount of what people build.

Needs the bundle: modal, dropdown, tabs, collapse, accordion, tooltip, popover, toast, offcanvas, carousel.

Does not need it: grid, cards, tables, buttons, badges, forms, alerts without dismiss, list groups, pagination, typography.

If your page is a report, leave the script out. That removes a request and an external dependency for something you never call.

The same page rendering correctly with the JavaScript bundle removed.
The same page rendering correctly with the JavaScript bundle removed.

Changing how it looks

Bootstrap pages look like Bootstrap pages, which is the point and also the complaint. Three levels of escape, in increasing effort:

  1. Utility classes and CSS variables. Override --bs-primary and the spacing utilities without touching the build.
  2. Your own stylesheet after the Bootstrap link. Later rules of equal specificity win, so a small override file goes a long way.
  3. A Sass build with customised variables. This is where the smaller, properly branded output comes from, and it needs a toolchain.

Level two covers most internal work. Load order matters: your file after theirs, or nothing you write will apply.

The cheapest single change is the accent colour. Overriding --bs-primary moves buttons, links and active states together, so the page stops looking like the default in one line.

After that, spacing. Bootstrap defaults are generous, and tightening the container padding and card spacing does more for a dense report than any colour change.

The grid, in one paragraph each

The grid is twelve columns wide at every breakpoint, and the column classes say how many of those twelve to take.

col-md-4 means four of twelve, so three across, from the medium breakpoint upward. Below that breakpoint the col-12 beside it applies and each card takes the full width.

Plain col with no number splits the row evenly between however many columns are present. That is the fastest way to lay out two or three equal blocks without counting.

Gutters live on the row. g-3 sets both horizontal and vertical spacing, gx-3 and gy-3 set them separately. Putting margins on the columns instead is the usual cause of a row that overflows its container.

One rule prevents most grid bugs: container, then row, then columns, then your content inside the column. Skipping a level is what produces the misalignment people assume is a framework problem.

Making the table useful

Report tables get three classes worth knowing, and they compose.

  • table-sm tightens the row height, which matters once there are more than about fifteen rows.
  • table-striped alternates row backgrounds, so the eye tracks across wide rows.
  • align-middle centres cell content vertically, which stops badges sitting on the baseline.

Wrap the whole table in table-responsive rather than trying to shrink the columns. Sideways scrolling is a better outcome on a phone than four squashed columns nobody can read.

Bootstrap against a utility framework

Bootstrap Tailwind
What you get Finished components Utility classes to build them
Time to a working page Minutes Minutes, more markup
Default appearance Recognisably Bootstrap Unstyled until you decide
Markup length Short class names Long class strings
Customising deeply Sass variables Config file and plugins

Neither is wrong. Pick the first column when the page needs to exist today and nobody will judge it on originality. The Tailwind HTML template is the other starter if you want the second column.

Sharing the finished page

The page depends on those two CDN references, so copy the file whole, head included. Strip the head and every class stops meaning anything.

Paste the complete HTML into a NOS document. It renders as written, at an address of its own. Then Share, Share link, Create link.

The Bootstrap page open from a shared link on a phone, cards stacked in one column.
The Bootstrap page open from a shared link on a phone, cards stacked in one column.

The address does not change when the numbers do, so next week's report replaces this week's at the same link. Turning HTML into a link is that step alone.

Before sending, open the file in the HTML file opener. A page that looks unstyled there is not loading its external stylesheet, which is exactly what the reader would have seen.

For pages that must work with no network at all, self-contained HTML explains how to fold the CSS inside instead.

Questions people ask

Do I need to install anything to use Bootstrap?

No. One stylesheet link and one script tag from a CDN are enough for the full framework, components included. Installing with a package manager matters when you want to customise the Sass variables and ship a smaller build.

Do I need the JavaScript bundle?

Only for components that move. Dropdowns, modals, tabs, tooltips, collapse and the offcanvas panel need it. A page of grids, cards, tables and buttons works from the stylesheet alone, and you can leave the script out.

Why does my Bootstrap layout not line up?

Almost always a missing wrapper. Columns must sit inside a row, and a row should sit inside a container. Skip the row and the columns lose their gutters and widths, which looks like the grid is broken when it is not loaded wrong.

Bootstrap or Tailwind for a quick internal page?

Bootstrap if you want finished components and do not care that pages look similar. Tailwind if you want control over appearance and are prepared to assemble components yourself. For a report that needs to exist this afternoon, Bootstrap is usually faster.

Keep reading