Typography, tables, images and content components

Use the type scale, table variants and card primitives so ordinary pages look deliberate without a stylesheet.

Headings, lead text and lists

Bootstrap does not restyle your h1 to a smaller size in nested contexts the way Bootstrap 4 did. Instead you detach the visual size from the semantic level: keep the correct heading element for the outline and add a display class for the look.

<h1 class="display-4">Ship faster</h1>
<p class="lead">Everything you need to build a responsive interface, without writing layout CSS.</p>
<p class="fs-6 fw-semibold text-uppercase text-body-secondary mb-1">Getting started</p>

<h2 class="h4">A semantically correct sub-heading that looks smaller</h2>

<ul class="list-unstyled">
  <li class="mb-2">No bullets, no padding — you style the marker yourself.</li>
</ul>

<ol class="list-group list-group-numbered">
  <li class="list-group-item d-flex justify-content-between align-items-start">
    <span>Install the package</span><span class="badge text-bg-primary rounded-pill">1</span>
  </li>
  <li class="list-group-item">Import the stylesheet</li>
</ol>
ClassEffectUse when
display-1display-6Fluid display scaleMarketing headings
leadLarger, lighter paragraphThe one introductory sentence
h1h6Heading appearance on any elementYou need the visual size without the tag
blockquote + blockquote-footerQuote with attributionTestimonials, citations
text-truncateSingle-line ellipsisTable cells and card titles
💡
text-truncate needs a width to truncate against. Inside a flex container also set min-w-0 on the flex child, or the child grows to fit the text and the ellipsis never appears.

Tables that survive real data

<div class="table-responsive">
  <table class="table table-hover align-middle caption-top">
    <caption>Invoices for September</caption>
    <thead class="table-light">
      <tr>
        <th scope="col">Invoice</th>
        <th scope="col" class="text-end">Amount</th>
        <th scope="col">Status</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th scope="row" class="fw-normal">#1041</th>
        <td class="text-end">82.00</td>
        <td><span class="badge text-bg-success">Paid</span></td>
      </tr>
      <tr class="table-warning">
        <th scope="row" class="fw-normal">#1042</th>
        <td class="text-end">140.00</td>
        <td><span class="badge text-bg-warning">Pending</span></td>
      </tr>
      <tr class="table-danger"><th scope="row" class="fw-normal">#1043</th><td class="text-end">12.50</td><td>Failed</td></tr>
    </tbody>
  </table>
</div>
  • table-responsive wraps the table in an element with overflow-x: auto — the table itself does not scroll.
  • Row variants (table-warning, table-danger) read through CSS custom properties, so they work in dark mode automatically.
  • Use <th scope="row"> for the leading cell of each row: it gives screen readers the row's own header instead of the column's.
  • table-sm halves cell padding; combined with align-middle it is the usual density for dashboards.
<!-- let Bootstrap paginate around a big table -->
<nav aria-label="Invoice pages">
  <ul class="pagination pagination-sm mb-0">
    <li class="page-item disabled"><a class="page-link" href="#" tabindex="-1" aria-disabled="true">Previous</a></li>
    <li class="page-item active" aria-current="page"><a class="page-link" href="#">1</a></li>
    <li class="page-item"><a class="page-link" href="#">2</a></li>
    <li class="page-item"><a class="page-link" href="#">Next</a></li>
  </ul>
</nav>

Images, figures and cards

<div class="row row-cols-1 row-cols-md-2 g-4">
  <div class="col">
    <div class="card h-100">
      <img src="/img/report.webp" class="card-img-top" alt="Quarterly report cover" width="640" height="360">
      <div class="card-body d-flex flex-column">
        <h2 class="card-title h6">Quarterly report</h2>
        <p class="card-text text-body-secondary flex-grow-1">Revenue grew 12% year over year.</p>
        <a href="#" class="btn btn-outline-primary btn-sm align-self-start">Open</a>
      </div>
    </div>
  </div>
</div>

<figure class="figure">
  <img src="/img/chart.webp" class="figure-img img-fluid rounded" alt="Revenue trend" width="800" height="400">
  <figcaption class="figure-caption">Revenue by month, 2026.</figcaption>
</figure>

<img src="/img/avatar.webp" class="rounded-circle object-fit-cover" width="48" height="48" alt="">
ClassWhat it doesGotcha
img-fluidmax-width: 100%, auto heightDoes nothing if the parent is wider than the image
object-fit-coverCrops instead of distortingRequires an explicit width and height on the element
ratio ratio-16x9Intrinsic-ratio wrapperThe child must be the only element and fill the box
h-100 on .cardEqual-height cards in a rowOnly works inside a row whose columns stretch

Setting width and height attributes on every image is not optional styling — it lets the browser reserve the space before the file arrives, which is the cheapest fix available for layout shift.

FAQ

Why is my table not scrolling horizontally?
The wrapper is missing, or an ancestor already scrolls. Put table-responsive directly around the <table> and make sure no parent has a fixed overflow: visible that lets the table push the page wider.
Can I use heading classes on non-heading elements?
Yes — that is the intended pattern. Keep <h2> for the real document outline and use h6 or fs-5 when you want a smaller visual size. Never skip heading levels purely to control size.

Layout beyond the grid: positioning and spacing recipes The grid system

Last refreshed 2026-09-18.