✦ A decade of Canvas craft, now driven by AI — describe it, watch it build live.Start building
Bootstrap 5Content

Bootstrap 5 Rating Stars

A rating stars component displays a row of star icons that represent a score, typically on a scale of one to five. Bootstrap 5 has no official rating stars component, so this pattern composes flex utilities, text colour helpers, Unicode or SVG star characters, and optionally hidden radio inputs for interactive variants. Use it wherever user-generated scores or review summaries must be presented clearly alongside product listings, testimonials, or content cards.

Primary Class

d-flex align-items-center gap-1

Common Use Cases

  • An e-commerce product page displays an average customer rating of 4.2 stars beneath the product title, using filled and empty star characters coloured with Bootstrap's text-warning utility.
  • A hotel booking platform renders an interactive five-star radio input group on each review submission form, letting users click a star to set their score before posting.
  • A SaaS dashboard shows a read-only aggregate satisfaction score for each support ticket, combining a compact star row with a small badge showing the numeric value.
  • A mobile restaurant app renders star ratings inside Bootstrap card components on a search results grid, keeping the stars inline with the cuisine label and review count.

Variants & Classes

VariantDescription
Read-only displayNon-interactive stars built from span elements containing Unicode star characters, coloured with text-warning for filled stars and text-secondary for empty ones. Uses d-flex, align-items-center, and gap-1 to space the icons.
Interactive radioAccessible interactive rating using visually hidden radio inputs paired with label elements containing star characters. CSS sibling selectors fill stars on hover and checked state. Wraps in a d-flex flex-row-reverse justify-content-end container to achieve right-to-left fill with pure CSS.
With numeric labelRead-only star row accompanied by a Bootstrap badge or small text element showing the numeric score and review count. Combines d-flex, align-items-center, gap-2, and badge bg-warning text-dark for the score chip.
Compact inlineReduced-size stars intended for use inside table rows, list groups, or tight card footers. Uses fs-6 or a custom font-size override and text-warning, keeping the entire row on one line with d-inline-flex.

Code Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Rating Stars</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
  <style>
    /* Interactive rating: flex-row-reverse lets CSS sibling selectors fill stars to the left */
    .star-rating {
      display: inline-flex;
      flex-direction: row-reverse;
      gap: 0.15rem;
    }
    .star-rating input[type="radio"] {
      position: absolute;
      opacity: 0;
      width: 0;
      height: 0;
    }
    .star-rating label {
      font-size: 1.75rem;
      color: #dee2e6;
      cursor: pointer;
      transition: color 0.1s ease;
      line-height: 1;
    }
    /* Fill this star and all stars to its left (higher value, rendered to the right in DOM but left visually) */
    .star-rating input[type="radio"]:checked ~ label,
    .star-rating label:hover,
    .star-rating label:hover ~ label {
      color: #ffc107;
    }
    /* Read-only partial star support via clip-path */
    .star-partial-wrap {
      position: relative;
      display: inline-block;
      font-size: 1.5rem;
      line-height: 1;
    }
    .star-partial-wrap .star-bg {
      color: #dee2e6;
    }
    .star-partial-wrap .star-fill {
      position: absolute;
      top: 0;
      left: 0;
      overflow: hidden;
      color: #ffc107;
    }
  </style>
</head>
<body class="p-4">

  <!-- 1. Read-only display stars -->
  <section class="mb-5">
    <h2 class="h5 mb-3">Read-only Rating (4 of 5)</h2>
    <div class="d-flex align-items-center gap-2">
      <div class="d-flex align-items-center gap-1" role="img" aria-label="Rated 4 out of 5 stars">
        <span class="text-warning fs-4" aria-hidden="true">&#9733;</span>
        <span class="text-warning fs-4" aria-hidden="true">&#9733;</span>
        <span class="text-warning fs-4" aria-hidden="true">&#9733;</span>
        <span class="text-warning fs-4" aria-hidden="true">&#9733;</span>
        <span class="text-secondary fs-4" aria-hidden="true">&#9733;</span>
      </div>
      <span class="badge bg-warning text-dark">4.0</span>
      <small class="text-muted">(128 reviews)</small>
    </div>
  </section>

  <!-- 2. Interactive radio rating -->
  <section class="mb-5">
    <h2 class="h5 mb-3">Interactive Rating</h2>
    <fieldset>
      <legend class="visually-hidden">Rate this product</legend>
      <div class="star-rating" id="interactive-rating">
        <input type="radio" name="rating" id="star5" value="5">
        <label for="star5" title="5 stars" aria-label="5 stars">&#9733;</label>
        <input type="radio" name="rating" id="star4" value="4">
        <label for="star4" title="4 stars" aria-label="4 stars">&#9733;</label>
        <input type="radio" name="rating" id="star3" value="3">
        <label for="star3" title="3 stars" aria-label="3 stars">&#9733;</label>
        <input type="radio" name="rating" id="star2" value="2">
        <label for="star2" title="2 stars" aria-label="2 stars">&#9733;</label>
        <input type="radio" name="rating" id="star1" value="1">
        <label for="star1" title="1 star" aria-label="1 star">&#9733;</label>
      </div>
    </fieldset>
  </section>

  <!-- 3. Product card with compact inline stars -->
  <section class="mb-5">
    <h2 class="h5 mb-3">Product Card with Rating</h2>
    <div class="card" style="max-width:320px">
      <div class="card-body">
        <h5 class="card-title">Wireless Headphones</h5>
        <div class="d-flex align-items-center gap-2 mb-2">
          <div class="d-inline-flex align-items-center gap-1 fs-6" role="img" aria-label="Rated 4.5 out of 5 stars">
            <span class="text-warning" aria-hidden="true">&#9733;</span>
            <span class="text-warning" aria-hidden="true">&#9733;</span>
            <span class="text-warning" aria-hidden="true">&#9733;</span>
            <span class="text-warning" aria-hidden="true">&#9733;</span>
            <span class="text-warning" aria-hidden="true">&#9734;</span>
          </div>
          <small class="text-muted fw-semibold">4.5</small>
          <small class="text-muted">&bull; 93 ratings</small>
        </div>
        <p class="card-text text-muted small">Premium noise-cancelling headphones with 30-hour battery life.</p>
        <a href="#" class="btn btn-primary btn-sm">View product</a>
      </div>
    </div>
  </section>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Live Examples

Read-only stars with badge

A simple read-only row of Unicode star characters coloured with Bootstrap text-warning and text-secondary, accompanied by a numeric badge. No custom CSS required beyond what Bootstrap ships.

Example 1

Interactive radio stars in a review form

Accessible five-star selector using hidden radio inputs and CSS sibling selectors. The flex-row-reverse trick means no JavaScript is needed to fill stars from left to right on hover and selection.

Example 2

Compact stars inside a Bootstrap list group

Inline stars sized with fs-6 placed inside a list-group-item alongside text content, demonstrating how the component integrates within Bootstrap's list group primitive without disrupting vertical rhythm.

Example 3

Canvas Framework Variants

The Canvas template extends Bootstrap 5 with 1,658+ component variants. Generate any of these using Canvas Builder:

  • Read-only five-star display with numeric badge generated from a product review prompt
  • Interactive radio star picker inside a Canvas-generated review submission form
  • Compact inline stars auto-inserted into product grid cards by Canvas Builder
  • Star rating row with half-star approximation rendered inside a Canvas testimonial section
  • Aggregated star summary with review count placed in a Canvas-generated pricing comparison table

Best Practices

Use role and aria-label on the wrapper, not individual spans

Screen readers do not need to announce each star character individually. Apply role="img" and aria-label="Rated X out of 5 stars" to the containing div, then add aria-hidden="true" to every star span. This gives assistive technology a clean, meaningful description without reading five separate symbols.

Achieve the hover-fill trick without JavaScript using flex-row-reverse

Place radio inputs in descending order (5, 4, 3, 2, 1) inside a flex-direction: row-reverse container. The CSS general sibling combinator (~) can then select all labels that follow a checked input in DOM order, which visually corresponds to all stars to the left of the selection. This avoids any JavaScript event listeners for the interactive variant.

Avoid text-warning on dark backgrounds without adjustment

Bootstrap's text-warning maps to #ffc107, which has insufficient contrast against white card backgrounds for small text but is acceptable for large decorative icons. If your design places stars on a dark card (bg-dark or bg-primary), switch the empty stars to text-light rather than text-secondary, and test the filled stars against your background with a contrast checker.

Server-render the correct filled/empty state to avoid layout shift

For read-only ratings fetched from a database, compute the integer and fractional parts on the server and render the appropriate number of filled &#9733; and empty &#9733; spans directly in HTML. Avoid calculating this in client-side JavaScript after page load, as a flash of all-empty or all-filled stars creates visible layout shift and a poor experience on slower connections.

FAQ

Does Bootstrap 5 include a built-in rating stars component or class?
No. Bootstrap 5 ships no official rating or star component. The pattern on this page is assembled from Bootstrap's own utility classes — d-flex, align-items-center, gap-1, text-warning, text-secondary, fs-4, and badge — combined with a small block of custom CSS for the interactive radio variant. You are not using any undocumented Bootstrap internals.
How do I display a half-star, for example 3.5 out of 5?
Bootstrap has no half-star primitive. The simplest approach is to use the outline star character &#9734; (&#9734;) for empty slots and a full star &#9733; (&#9733;) for filled, and round to the nearest whole number for display. If you need true half-star fidelity, render a full star behind a half-width clipped duplicate using position: absolute and overflow: hidden on a wrapper element, as shown in the codeExample's .star-partial-wrap pattern.
How do I make the interactive star rating accessible to keyboard users?
Because the interactive variant uses real radio input elements, keyboard accessibility is inherited automatically. Users can Tab into the fieldset and then use the arrow keys to move between the five radio options, exactly as they would with any radio group. Ensure each input has a unique id and each label's for attribute matches that id. Wrapping the group in a fieldset with a descriptive legend completes the accessible pattern.
Can I use Bootstrap Icons or Font Awesome stars instead of Unicode characters?
Yes. Replace each Unicode star span with a Bootstrap Icons i element such as <i class="bi bi-star-fill text-warning"></i> for filled and <i class="bi bi-star text-secondary"></i> for empty, after including the Bootstrap Icons stylesheet. The same d-flex, gap-1, and text colour utilities apply unchanged. Font Awesome equivalents are fas fa-star and far fa-star, used in the same way.