Open demo

CSS code

HTML
<div><span class="lbl">Rating summary with a breakdown and review cards</span>
<section class="rs" aria-labelledby="rs-title">
  <div class="rs-grid">
    <div class="rs-sum">
      <h2 id="rs-title">Customer reviews</h2>
      <div class="rs-score"><b>4.7</b><div><span class="st" style="--r:4.7" aria-hidden="true"></span><span class="sr-only">Rated 4.7 out of 5.</span><small>Based on 1,284 reviews</small></div></div>
      <ul class="rs-bars" role="list" aria-label="Rating breakdown">
      <li><span>5 stars</span><span class="rs-bar" aria-hidden="true"><span style="--w:78%"></span></span><span class="rs-pct">78%<span class="sr-only"> of reviews</span></span></li>
      <li><span>4 stars</span><span class="rs-bar" aria-hidden="true"><span style="--w:14%"></span></span><span class="rs-pct">14%<span class="sr-only"> of reviews</span></span></li>
      <li><span>3 stars</span><span class="rs-bar" aria-hidden="true"><span style="--w:5%"></span></span><span class="rs-pct">5%<span class="sr-only"> of reviews</span></span></li>
      <li><span>2 stars</span><span class="rs-bar" aria-hidden="true"><span style="--w:2%"></span></span><span class="rs-pct">2%<span class="sr-only"> of reviews</span></span></li>
      <li><span>1 star</span><span class="rs-bar" aria-hidden="true"><span style="--w:1%"></span></span><span class="rs-pct">1%<span class="sr-only"> of reviews</span></span></li>
      </ul>
      <a class="rs-write" href="#write-review">Write a review</a>
    </div>
    <ul class="rs-list" role="list" aria-label="Most recent reviews">
      <li><figure class="rs-card">
        <div class="rs-card-head"><span class="st" style="--r:5" aria-hidden="true"></span><span class="sr-only">Rated 5 out of 5.</span><p class="rs-title">Boils fast, pours slow</p></div>
        <blockquote><p>The gooseneck gives me a pour I can actually control, and the temperature hold means the second cup is as good as the first. It looks lovely on the counter too.</p></blockquote>
        <figcaption><strong>Isabel Moreau</strong><span class="rs-ok"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-09-12">12 September 2026</time></figcaption>
      </figure></li>
      <li><figure class="rs-card">
        <div class="rs-card-head"><span class="st" style="--r:4" aria-hidden="true"></span><span class="sr-only">Rated 4 out of 5.</span><p class="rs-title">Great kettle, small lid</p></div>
        <blockquote><p>Heats to the exact degree in about three minutes and holds it for half an hour. I take one star off because the lid opening is narrow and hard to clean inside.</p></blockquote>
        <figcaption><strong>Kenji Watanabe</strong><span class="rs-ok"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-08-30">30 August 2026</time></figcaption>
      </figure></li>
      <li><figure class="rs-card">
        <div class="rs-card-head"><span class="st" style="--r:3" aria-hidden="true"></span><span class="sr-only">Rated 3 out of 5.</span><p class="rs-title">Good pour, noisy base</p></div>
        <blockquote><p>The pour is excellent and the build feels solid. The base clicks loudly when it holds temperature, which I notice in a quiet kitchen at six in the morning.</p></blockquote>
        <figcaption><strong>Olivia Brennan</strong><span class="rs-ok"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-08-21">21 August 2026</time></figcaption>
      </figure></li>
    </ul>
  </div>
</section></div>

<div><span class="lbl">Compact rating badges</span>
<div class="rs rb-row">
  <p class="rb-pill"><span class="st" style="--r:4.7" aria-hidden="true"></span><span><b>4.7</b><span class="sr-only"> out of 5</span> · 1,284 reviews</span></p>
  <div class="rb-tile"><span class="rb-num" aria-hidden="true">4.9</span><div><b>Excellent</b><span class="st" style="--r:4.9" aria-hidden="true"></span><span class="sr-only">Rated 4.9 out of 5.</span><small>from 312 reviews</small></div></div>
  <p class="rb-inline"><span class="st" style="--r:4.2" aria-hidden="true"></span><span>4.2 out of 5</span><a class="rb-link" href="#reviews">Read 86 reviews</a></p>
</div></div>
CSS
/* Review summary: an average score, a five-row breakdown and star-rated review cards.
   The stars are one element: a gradient filled to the rating, masked by a repeating star shape, so a
   4.7 shows four and a bit. They are aria-hidden; the rating is always given as text. */
.rs{--rs-ink:#1c1917;--rs-muted:#57534e;--rs-line:#e7e5e4;--star:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.6l2.5 5.4 5.9.7-4.4 4 1.2 5.8L10 14.6l-5.2 2.9 1.2-5.8-4.4-4 5.9-.7z'/%3E%3C/svg%3E")}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.st{--s:18px;--r:5;flex:none;display:inline-block;width:calc(var(--s) * 5);height:var(--s);
  background:linear-gradient(90deg,var(--st-on,#d97706) calc(var(--r) * 20%),var(--st-off,#d6d3d1) 0);
  -webkit-mask:var(--star) 0 0/var(--s) var(--s) repeat-x;mask:var(--star) 0 0/var(--s) var(--s) repeat-x}
.rs-grid{display:grid;gap:24px;align-items:start}
@media (min-width:992px){.rs-grid{grid-template-columns:320px 1fr}}
.rs-sum{padding:28px;background:#fff;border:1px solid var(--rs-line);border-radius:20px}
.rs-sum h2{font-size:1.15rem;font-weight:800;color:var(--rs-ink)}
.rs-score{display:flex;align-items:center;gap:14px;margin-top:16px}
.rs-score b{font-size:3rem;font-weight:800;line-height:1;letter-spacing:-.03em;color:var(--rs-ink)}
.rs-score .st{--s:20px}
.rs-score small{display:block;margin-top:6px;font-size:.875rem;color:var(--rs-muted)}
.rs-bars{display:grid;gap:10px;margin:24px 0 0;padding:24px 0 0;list-style:none;border-top:1px solid var(--rs-line)}
.rs-bars li{display:grid;grid-template-columns:4.2em 1fr 4ch;align-items:center;gap:12px;font-size:.9rem;color:var(--rs-ink)}
.rs-bar{height:8px;border-radius:999px;background:#e7e5e4;overflow:hidden}
.rs-bar span{display:block;width:var(--w);height:100%;border-radius:inherit;background:#d97706}
.rs-bars .rs-pct{text-align:right;font-variant-numeric:tabular-nums;color:var(--rs-muted)}
.rs-write{display:block;margin-top:24px;padding:11px 16px;border:1.5px solid var(--rs-ink);border-radius:12px;text-align:center;font-weight:700;color:var(--rs-ink);text-decoration:none}
.rs-write:hover{background:var(--rs-ink);color:#fff}
.rs-write:focus-visible,.rb-link:focus-visible{outline:3px solid #b45309;outline-offset:3px}
.rs-list{display:grid;gap:16px;margin:0;padding:0;list-style:none}
.rs-card{margin:0;padding:24px 26px;background:#fff;border:1px solid var(--rs-line);border-radius:20px}
.rs-card-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px}
.rs-card-head .st{--s:16px}
.rs-title{font-weight:800;color:var(--rs-ink)}
.rs-card blockquote{margin:10px 0 0;line-height:1.65;color:#292524}
.rs-card figcaption{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin-top:16px;font-size:.875rem;color:var(--rs-muted)}
.rs-card figcaption strong{color:var(--rs-ink)}
.rs-ok{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;background:#dcfce7;font-size:.75rem;font-weight:700;color:#166534}

/* Compact rating badges */
.rb-row{display:flex;flex-wrap:wrap;align-items:center;gap:20px}
.rb-pill{display:inline-flex;align-items:center;gap:10px;padding:10px 16px;background:#fff;border:1px solid var(--rs-line);border-radius:999px;font-size:.9rem;color:var(--rs-muted)}
.rb-pill .st{--s:16px}
.rb-pill b{color:var(--rs-ink)}
.rb-tile{display:flex;align-items:center;gap:14px;padding:12px 18px 12px 12px;background:#fff;border:1px solid var(--rs-line);border-radius:16px}
.rb-num{display:grid;place-items:center;width:56px;height:56px;border-radius:12px;background:#166534;color:#fff;font-size:1.4rem;font-weight:800}
.rb-tile .st{--s:14px;--st-on:#15803d}
.rb-tile b{display:block;color:var(--rs-ink)}
.rb-tile small{display:block;font-size:.8rem;color:var(--rs-muted)}
.rb-inline{display:inline-flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:.9rem;color:var(--rs-ink)}
.rb-inline .st{--s:16px}
.rb-link{font-weight:700;color:#9a3412;text-underline-offset:3px;border-radius:3px}
.rb-link:hover{color:#7c2d12}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div><span class="lbl">Rating summary with a breakdown and review cards</span>
<section class="rs" aria-labelledby="rs-title">
  <div class="row g-4 align-items-start">
    <div class="col-lg-auto rs-col"><div class="card rs-sum"><div class="card-body">
      <h2 id="rs-title">Customer reviews</h2>
      <div class="rs-score d-flex align-items-center gap-3 mt-3"><b>4.7</b><div><span class="st" style="--r:4.7" aria-hidden="true"></span><span class="visually-hidden">Rated 4.7 out of 5.</span><small class="d-block mt-1 rs-muted">Based on 1,284 reviews</small></div></div>
      <ul class="rs-bars list-unstyled d-grid mt-4 mb-0 pt-4" role="list" aria-label="Rating breakdown">
        <li><span>5 stars</span><div class="progress" aria-hidden="true"><div class="progress-bar" style="width:78%"></div></div><span class="rs-pct">78%<span class="visually-hidden"> of reviews</span></span></li>
        <li><span>4 stars</span><div class="progress" aria-hidden="true"><div class="progress-bar" style="width:14%"></div></div><span class="rs-pct">14%<span class="visually-hidden"> of reviews</span></span></li>
        <li><span>3 stars</span><div class="progress" aria-hidden="true"><div class="progress-bar" style="width:5%"></div></div><span class="rs-pct">5%<span class="visually-hidden"> of reviews</span></span></li>
        <li><span>2 stars</span><div class="progress" aria-hidden="true"><div class="progress-bar" style="width:2%"></div></div><span class="rs-pct">2%<span class="visually-hidden"> of reviews</span></span></li>
        <li><span>1 star</span><div class="progress" aria-hidden="true"><div class="progress-bar" style="width:1%"></div></div><span class="rs-pct">1%<span class="visually-hidden"> of reviews</span></span></li>
      </ul>
      <a class="btn rs-write w-100 mt-4" href="#write-review">Write a review</a>
    </div></div></div>
    <div class="col-lg">
    <ul class="list-unstyled d-grid gap-3 mb-0" role="list" aria-label="Most recent reviews">
      <li><figure class="card rs-card mb-0"><div class="card-body">
        <div class="d-flex flex-wrap align-items-center column-gap-3 row-gap-1"><span class="st" style="--r:5" aria-hidden="true"></span><span class="visually-hidden">Rated 5 out of 5.</span><p class="fw-bolder mb-0">Boils fast, pours slow</p></div>
        <blockquote class="mt-2 mb-0"><p class="mb-0">The gooseneck gives me a pour I can actually control, and the temperature hold means the second cup is as good as the first. It looks lovely on the counter too.</p></blockquote>
        <figcaption class="d-flex flex-wrap align-items-center column-gap-3 row-gap-1 mt-3 rs-muted"><strong class="text-body-emphasis">Isabel Moreau</strong><span class="badge rounded-pill rs-ok d-inline-flex align-items-center gap-1"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-09-12">12 September 2026</time></figcaption>
      </div></figure></li>
      <li><figure class="card rs-card mb-0"><div class="card-body">
        <div class="d-flex flex-wrap align-items-center column-gap-3 row-gap-1"><span class="st" style="--r:4" aria-hidden="true"></span><span class="visually-hidden">Rated 4 out of 5.</span><p class="fw-bolder mb-0">Great kettle, small lid</p></div>
        <blockquote class="mt-2 mb-0"><p class="mb-0">Heats to the exact degree in about three minutes and holds it for half an hour. I take one star off because the lid opening is narrow and hard to clean inside.</p></blockquote>
        <figcaption class="d-flex flex-wrap align-items-center column-gap-3 row-gap-1 mt-3 rs-muted"><strong class="text-body-emphasis">Kenji Watanabe</strong><span class="badge rounded-pill rs-ok d-inline-flex align-items-center gap-1"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-08-30">30 August 2026</time></figcaption>
      </div></figure></li>
      <li><figure class="card rs-card mb-0"><div class="card-body">
        <div class="d-flex flex-wrap align-items-center column-gap-3 row-gap-1"><span class="st" style="--r:3" aria-hidden="true"></span><span class="visually-hidden">Rated 3 out of 5.</span><p class="fw-bolder mb-0">Good pour, noisy base</p></div>
        <blockquote class="mt-2 mb-0"><p class="mb-0">The pour is excellent and the build feels solid. The base clicks loudly when it holds temperature, which I notice in a quiet kitchen at six in the morning.</p></blockquote>
        <figcaption class="d-flex flex-wrap align-items-center column-gap-3 row-gap-1 mt-3 rs-muted"><strong class="text-body-emphasis">Olivia Brennan</strong><span class="badge rounded-pill rs-ok d-inline-flex align-items-center gap-1"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-08-21">21 August 2026</time></figcaption>
      </div></figure></li>
    </ul>
    </div>
  </div>
</section></div>

<div><span class="lbl">Compact rating badges</span>
<div class="rs d-flex flex-wrap align-items-center gap-4">
  <p class="rb-pill rounded-pill d-inline-flex align-items-center gap-2 mb-0"><span class="st" style="--r:4.7" aria-hidden="true"></span><span><b class="text-body-emphasis">4.7</b><span class="visually-hidden"> out of 5</span> · 1,284 reviews</span></p>
  <div class="card rb-tile flex-row align-items-center gap-3 py-2 ps-2 pe-3"><span class="rb-num" aria-hidden="true">4.9</span><div><b class="d-block">Excellent</b><span class="st" style="--r:4.9" aria-hidden="true"></span><span class="visually-hidden">Rated 4.9 out of 5.</span><small class="d-block">from 312 reviews</small></div></div>
  <p class="rb-inline d-inline-flex flex-wrap align-items-center gap-2 mb-0"><span class="st" style="--r:4.2" aria-hidden="true"></span><span>4.2 out of 5</span><a class="rb-link" href="#reviews">Read 86 reviews</a></p>
</div></div>
CSS
/* Bootstrap: .card panels, a .progress per breakdown row, .badge for verified buyers and
   .visually-hidden for the text ratings. The star element is the same masked gradient. */
.rs{--rs-ink:#1c1917;--rs-muted:#57534e;--rs-line:#e7e5e4;--star:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.6l2.5 5.4 5.9.7-4.4 4 1.2 5.8L10 14.6l-5.2 2.9 1.2-5.8-4.4-4 5.9-.7z'/%3E%3C/svg%3E");color:var(--rs-ink)}
.st{--s:18px;--r:5;flex:none;display:inline-block;width:calc(var(--s) * 5);height:var(--s);
  background:linear-gradient(90deg,var(--st-on,#d97706) calc(var(--r) * 20%),var(--st-off,#d6d3d1) 0);
  -webkit-mask:var(--star) 0 0/var(--s) var(--s) repeat-x;mask:var(--star) 0 0/var(--s) var(--s) repeat-x}
.rs .card{--bs-card-border-color:var(--rs-line);--bs-card-border-radius:20px;--bs-card-color:var(--rs-ink)}
.rs-sum{--bs-card-spacer-y:28px;--bs-card-spacer-x:28px}
.rs-sum h2{font-size:1.15rem;font-weight:800;margin:0}
.rs-score b{font-size:3rem;font-weight:800;line-height:1;letter-spacing:-.03em}
.rs-score .st{--s:20px}
.rs-muted{font-size:.875rem;color:var(--rs-muted)}
.rs-bars{gap:10px;border-top:1px solid var(--rs-line)}
.rs-bars li{display:grid;grid-template-columns:4.2em 1fr 4ch;align-items:center;gap:12px;font-size:.9rem}
.rs-bars .progress{--bs-progress-height:8px;--bs-progress-bg:#e7e5e4;--bs-progress-bar-bg:#d97706;--bs-progress-border-radius:999px}
.rs-bars .progress-bar{border-radius:999px}
.rs-pct{text-align:right;font-variant-numeric:tabular-nums;color:var(--rs-muted)}
.rs-write{--bs-btn-padding-y:11px;--bs-btn-font-weight:700;--bs-btn-color:var(--rs-ink);--bs-btn-border-color:var(--rs-ink);--bs-btn-border-width:1.5px;
  --bs-btn-hover-bg:var(--rs-ink);--bs-btn-hover-border-color:var(--rs-ink);--bs-btn-border-radius:12px}
.rs-write:focus-visible,.rb-link:focus-visible{outline:3px solid #b45309;outline-offset:3px;box-shadow:none}
.rs-card{--bs-card-spacer-y:24px;--bs-card-spacer-x:26px}
.rs-card-head .st{--s:16px}
.rs-card blockquote{line-height:1.65;color:#292524}
.rs-ok{--bs-badge-padding-x:8px;--bs-badge-padding-y:2px;--bs-badge-font-size:.75rem;--bs-badge-color:#166534;line-height:1.5;background:#dcfce7}
.rb-pill{padding:10px 16px;background:#fff;border:1px solid var(--rs-line);font-size:.9rem;color:var(--rs-muted)}
.rb-pill .st{--s:16px}
.rb-tile{--bs-card-border-radius:16px}
.rb-num{display:grid;place-items:center;width:56px;height:56px;border-radius:12px;background:#166534;color:#fff;font-size:1.4rem;font-weight:800}
.rb-tile .st{--s:14px;--st-on:#15803d}
.rb-tile small{font-size:.8rem;color:var(--rs-muted)}
.rb-inline{font-size:.9rem}
.rb-inline .st{--s:16px}
.rb-link{--bs-link-color-rgb:154,52,18;--bs-link-hover-color-rgb:124,45,18;font-weight:700;text-underline-offset:3px;border-radius:3px}

@media (min-width:992px){.rs-col{width:344px}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div><span class="mb-[18px] block text-[.72rem] tracking-[.12em] text-[#57534e] uppercase">Rating summary with a breakdown and review cards</span>
<section class="text-rs-ink" aria-labelledby="rs-title">
  <div class="grid items-start gap-6 lg:grid-cols-[320px_1fr]">
    <div class="rounded-[20px] border border-rs-line bg-white p-7">
      <h2 id="rs-title" class="text-[1.15rem] font-extrabold">Customer reviews</h2>
      <div class="mt-4 flex items-center gap-3.5"><b class="text-5xl leading-none font-extrabold tracking-[-.03em]">4.7</b><div><span class="stars" style="--r:4.7;--s:20px" aria-hidden="true"></span><span class="sr-only">Rated 4.7 out of 5.</span><small class="mt-1.5 block text-[.875rem] text-rs-muted">Based on 1,284 reviews</small></div></div>
      <ul class="mt-6 grid gap-2.5 border-t border-rs-line pt-6" role="list" aria-label="Rating breakdown">
        <li class="grid grid-cols-[4.2em_1fr_4ch] items-center gap-3 text-[.9rem]"><span>5 stars</span><span class="h-2 overflow-hidden rounded-full bg-[#e7e5e4]" aria-hidden="true"><span class="block h-full rounded-full bg-[#d97706]" style="width:78%"></span></span><span class="text-right text-rs-muted tabular-nums">78%<span class="sr-only"> of reviews</span></span></li>
        <li class="grid grid-cols-[4.2em_1fr_4ch] items-center gap-3 text-[.9rem]"><span>4 stars</span><span class="h-2 overflow-hidden rounded-full bg-[#e7e5e4]" aria-hidden="true"><span class="block h-full rounded-full bg-[#d97706]" style="width:14%"></span></span><span class="text-right text-rs-muted tabular-nums">14%<span class="sr-only"> of reviews</span></span></li>
        <li class="grid grid-cols-[4.2em_1fr_4ch] items-center gap-3 text-[.9rem]"><span>3 stars</span><span class="h-2 overflow-hidden rounded-full bg-[#e7e5e4]" aria-hidden="true"><span class="block h-full rounded-full bg-[#d97706]" style="width:5%"></span></span><span class="text-right text-rs-muted tabular-nums">5%<span class="sr-only"> of reviews</span></span></li>
        <li class="grid grid-cols-[4.2em_1fr_4ch] items-center gap-3 text-[.9rem]"><span>2 stars</span><span class="h-2 overflow-hidden rounded-full bg-[#e7e5e4]" aria-hidden="true"><span class="block h-full rounded-full bg-[#d97706]" style="width:2%"></span></span><span class="text-right text-rs-muted tabular-nums">2%<span class="sr-only"> of reviews</span></span></li>
        <li class="grid grid-cols-[4.2em_1fr_4ch] items-center gap-3 text-[.9rem]"><span>1 star</span><span class="h-2 overflow-hidden rounded-full bg-[#e7e5e4]" aria-hidden="true"><span class="block h-full rounded-full bg-[#d97706]" style="width:1%"></span></span><span class="text-right text-rs-muted tabular-nums">1%<span class="sr-only"> of reviews</span></span></li>
      </ul>
      <a class="mt-6 block rounded-xl border-[1.5px] border-rs-ink px-4 py-[11px] text-center font-bold text-rs-ink no-underline hover:bg-rs-ink hover:text-white focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-[#b45309]" href="#write-review">Write a review</a>
    </div>
    <ul class="grid gap-4" role="list" aria-label="Most recent reviews">
      <li><figure class="rounded-[20px] border border-rs-line bg-white px-[26px] py-6">
        <div class="flex flex-wrap items-center gap-x-3 gap-y-1.5"><span class="stars" style="--r:5;--s:16px" aria-hidden="true"></span><span class="sr-only">Rated 5 out of 5.</span><p class="font-extrabold">Boils fast, pours slow</p></div>
        <blockquote class="mt-2.5 leading-[1.65] text-[#292524]"><p>The gooseneck gives me a pour I can actually control, and the temperature hold means the second cup is as good as the first. It looks lovely on the counter too.</p></blockquote>
        <figcaption class="mt-4 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-[.875rem] text-rs-muted"><strong class="text-rs-ink">Isabel Moreau</strong><span class="inline-flex items-center gap-1 rounded-full bg-[#dcfce7] px-2 py-0.5 text-[.75rem] font-bold text-[#166534]"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-09-12">12 September 2026</time></figcaption>
      </figure></li>
      <li><figure class="rounded-[20px] border border-rs-line bg-white px-[26px] py-6">
        <div class="flex flex-wrap items-center gap-x-3 gap-y-1.5"><span class="stars" style="--r:4;--s:16px" aria-hidden="true"></span><span class="sr-only">Rated 4 out of 5.</span><p class="font-extrabold">Great kettle, small lid</p></div>
        <blockquote class="mt-2.5 leading-[1.65] text-[#292524]"><p>Heats to the exact degree in about three minutes and holds it for half an hour. I take one star off because the lid opening is narrow and hard to clean inside.</p></blockquote>
        <figcaption class="mt-4 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-[.875rem] text-rs-muted"><strong class="text-rs-ink">Kenji Watanabe</strong><span class="inline-flex items-center gap-1 rounded-full bg-[#dcfce7] px-2 py-0.5 text-[.75rem] font-bold text-[#166534]"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-08-30">30 August 2026</time></figcaption>
      </figure></li>
      <li><figure class="rounded-[20px] border border-rs-line bg-white px-[26px] py-6">
        <div class="flex flex-wrap items-center gap-x-3 gap-y-1.5"><span class="stars" style="--r:3;--s:16px" aria-hidden="true"></span><span class="sr-only">Rated 3 out of 5.</span><p class="font-extrabold">Good pour, noisy base</p></div>
        <blockquote class="mt-2.5 leading-[1.65] text-[#292524]"><p>The pour is excellent and the build feels solid. The base clicks loudly when it holds temperature, which I notice in a quiet kitchen at six in the morning.</p></blockquote>
        <figcaption class="mt-4 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-[.875rem] text-rs-muted"><strong class="text-rs-ink">Olivia Brennan</strong><span class="inline-flex items-center gap-1 rounded-full bg-[#dcfce7] px-2 py-0.5 text-[.75rem] font-bold text-[#166534]"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>Verified buyer</span><time datetime="2026-08-21">21 August 2026</time></figcaption>
      </figure></li>
    </ul>
  </div>
</section></div>

<div><span class="mb-[18px] block text-[.72rem] tracking-[.12em] text-[#57534e] uppercase">Compact rating badges</span>
<div class="flex flex-wrap items-center gap-5 text-rs-ink">
  <p class="inline-flex items-center gap-2.5 rounded-full border border-rs-line bg-white px-4 py-2.5 text-[.9rem] text-rs-muted"><span class="stars" style="--r:4.7;--s:16px" aria-hidden="true"></span><span><b class="text-rs-ink">4.7</b><span class="sr-only"> out of 5</span> · 1,284 reviews</span></p>
  <div class="flex items-center gap-3.5 rounded-2xl border border-rs-line bg-white py-3 pr-[18px] pl-3"><span class="grid size-14 place-items-center rounded-xl bg-[#166534] text-[1.4rem] font-extrabold text-white" aria-hidden="true">4.9</span><div><b class="block">Excellent</b><span class="stars" style="--r:4.9;--s:14px;--st-on:#15803d" aria-hidden="true"></span><span class="sr-only">Rated 4.9 out of 5.</span><small class="block text-[.8rem] text-rs-muted">from 312 reviews</small></div></div>
  <p class="inline-flex flex-wrap items-center gap-2 text-[.9rem]"><span class="stars" style="--r:4.2;--s:16px" aria-hidden="true"></span><span>4.2 out of 5</span><a class="rounded-[3px] font-bold text-[#9a3412] underline underline-offset-3 hover:text-[#7c2d12] focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-[#b45309]" href="#reviews">Read 86 reviews</a></p>
</div></div>
CSS
@theme {
  --color-rs-ink: #1c1917;
  --color-rs-muted: #57534e;
  --color-rs-line: #e7e5e4;
}
/* Star rating: a gradient filled to --r (out of 5) under a repeating star mask. Set --s for the size. */
@utility stars {
  --s: 18px;
  --star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.6l2.5 5.4 5.9.7-4.4 4 1.2 5.8L10 14.6l-5.2 2.9 1.2-5.8-4.4-4 5.9-.7z'/%3E%3C/svg%3E");
  flex: none;
  display: inline-block;
  width: calc(var(--s) * 5);
  height: var(--s);
  background: linear-gradient(90deg, var(--st-on, #d97706) calc(var(--r, 5) * 20%), var(--st-off, #d6d3d1) 0);
  -webkit-mask: var(--star) 0 0 / var(--s) var(--s) repeat-x;
  mask: var(--star) 0 0 / var(--s) var(--s) repeat-x;
}

About this set

The ratings block from a product page: an average score, a breakdown of how many reviews gave each star rating, and the latest reviews, plus compact badges for use elsewhere. The rating summary shows 4.7 out of 5 from 1,284 reviews, a five-row bar chart with the percentage printed beside every bar, and a Write a review button, next to three review cards with stars, a headline, the review, the reviewer’s name, a Verified buyer badge and a date. The compact badges are a rating pill, a green score tile reading Excellent, and an inline rating with a Read 86 reviews link. The stars are a single element: a gradient filled to the rating and masked with a repeating star shape, so a 4.7 shows four full stars and most of the fifth without any icon font. Stars and bars are aria-hidden and every rating and percentage is also written as text, so nothing depends on seeing the graphics.

What’s included

  • Average score, five-row breakdown and three review cards
  • Partial stars from one masked gradient element
  • Every rating and percentage also given as text
  • Verified buyer badge and machine-readable review dates
  • Three compact badges: pill, score tile, inline link

Accessibility

Star graphics and bars are aria-hidden; each rating is given as visually hidden text such as Rated 4.7 out of 5, and each bar row reads like 5 stars, 78% of reviews. Review dates use the time element. Links show a 3px amber focus outline, and all text meets 4.5:1.

Customise it

Change --st-on, --st-off and the size --s on .st, and the bar colour in .rs-bar span. Bootstrap uses .progress with --bs-progress-bar-bg; in Tailwind the same variables go in the style attribute and the stars utility is defined once with @utility.