Tooltip

Ajutor scurt la hover sau focus, pe fundal de brand. Bula e ascunsă până atunci, iar latura e o clasă — .top implicit, .bottom, .left, .right, cu .start / .end pe sus și jos — nu left / top scrise de mână. Momentul în care explici ceva e un moment bun de brand, și tooltipul îl poartă, cu contrastul declarat mai jos.

Markup canonic · components/tooltip.json

sursa = JSON · generat de scripts/build-catalog.py · treci cu mouse-ul sau apasă Tab
Codul Unic de Înregistrare — identificatorul fiscal al firmei, tipărit pe orice factură.

Interactiv · hover și focus

Ca în preview-ul shadcn: nimic la repaus, bula apare după 120ms de hover și imediat la focus (Tab). Cele patru laturi, pe declanșatoare reale — un buton cu text și trei iconuri.

.tooltip-wrap:hover · :focus-within — 120ms la hover, 0 la focus
Salvează documentul în biblioteca firmei Descarcă PDF Trimite pe email Șterge — cere confirmare
Pe iconuri, tooltipul nu înlocuiește aria-label-ul butonului — îl completează. Declanșatorul poartă aria-describedby spre bulă; bula are role="tooltip" și rămâne în DOM (doar opacity: 0), deci cititorul de ecran o citește și fără hover. Fără title — ar dubla bula cu tooltipul nativ.

Toate pozițiile · patru laturi, trei alinieri

Aceeași geometrie ca side / align din shadcn (Radix): .top · .bottom · .left · .right, iar pe sus și jos .start / .end lipesc bula de marginea declanșatorului — pentru butoane la marginea viewportului, unde bula centrată ar ieși din ecran. Mai jos bulele sunt ținute deschise cu .tooltip-wrap.is-open.

Lipită de marginea stângă
.top.start
Centrată pe declanșator
.top (implicit)
Lipită de marginea dreaptă
.top.end
Ascunde coloana
.left
8px aer între declanșator și bulă pe toate laturile. Săgeata la mijlocul muchiei, sau la 16px pe .start / .end.
Numele itemului
.right
Lipită de marginea stângă
.bottom.start
Când sus nu e loc
.bottom
Lipită de marginea dreaptă
.bottom.end
ClasăUnde stă bulaSăgeataCând
.topdeasupra, centrată, 8px aermijlocul muchiei de josimplicit — de regulă e loc sus
.bottomsub declanșator, centratămijlocul muchiei de sussus nu e loc: primul rând al unei liste, un buton din header
.leftla stânga, centrată verticalmijlocul muchiei din dreaptaiconuri lipite de marginea dreaptă a ecranului
.rightla dreapta, centrată verticalmijlocul muchiei din stângaiconuri într-o coloană din stânga — perechea scrisă de mână a etichetei din rail
.top.start · .bottom.startlipită de marginea stângă a declanșatoruluila 16px de stângadeclanșatorul e lângă marginea stângă a viewportului
.top.end · .bottom.endlipită de marginea dreaptăla 16px de dreaptadeclanșatorul e lângă marginea dreaptă

Fără detecție de coliziune în CSS — alegi latura care are loc pe ecranul tău. Un consumator cu JS poate schimba clasa la deschidere, dacă măsoară că bula ar ieși din viewport.

Stări

StareCe se vedeCum
repausnimic — opacity: 0, bula rămâne în DOMimplicit
hoverbula, după 120ms — ca eticheta din rail.tooltip-wrap:hover
focusbula, imediat.tooltip-wrap:focus-within
deschisăbula, permanent.tooltip-wrap.is-open — documentație, teste, JS (Escape o închide scoțând clasa)

Contrastul, declarat

Fundalul e --c-accent. Alb pe el dă 3.67:1 — sub AA la 13px (textul mare începe la 18.66px bold, deci excepția nu se aplică). Decizie luată în cunoștință de cauză la 2026-08-27: momentul în care explici ceva e un moment de brand, și tooltipul poartă pinkul. Nu e o scăpare — dacă apare într-un audit, ăsta e răspunsul. Alternativa măsurată, dacă se răzgândește cineva: --c-accent-deep, 5.39:1.
FundalTextContrastAA la 13px
--c-accent#fff3.67:1pică
--c-accent-deep#fff5.39:1trece

Metrici

fundal      --c-accent
text        #fff · 13px / 18px
padding     7px 11px
radius      --r-sm (10px)
lățime      max-content, cel mult 260px
aer         8px între declanșator și bulă
umbră       --sh-md
săgeată     8px, rotită 45°, aceeași culoare; la mijlocul muchiei, sau la 16px pe .start / .end
apariție    opacity 100ms · 120ms întârziere la hover · 0 la focus

Tooltipul e pointer-events: none — nu poate fi ținta unui click, deci nu poate conține acțiuni. Ceva pe care utilizatorul trebuie să-l apese e un .popover.

Reguli

  • Hover ȘI focus. Un tooltip care apare doar la hover nu există pentru tastatură. aria-describedby pe declanșator, role="tooltip" pe el.
  • Latura e o clasă. Nu left / top inline — offsetul, centrarea și săgeata vin din clasă, ca toate tooltipurile din produs să cadă la fel.
  • Ascunsă în repaus. .is-open e pentru documentație și JS, nu pentru o bulă mereu aprinsă.
  • Nu pune informație necesară în el. Ce e obligatoriu ca să completezi un câmp e .field-help, vizibil permanent.
  • O propoziție. Peste ~140 de caractere, e conținut de pagină sau un .popover.
  • Fără acțiuni. Vezi mai sus — dispare la mișcarea mouse-ului.
  • A doua plasare: eticheta din rail-ul icon-only. .sidebar.icon-only .sidebar-label e aceeași bulă (selector grupat cu .tooltip în bono-ds.css), așezată de sidebar la dreapta railului, la hover și focus. Acolo e numele itemului, nu o descriere — fără aria-describedby, fără title. Vezi App navigation.