Компонент · рівень 1

Рейтинг

Зірка, цифра і кількість відгуків. Цифру несе моношрифт, бо саме її порівнюють між картками, а зірку малює набір - вона на пів пікселя більша за цифру, бо інакше читається меншою.

рівень 1design/system/components/rating.css164 рядки8 імен17 з 40 екранів
Анатомія

Розмітка тут та сама, що в продукті, знак у знак. До кроку 7.27 на цій сторінці стояла інша: <span class="uiv-star">★</span> поруч з .st, з зірочкою, намальованою шрифтом. Такої розмітки в продукті немає жодної.

4.8 · 126 відгуків
1Знак .uiv-star - той самий гліф, що й у наборі, тільки залитий. Декоративний, aria-hidden, 2.00:1 - він не несе значення
2Цифра .st > b - моношрифт, і саме вона несе факт. Обгортка .st це рядок «знак + цифра», а не сама цифра
3Кількість - текстовий вузол після .st. Без нього оцінка нічого не варта

Чому демо стоїть у картці. Три з чотирьох правил цифри прив'язані до контейнера - .pcard .rate .st, .bb .bbrate .st, .rvmeta .rstars - тому поза карткою, блоком покупки чи рядком відгуку рейтинг втрачає моношрифт і осідає на Inter. Перевірено тут: перша редакція цього демо стояла голим <div class="rate"> і цифра вийшла Inter 700 замість IBM Plex Mono. Це рівень 1, який поки не вміє стояти сам; розчепити селектори - пункт Кроку 6, разом з перейменуванням .rstars.

Розмір зірки - одне правило замість чотирьох

До 7.27 зірку розмічали чотири файли, і виходило чотири числа: 13, 14, 15 і 18. Три з них виявились одним правилом, якого ніхто не записав - розмір рядка плюс один піксель. Два незалежні автори дійшли до нього окремо: product-card.css написав 13 у рядку 12px, а rating.css - 15 у рядку 14px.

ДеРядокЗіркаЗвідки число
.pcard .rate · .pcard-l .lmeta12px13calc(1em + 1px)
.bb .bbrate · .rvmeta .rstars14px15calc(1em + 1px)
.tbanners, банер відгуків14px14 → 15було власне число, стало правило
.rvbig .starrow, п'ять зірок14px18окреме рішення, не промах
.pm-stars .pmst, вибір оцінки30px31.51.05em з icon.css
4.8 · 126 відгуків
5.0
4.8

126 відгуків

Чому «плюс один»: чорнило зірки не заповнює свій квадрат так, як цифра заповнює свій, тому зірка рівно в розмір цифри читається дрібнішою за неї. 18 у рядку 14px - це не промах на чотири пікселі, це дисплейний рядок з п'яти зірок поруч з цифрою в 50px, і його розмір лишається окремим рішенням. Зірка у виборі оцінки не супроводжує цифру - вона і є контрол, тому бере правило знака (1.05em), а не правило рядка.

Стани

Попередня редакція цієї сторінки казала «у коді немає жодного стану, крім базового». У коді їх три, і всі три знайшлися в браузері.

4.8 · 126 відгуків
- · новинка
1Оцінка є - зірка, цифра, кількість. 132 входження
2Оцінки ще немає - ★ - · новинка. 6 входжень на 6 екранах: товар щойно в каталозі, відгуків нема, і рядок каже це словом, а не порожнечею
3Рядок ще не приїхав - .rate порожній, і його тримає min-height: 15px, щоб картка під ним не стрибала, коли цифра з'явиться

Четвертий стан заведено на 8.16, і він єдиний, під який у файлі немає жодного оголошення. Це нуль відгуків у зведенні на product-reviews.html - те саме, що рядок каже словом «новинка», але на два поверхи вище. Зліва зведення, яке має що показати; праворуч те, що стоїть на його місці, коли не має.

4.8

126 відгуків
Відгуків ще немає
Цей товар щойно в каталозі. Якщо ви його купували - ваш відгук допоможе обрати іншим.
жодного числа праворуч немає навмисно. 0.0 - це твердження про товар, і воно неправдиве; риска в 50px - не пропущене значення, а заголовок, який нічого не каже; п'ять погашених зірок - це малюнок «0 з 5», тобто найгірша можлива оцінка формою знака. Цифру тут ставлять у моношрифт саме тому, що її порівнюють - а коли порівнювати нема з чим, немає й роботи. Коробка - .emptybox.mini зі empty-state.css, кнопка в ній та сама, що була в шапці

Рядок і зведення відповідають по-різному, і це не суперечність. У картці рейтинг - один факт серед п'яти, тож ★ - · новинка тримає місце й не бреше. У зведенні рейтинг - увесь блок, і тримати місце нічим: 50px, віддані риске, кажуть неправду голосніше, ніж 12px. Один принцип - не вигадувати значення - дає дві різні відповіді на двох масштабах.

Вибір оцінки

Єдиний рейтинг, який натискають. До 7.27 він цілком жив у review-modal.css - модалка вирішувала не лише де він стоїть, а й який він. Модалка вирішує місце; який вигляд має зірка, коли її натиснули, вирішує рейтинг. З усієї родини тільки в нього є кільце фокуса.

Три стани, і всі три можна дістати просто тут. Натисніть - обрана зірка й усі до неї беруть .on і золото --mark-rating, решта лишається на --mark-inactive. Наведення :hover піднімає зірку на піксель. Клавіша Tab дає :focus-visible - кільце, якого більше ні в кого в цій родині немає, бо решта рейтингів нічого не робить у відповідь.

І тут була друга зірка. icons.js каже про це зверху свого uivStarSvg: «той самий гліф, дві обробки - контур для навігаційного чипа, заливка для рейтингу». Але marks.js малює будь-який знак-контрол через uivIconSvg, тобто контуром, тому єдине місце, де зірка є цілим контролом, показувало п'ять контурів поруч зі 140 залитими - і натиснута ставала золотим контуром.

Перша спроба виправити це в marks.js («будь-яка ★ - залита») залила на одну зірку більше: «Знижки та бонуси» в навігації кабінету - теж ★, і вона за тим самим правилом має лишатись контуром. Гліф не знає, що він означає; це знає контекст. Тому marks.js лишився з контуром за замовчуванням, а вибір оцінки прописаний у design/_nav.js поруч із трьома іншими підмінами рейтингу. Знайдено звіркою до/після на 2148 вимірах, не оком.

Перепис

Браузер обійшов 40 кольорових екранів на 1280 і 390. Рейтинг є на 17 з них, і в них 142 зірки. Дві з них до цього кроку малював шрифт.

РодинаФайл до 7.27ВходженьЕкранів
.pcard .rate .strating.css + product-card.css9016
.rvbig .starrowreview-item.css153
.pm-stars .pmstreview-modal.css153
.rvmeta .rstarsreview-item.css73
.pcard-l .lmeta .strating.css + product-card.css61
.tbanners банер 5banner.css44
.bb .bbrate .strating.css33
.co-accrual .star - не рейтингcheckout-form.css22

Остання зірка, яку малював шрифт. Дві на чекауті - знак бонуса, не оцінка. Її пропустили всі попередні проходи, і кожен з них пояснює чому: marks.js ходить по контролах, а це span у div; три виклики uivStarify у _nav.js названі по рейтингах, а бонус не рейтинг. Гліф той самий, отже й малюнок той самий - виправлено правилом у design/_nav.js, не руками в двох файлах.

Коли вживати

Скрізь, де є оцінка. Job 4 - робота довіри: оцінка без кількості відгуків це число зі стелі, тому кількість не прибираємо «для краси». Кількість зникає лише в списковому рядку, де її місце займає ціна за порцію.

Правило і антиправило

Правило

Оцінка завжди з кількістю. 4.8 з двох відгуків і 4.8 зі ста двадцяти шести - різні факти. Якщо відгуків ще нема, рядок каже ★ - · новинка, а не зникає.

Антиправило

Не малюй п'ять зірок замість цифри. П'ять гліфів займають місце ціни й читаються повільніше за одне число. П'ять зірок є рівно в одному місці - у зведенні відгуків, де вони і є заголовком блоку. Якщо потрібен розподіл оцінок - це Відгук зі своїми смугами.
Контраст
ПараКонтрастВирок
зірка --mark-rating на --bg-page2.00:1декоративна, aria-hidden - контраст її не стосується
цифра --text-body на --bg-page15.9:1саме вона несе факт, і вона проходить
кількість --text-muted на --bg-page4.62:1проходить AA на 12px
погашена зірка --mark-inactive1.51:1вибір оцінки: стан «не обрано» у контролі 30px, поруч із залитими сусідками

Зірка ніколи не лишається сама: факт несе цифра поруч, і саме тому знак має право бути тихим. Прибрати цифру і лишити зірки означало б повісити сенс на 2.00:1.

Холостий контроль

Сторінка звіряє себе з файлом: 8 власних класів і 4 стани. Три перші оголошені в rating.css; четвертий - нуль відгуків - навпаки, той, під який файл навмисно не має жодного оголошення, і він у списку саме тому: у коді його не видно, тож холостий контроль стежить, щоб його було видно тут. Нижче - те, чого на цій сторінці немає ні в демо, ні в розмітці. Чужий контекст (.pcard .pcard-l .lmeta .bb .bbrate .rvbig .rvmeta) не рахується: у цих селекторах компонент не є підметом, він лише стоїть усередині когось.

Рух

Робота: ВІДПОВІДЬ. Рухається: color, transform зірки. Тривалість --dur-fast (150ms), крива --ease-standard. Значення читаються через var() з tokens.css: підміна токена в браузері веде за собою кожне з них, тобто числа у файлі немає. При prefers-reduced-motion рух зникає, а стан лишається.

Токени

Прочитані з rating.css, не переписані руками. Колір іде лише через роль, геометрія - напряму з примітива. Єдине число без токена - 18px п'ятизіркового рядка, і воно назване рішенням у самому файлі.

Семантичні ролі (5)Примітиви (10)
--line-action --mark-inactive --mark-rating --text-body --text-muted--font-mono --fs-12 --fs-14 --fs-30 --fw-bold --lh-flat --radius-4 --space-2 --space-4 --space-8
–--dur-fast --ease-standard
Розмітка
<div class="rate"><span class="st"><span class="uiv-ic uiv-star"><svg…></span><b>4.8</b></span> · 126 відгуків</div>

Зірку в .st ставить uivStarify() у design/_nav.js: у вихідній розмітці стоїть <span class="st">★ 4.8</span>, і одна функція міняє гліф на малюнок та загортає цифру в <b>. Тому в html лежить ★, а на екрані - набір.

Де вживається

Якорі: .rate .st .rstars .starrow .pmst

17 з 40 екранів у design/: account.html, account-wishlist.html, checkout.html, checkout-loggedin.html, checkout-noaddr.html, home-buyer.html, home-cart.html, home-coach.html, index.html, listing.html, listing-filtered.html, listing-list.html, listing-sheet.html, product.html, product-coach.html, product-oos.html, product-reviews.html