Rating components let users view or provide a score. These examples cover five-star ratings, half-star precision, custom icons (hearts, thumbs, flames), read-only display, interactive hover states, multiple sizes, review breakdowns with bar charts, and the CSS gradient technique that powers proportional fill without JavaScript.
Basic Star Rating
Standard five-star rating display using a CSS custom property--rating with a linear gradient. Filled stars indicate the score, empty stars show the remaining range. Pure CSS with no JavaScript required for read-only display.
basic-star-rating
Live
untitled.html
HTML
1
<div class="rating-demo">
2
<div class="rating-group">
3
<span class="stars" style="--rating:5" aria-label="5 out of 5 stars">
4
★★★★★
5
</span>
6
<span class="rating-value">
7
5.0
8
</span>
9
<span class="rating-text">
10
Excellent
11
</span>
12
</div>
13
<div class="rating-group">
14
<span class="stars" style="--rating:4" aria-label="4 out of 5 stars">
15
★★★★★
16
</span>
17
<span class="rating-value">
18
4.0
19
</span>
20
<span class="rating-text">
21
Very Good
22
</span>
23
</div>
24
<div class="rating-group">
25
<span class="stars" style="--rating:3" aria-label="3 out of 5 stars">
26
★★★★★
27
</span>
28
<span class="rating-value">
29
3.0
30
</span>
31
<span class="rating-text">
32
Good
33
</span>
34
</div>
35
<div class="rating-group">
36
<span class="stars" style="--rating:2.5" aria-label="2.5 out of 5 stars">
37
★★★★★
38
</span>
39
<span class="rating-value">
40
2.5
41
</span>
42
<span class="rating-text">
43
Fair
44
</span>
45
</div>
46
<div class="rating-group">
47
<span class="stars" style="--rating:1" aria-label="1 out of 5 stars">
48
★★★★★
49
</span>
50
<span class="rating-value">
51
1.0
52
</span>
53
<span class="rating-text">
54
Poor
55
</span>
56
</div>
57
</div>
untitled.css
CSS
1
.rating-demo {
2
display:flex;
3
flex-direction:column;
4
gap:8px;
5
padding:20px 24px;
6
font-family:system-ui,
7
sans-serif
8
}
9
.rating-group {
10
display:flex;
11
align-items:center;
12
gap:10px
13
}
14
.stars {
15
--rating:0;
16
--star-size:18px;
17
--star-color:#333;
18
--star-fill:#EAB308;
19
font-size:var(--star-size);
20
letter-spacing:2px;
21
line-height:1;
22
color:var(--star-color);
23
background:linear-gradient(90deg,
24
var(--star-fill) calc(var(--rating)/5*100%),
25
var(--star-color) calc(var(--rating)/5*100%));
26
-webkit-background-clip:text;
27
-webkit-text-fill-color:transparent;
28
background-clip:text;
29
display:inline-block;
30
font-style:normal
31
}
32
.rating-value {
33
font-size:13px;
34
color:#E0E0E0;
35
font-weight:600;
36
min-width:24px
37
}
38
.rating-text {
39
font-size:12px;
40
color:#808080;
41
min-width:80px
42
}
preview
Interactive Rating
Clickable star rating with hover preview. Hovering over a star highlights all stars up to that position. Clicking sets the value and displays a text label. Uses ARIA radio group pattern for accessibility.
Half-star ratings for more precise scoring. Each star splits into two clickable halves using CSS clip-path. The left half sets a .5 value, the right half sets the full integer. This gives 10 discrete rating levels.
half-star-rating
Live
untitled.html
HTML
1
<div class="half-demo">
2
<div class="half-stars" id="half-rating" aria-label="Rate 3.5 out of 5">
Replace stars with any icon — hearts for favorites, thumbs for likes, or custom emoji for brand-specific scoring. The gradient clip technique works with any repeated character, making it trivially customizable.
custom-icon-rating
Live
untitled.html
HTML
1
<div class="custom-rating-demo">
2
<div class="custom-group">
3
<span class="heart-stars" style="--rating:4" aria-label="4 out of 5">
4
♥♥♥♥♥
5
</span>
6
<span class="custom-label">
7
Favorite
8
</span>
9
</div>
10
<div class="custom-group">
11
<span class="thumb-stars" style="--rating:3" aria-label="3 out of 5">
12
👍👍👍👍👍
13
</span>
14
<span class="custom-label">
15
Like
16
</span>
17
</div>
18
<div class="custom-group">
19
<span class="flame-stars" style="--rating:5" aria-label="5 out of 5">
20
🔥🔥🔥🔥🔥
21
</span>
22
<span class="custom-label">
23
Hot
24
</span>
25
</div>
26
</div>
untitled.css
CSS
1
.custom-rating-demo {
2
display:flex;
3
flex-direction:column;
4
gap:12px;
5
padding:24px 24px;
6
font-family:system-ui,
7
sans-serif
8
}
9
.custom-group {
10
display:flex;
11
align-items:center;
12
gap:12px
13
}
14
.heart-stars {
15
--rating:0;
16
--fill:#EF4444;
17
--empty:#333;
18
font-size:20px;
19
letter-spacing:2px;
20
line-height:1;
21
background:linear-gradient(90deg,
22
var(--fill) calc(var(--rating)/5*100%),
23
var(--empty) calc(var(--rating)/5*100%));
24
-webkit-background-clip:text;
25
-webkit-text-fill-color:transparent;
26
background-clip:text;
27
display:inline-block
28
}
29
.thumb-stars {
30
--rating:0;
31
--fill:#3B82F6;
32
--empty:#333;
33
font-size:20px;
34
letter-spacing:2px;
35
line-height:1;
36
background:linear-gradient(90deg,
37
var(--fill) calc(var(--rating)/5*100%),
38
var(--empty) calc(var(--rating)/5*100%));
39
-webkit-background-clip:text;
40
-webkit-text-fill-color:transparent;
41
background-clip:text;
42
display:inline-block
43
}
44
.flame-stars {
45
--rating:0;
46
--fill:#F97316;
47
--empty:#333;
48
font-size:20px;
49
letter-spacing:2px;
50
line-height:1;
51
background:linear-gradient(90deg,
52
var(--fill) calc(var(--rating)/5*100%),
53
var(--empty) calc(var(--rating)/5*100%));
54
-webkit-background-clip:text;
55
-webkit-text-fill-color:transparent;
56
background-clip:text;
57
display:inline-block
58
}
59
.custom-label {
60
font-size:11px;
61
color:#808080;
62
text-transform:uppercase;
63
letter-spacing:.5px;
64
font-weight:500
65
}
preview
Sizes
Compact, default, large, and hero rating displays. Small ratings fit inline with product names in tables; large and hero ratings work as display elements on product detail pages and landing pages.
Pairing the star rating with a review count, average score, and rating distribution bar chart gives users full context. Common in product detail pages, app store listings, and marketplace reviews.
Side-by-side comparison of read-only (display only, no hover effects) and interactive (clickable, hover preview) ratings. Usepointer-events: none on read-only variants to prevent hover and click interactions.
<span class="stars interactive-stars" aria-label="Click to rate">
20
<span class="i-star on">
21
★
22
</span>
23
<span class="i-star on">
24
★
25
</span>
26
<span class="i-star on">
27
★
28
</span>
29
<span class="i-star hoverable">
30
★
31
</span>
32
<span class="i-star hoverable">
33
★
34
</span>
35
</span>
36
<span class="compare-value">
37
Click to rate
38
</span>
39
</div>
40
</div>
untitled.css
CSS
1
.compare-demo {
2
display:flex;
3
align-items:center;
4
gap:0;
5
padding:24px;
6
font-family:system-ui,
7
sans-serif;
8
justify-content:center
9
}
10
.compare-col {
11
display:flex;
12
flex-direction:column;
13
align-items:center;
14
gap:8px;
15
padding:0 32px
16
}
17
.compare-label {
18
font-size:10px;
19
color:#555;
20
text-transform:uppercase;
21
letter-spacing:.5px;
22
font-weight:600
23
}
24
.compare-value {
25
font-size:11px;
26
color:#808080
27
}
28
.compare-divider {
29
width:1px;
30
height:60px;
31
background:#222;
32
flex-shrink:0
33
}
34
.stars.readonly {
35
--rating:3.5;
36
--star-size:20px;
37
--star-color:#333;
38
--star-fill:#EAB308;
39
font-size:var(--star-size);
40
letter-spacing:2px;
41
line-height:1;
42
background:linear-gradient(90deg,
43
var(--star-fill) calc(var(--rating)/5*100%),
44
var(--star-color) calc(var(--rating)/5*100%));
45
-webkit-background-clip:text;
46
-webkit-text-fill-color:transparent;
47
background-clip:text;
48
display:inline-block;
49
pointer-events:none
50
}
51
.interactive-stars {
52
display:flex;
53
gap:2px
54
}
55
.i-star {
56
font-size:20px;
57
color:#333;
58
cursor:pointer;
59
transition:color .15s,
60
transform .15s
61
}
62
.i-star.on {
63
color:#EAB308
64
}
65
.i-star.hoverable:hover {
66
color:#EAB308;
67
transform:scale(1.15)
68
}
preview
CSS Gradient Technique
The star rating uses a CSS custom property--rating with a linear gradient andbackground-clip: text. The gradient fills stars proportionally based on the rating value — no JavaScript needed for read-only display.
star-rating.css
CSS
1
.stars {
2
--rating: 0;
3
--star-size: 18px;
4
--star-color: #333;
5
--star-fill: #EAB308;
6
7
font-size: var(--star-size);
8
letter-spacing: 2px;
9
line-height: 1;
10
color: var(--star-color);
11
background: linear-gradient(
12
90deg,
13
var(--star-fill) calc(var(--rating) / 5 * 100%),
14
var(--star-color) calc(var(--rating) / 5 * 100%)
15
);
16
-webkit-background-clip: text;
17
-webkit-text-fill-color: transparent;
18
background-clip: text;
19
display: inline-block;
20
}
ℹ
info
The CSS gradient technique is ideal for read-only ratings. For interactive ratings, use JavaScript to toggle classes and setaria-checkedon each star. Always provide a text fallback (e.g., "4.5 out of 5 stars") for screen readers.
✓
best practice
When using custom icons (hearts, thumbs), ensure the empty state is visible against the background. Use #333 on dark themes and #DDD on light backgrounds. The icon character must have a consistent width for the gradient clip to align correctly across all ratings.
Best Practices
Always provide aria-label or visible text with the rating for accessibility.
Use role="radiogroup" and role="radio" with aria-checked for interactive ratings.
Display the numeric score alongside stars — color-blind users may not distinguish filled from empty.
For half-star ratings, ensure each half has a distinct click target and hover state.
Use pointer-events: none on read-only ratings to prevent hover effects.
On mobile, increase touch targets to at least 44×44px per star.
Consider showing a review breakdown (bar chart) alongside the average for transparency.