Show "4.5 / 5" or any fractional rating as 4 solid stars + 1 half star, rendered with a single inline SVG using a linearGradient with a hard stop at the half-mark. No icon-font, no JS, scales perfectly.
<svg viewBox="0 0 120 20" width="120" height="20" aria-label="4.5 out of 5 stars">
<!-- 4 full stars at x = 1, 25, 49, 73, 97 (24px stride) -->
<polygon points="10,1 13,7 19,7.5 14.5,12 15.8,18 10,15 4.2,18 5.5,12 1,7.5 7,7" fill="#FF9900"/>
<polygon points="34,1 37,7 43,7.5 38.5,12 39.8,18 34,15 28.2,18 29.5,12 25,7.5 31,7" fill="#FF9900"/>
<polygon points="58,1 61,7 67,7.5 62.5,12 63.8,18 58,15 52.2,18 53.5,12 49,7.5 55,7" fill="#FF9900"/>
<polygon points="82,1 85,7 91,7.5 86.5,12 87.8,18 82,15 76.2,18 77.5,12 73,7.5 79,7" fill="#FF9900"/>
<!-- Half-gold gradient: hard stop at 50%, second color at 25% opacity -->
<defs>
<linearGradient id="halfGold" x1="0" x2="1">
<stop offset="50%" stop-color="#FF9900"/>
<stop offset="50%" stop-color="#FF9900" stop-opacity="0.25"/>
</linearGradient>
</defs>
<!-- 5th star uses the gradient as fill -->
<polygon points="106,1 109,7 115,7.5 110.5,12 111.8,18 106,15 100.2,18 101.5,12 97,7.5 103,7" fill="url(#halfGold)"/>
</svg>
The gradient. Two stops, both at offset="50%". The
first stop is full-opacity gold; the second is the same gold at 25% opacity. Because
both are AT the same position, the transition is instant — a vertical line down the
middle of the star. The left half renders solid gold; the right half renders as a
faded ghost.
The polygon. Standard 5-point star polygon. Same shape repeated
with the x coordinates translated by 24px for each subsequent star. The 5th star is
identical to the others but its fill is url(#halfGold)
instead of a flat color.
Why this beats text "★★★★½". Half-star Unicode (½)
doesn't exist as a star character — you'd have to either fudge it ("★★★★⯨" looks
off) or use one of the partial-star Unicode characters that doesn't render
consistently across fonts. The SVG approach renders identically everywhere.
Star color. Amazon-style gold is #FF9900. Trustpilot
green is #00B67A. App Store dark gold is #FFB800. Match the
source's actual color for legitimacy signal.
Ghost opacity. 0.25 reads clearly as "empty" without disappearing. 0.4 starts looking too solid; 0.15 disappears. The 25% mark is the sweet spot.
Multiple half-star ratings on the same page. Each
<linearGradient id="..."> must have a unique ID — I use
halfGold for the homepage rating, halfGoldP for the product
page, etc. If two SVGs share an ID, only the first gradient renders.
Other fractions. Change offset="50%" on both stops
to "33%" for a one-third star, "66%" for two-thirds, etc.
Useful when displaying e.g. 4.3 (small half) or 4.7 (large half).
Accessibility. The aria-label="4.5 out of 5 stars"
on the SVG is mandatory — screen readers can't parse the visual gradient. Always
pair the SVG with visible text ("4,4 / 5") for sighted users too.
Gradient IDs collide site-wide. If you use this on the homepage
with id="halfGold" and on a product page also with id="halfGold"
but a different color, the second one inherits the first's gradient — common bug
when copy-pasting between pages. Suffix IDs: halfGoldH (home),
halfGoldP (product), etc.
SVG inheritance. If you wrap the SVG in a parent that sets
color, you can use fill="currentColor" on the polygons
and color-theme via CSS. Useful for dark/light theme swaps without duplicating
the SVG.
Comma-decimal locales. In Spanish, the rating displays as "4,4" (comma) not "4.4" (period). Don't hard-code "4.4" in the visible text; match the locale convention.
Source: Mithjem product pages + homepage trust bar (2026-05-22+).
Pattern reused across 4 stars + 1 half = "4,4 / 5" for the Amazon rating display.
Each instance gets its own gradient ID (halfGold, halfGoldP,
halfGoldH).