x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<div class="tw:p-6 tw:max-w-7xl tw:mx-auto tw:space-y-8"> <div class="callout"> <p class="tw:mb-1 tw:text-sm tw:font-mono"> <strong>COMPONENT:</strong> Stars<br> <strong>VARIANTS:</strong> sm | default | lg + optional count label </p> <p class="tw:mb-0 tw:text-sm"> Read-only 5-star rating display. Caller emits filled (<code>fa-solid fa-star</code>), half (<code>fa-solid fa-star-half-stroke</code>) and empty (<code>fa-light fa-star</code>) icons; the component styles the wrapper + icon color/opacity. <strong>The row you draw must match the value you announce</strong> — see Half-star ratings below. </p> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">Integer ratings (1–5)</h2> <div class="tw:flex tw:flex-col tw:gap-2"> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-16">Rating 1:</span> <div class="stars" role="img" aria-label="1 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-16">Rating 2:</span> <div class="stars" role="img" aria-label="2 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-16">Rating 3:</span> <div class="stars" role="img" aria-label="3 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-16">Rating 4:</span> <div class="stars" role="img" aria-label="4 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-16">Rating 5:</span> <div class="stars" role="img" aria-label="5 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> </div> </div> </div> <div class="tw:mt-4 tw:text-sm tw:text-gray-600"> <code><div class="stars"><i class="fa-solid fa-star"></i>...</div></code> </div> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">Half-star ratings</h2> <div class="callout tw:mb-4"> <p class="tw:mb-0 tw:text-sm"> <strong>Half stars:</strong> use <code>fa-solid fa-star-half-stroke</code> (Font Awesome Pro 6) — zero extra CSS, and it measures the same box as <code>fa-star</code> (11.81 × 10.5px at <code>.stars-sm</code>), so a half star never shifts the row. Always <code>fa-solid</code>, never <code>fa-light</code>. Until 2026-08-12 the docs told callers to render 4 filled stars for a 4.5 rating while the <code>aria-label</code> announced “4.5”, so sighted users saw one value and screen-reader users heard another. </p> </div> <div class="tw:flex tw:flex-col tw:gap-2"> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24 tw:shrink-0">Rating 0.5:</span> <div class="stars" role="img" aria-label="0.5 out of 5 stars"> <i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24 tw:shrink-0">Rating 1.5:</span> <div class="stars" role="img" aria-label="1.5 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24 tw:shrink-0">Rating 2.5:</span> <div class="stars" role="img" aria-label="2.5 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24 tw:shrink-0">Rating 3.5:</span> <div class="stars" role="img" aria-label="3.5 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24 tw:shrink-0">Rating 4.5:</span> <div class="stars" role="img" aria-label="4.5 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i> </div> </div> </div> <div class="tw:mt-4 tw:text-sm tw:text-gray-600"> <code><div class="stars" role="img" aria-label="4.5 out of 5 stars"></code><br> <code> <i class="fa-solid fa-star"></i> ×4</code><br> <code> <i class="fa-solid fa-star-half-stroke"></i></code><br> <code></div></code> </div> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">Size variants</h2> <div class="tw:flex tw:flex-col tw:gap-3"> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24">sm (12px):</span> <div class="stars stars-sm" role="img" aria-label="4 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24">default (14px):</span> <div class="stars" role="img" aria-label="4 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24">lg (17.5px):</span> <div class="stars stars-lg" role="img" aria-label="4 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> </div> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">With count label</h2> <p class="tw:text-sm tw:text-gray-600 tw:mb-3">Append a <code>.stars-count</code> span after the icons.</p> <div class="callout tw:mb-4"> <p class="tw:mb-0 tw:text-sm"> <strong>Precision:</strong> <code>.stars</code> renders to half-star granularity. An aggregate average finer than that (4.8) may keep its exact figure in the <code>aria-label</code> <em>only because the same figure is on screen</em> as <code>.stars-count</code> text — both audiences get the same number beside the same rounded row. With no visible number, round the value to the nearest half and label it as drawn; never let the label assert a precision no viewer can see. </p> </div> <div class="stars" role="img" aria-label="4.8 out of 5 stars from 124 reviews"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <span class="stars-count">4.8 · 124 reviews</span> </div> <div class="tw:mt-4 tw:text-sm tw:text-gray-600"> <code><span class="stars-count">4.8 · 124 reviews</span></code> </div> </div></div>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<div class="tw:p-6 tw:max-w-7xl tw:mx-auto tw:space-y-8"> <div class="callout"> <p class="tw:mb-1 tw:text-sm tw:font-mono"> <strong>COMPONENT:</strong> Stars<br> <strong>VARIANTS:</strong> sm | default | lg + optional count label </p> <p class="tw:mb-0 tw:text-sm"> Read-only 5-star rating display. Caller emits filled (<code>fa-solid fa-star</code>), half (<code>fa-solid fa-star-half-stroke</code>) and empty (<code>fa-light fa-star</code>) icons; the component styles the wrapper + icon color/opacity. <strong>The row you draw must match the value you announce</strong> — see Half-star ratings below. </p> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">Integer ratings (1–5)</h2> <div class="tw:flex tw:flex-col tw:gap-2"> <% (1..5).each do |rating| %> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-16">Rating <%= rating %>:</span> <div class="stars" role="img" aria-label="<%= rating %> out of 5 stars"> <% 5.times do |i| %> <i class="<%= i < rating ? 'fa-solid' : 'fa-light' %> fa-star" aria-hidden="true"></i> <% end %> </div> </div> <% end %> </div> <div class="tw:mt-4 tw:text-sm tw:text-gray-600"> <code><div class="stars"><i class="fa-solid fa-star"></i>...</div></code> </div> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">Half-star ratings</h2> <div class="callout tw:mb-4"> <p class="tw:mb-0 tw:text-sm"> <strong>Half stars:</strong> use <code>fa-solid fa-star-half-stroke</code> (Font Awesome Pro 6) — zero extra CSS, and it measures the same box as <code>fa-star</code> (11.81 × 10.5px at <code>.stars-sm</code>), so a half star never shifts the row. Always <code>fa-solid</code>, never <code>fa-light</code>. Until 2026-08-12 the docs told callers to render 4 filled stars for a 4.5 rating while the <code>aria-label</code> announced “4.5”, so sighted users saw one value and screen-reader users heard another. </p> </div> <div class="tw:flex tw:flex-col tw:gap-2"> <% [["0.5", 0, true], ["1.5", 1, true], ["2.5", 2, true], ["3.5", 3, true], ["4.5", 4, true]].each do |label, filled, half| %> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24 tw:shrink-0">Rating <%= label %>:</span> <div class="stars" role="img" aria-label="<%= label %> out of 5 stars"> <% filled.times do %> <i class="fa-solid fa-star" aria-hidden="true"></i> <% end %> <% if half %> <i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i> <% end %> <% (5 - filled - (half ? 1 : 0)).times do %> <i class="fa-light fa-star" aria-hidden="true"></i> <% end %> </div> </div> <% end %> </div> <div class="tw:mt-4 tw:text-sm tw:text-gray-600"> <code><div class="stars" role="img" aria-label="4.5 out of 5 stars"></code><br> <code> <i class="fa-solid fa-star"></i> ×4</code><br> <code> <i class="fa-solid fa-star-half-stroke"></i></code><br> <code></div></code> </div> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">Size variants</h2> <div class="tw:flex tw:flex-col tw:gap-3"> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24">sm (12px):</span> <div class="stars stars-sm" role="img" aria-label="4 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24">default (14px):</span> <div class="stars" role="img" aria-label="4 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> <div class="tw:flex tw:items-center tw:gap-3"> <span class="tw:text-sm tw:font-mono tw:text-gray-500 tw:w-24">lg (17.5px):</span> <div class="stars stars-lg" role="img" aria-label="4 out of 5 stars"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-light fa-star" aria-hidden="true"></i> </div> </div> </div> </div> <div class="tw:border-t tw:pt-6"> <h2 class="h4 tw:mb-4">With count label</h2> <p class="tw:text-sm tw:text-gray-600 tw:mb-3">Append a <code>.stars-count</code> span after the icons.</p> <div class="callout tw:mb-4"> <p class="tw:mb-0 tw:text-sm"> <strong>Precision:</strong> <code>.stars</code> renders to half-star granularity. An aggregate average finer than that (4.8) may keep its exact figure in the <code>aria-label</code> <em>only because the same figure is on screen</em> as <code>.stars-count</code> text — both audiences get the same number beside the same rounded row. With no visible number, round the value to the nearest half and label it as drawn; never let the label assert a precision no viewer can see. </p> </div> <div class="stars" role="img" aria-label="4.8 out of 5 stars from 124 reviews"> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <i class="fa-solid fa-star" aria-hidden="true"></i> <span class="stars-count">4.8 · 124 reviews</span> </div> <div class="tw:mt-4 tw:text-sm tw:text-gray-600"> <code><span class="stars-count">4.8 · 124 reviews</span></code> </div> </div></div>No notes provided.
No params configured.