Poziționarea ancorelor CSS: balon explicativ și meniu derulant fără JavaScript
Crearea unui tooltip în JavaScript înseamnă a scrie cod pentru a calcula poziția a elementului în raport cu declanșatorul său, actualizați acea poziție la redimensionare și derulați, gestionați cazurile marginale când sfatul cu instrumente ajunge în afara ferestrei de vizualizare și faceți toate acestea fără a introduce thrashing layout. Nu este complex, dar este un cod repetitiv pe care fiecare reinventează aplicația de la zero.
La CSS Anchor Positioning API rezolvă această problemă cu CSS pur și declarativ. Cu suport pentru browser86% la nivel global până la începutul anului 2026 (Chrome 125+, Edge 125+, Chrome pentru Android, Previzualizarea tehnologiei Safari), tehnica este matură pentru producție pe site-uri care acceptă browsere moderne. Permite pentru a „ancora” un element la altul ca punct de referință pentru poziționare, cu alternative automate dacă nu există suficient spațiu.
Ce vei învăța
- Conceptele fundamentale ale CSS Anchor Positioning: ancora, element pozitionat
- Proprietățile
anchor-nameeposition-anchor - Funcția
anchor()pentru poziţionare relativă - Cum să implementați sfaturi cu instrumente, meniuri derulante și meniuri contextuale în CSS pur
- Fallback-uri automate cu
position-try-fallbacks - Cum se integrează cu Popover API pentru accesibilitate deplină
- Îmbunătățirea progresivă pentru browsere fără suport
Conceptele fundamentale
CSS Anchor Positioning introduce două roluri:
-
L'element de ancorare (element de ancorare): elementul la care ancorăm.
El primește proprietatea
anchor-namecu o valoare de identificare personalizată (prefix--). -
Il element pozitionat (element pozitionat): elementul pe care il dorim
poziție față de ancoră. Trebuie să aibă
position: absoluteoposition: fixed, și primeșteposition-anchorpentru a se conecta la ancora.
/* 1. Definisci l'ancora */
.button-trigger {
anchor-name: --tooltip-anchor;
}
/* 2. Posiziona l'elemento relativamente all'ancora */
.tooltip {
position: absolute;
/* Collega questo elemento all'ancora */
position-anchor: --tooltip-anchor;
/* Posizionamento usando la funzione anchor() */
/* anchor(bottom) = il bordo bottom dell'ancora */
top: calc(anchor(bottom) + 8px);
/* Centra orizzontalmente rispetto all'ancora */
left: anchor(center);
transform: translateX(-50%);
}
Funcția anchor().
Funcția anchor() se rezolvă la o coordonată relativă la margine
elementul de ancorare specificat. Valorile disponibile sunt:
anchor(top): marginea superioară a ancoreianchor(bottom): marginea de jos a ancoreianchor(left): marginea stângă a ancoreianchor(right): marginea dreaptă a ancoreianchor(center): centrul orizontal al ancoreianchor(middle): centrul vertical al ancoreianchor(self-start),anchor(self-end): legat de direcția textului
/* Tooltip sopra il trigger */
.tooltip-top {
position: absolute;
position-anchor: --my-anchor;
bottom: calc(anchor(top) - 8px);
left: anchor(center);
transform: translateX(-50%);
}
/* Tooltip a destra del trigger */
.tooltip-right {
position: absolute;
position-anchor: --my-anchor;
top: anchor(center);
left: calc(anchor(right) + 8px);
transform: translateY(-50%);
}
/* Dropdown sotto il trigger - allineato a sinistra */
.dropdown {
position: absolute;
position-anchor: --dropdown-anchor;
top: calc(anchor(bottom) + 4px);
left: anchor(left);
min-width: anchor-size(width); /* larghezza minima = larghezza dell'ancora */
}
anchor-size(): Dimensiuni relativ la ancora
Pe langa functie anchor() pentru coordonate, anchor-size()
vă permite să accesați din nou dimensiunile elementului:
/* Il dropdown ha la stessa larghezza del trigger */
.dropdown {
min-width: anchor-size(width);
/* Altezza massima pari al 50% dell'altezza dell'ancora */
max-height: calc(anchor-size(height) * 0.5);
}
Balon explicativ accesibil: CSS Anchor + Popover API
Combinația optimă pentru sfaturi cu instrumente accesibile în 2026 și poziționarea ancorelor CSS cu API-ul Popover. API-ul Popover se ocupă automat de gestionarea focalizării, clicul din exterior pentru a închide și accesibilitatea ARIA. Poziționarea ancorelor CSS gestionează poziționarea vizuală.
<!-- HTML: Popover API + Anchor Positioning -->
<button
popovertarget="tooltip-content"
class="btn-with-tooltip"
>
Hover per info
</button>
<div
id="tooltip-content"
popover="hint"
class="tooltip"
role="tooltip"
>
Informazione contestuale utile all'utente
</div>
/* CSS: Anchor + Popover */
.btn-with-tooltip {
anchor-name: --btn-anchor;
}
.tooltip {
/* Stili base del tooltip */
position: absolute;
position-anchor: --btn-anchor;
/* Posiziona sotto il pulsante */
top: calc(anchor(bottom) + 8px);
left: anchor(center);
transform: translateX(-50%);
/* Reset stili popover */
margin: 0;
border: 1px solid #e2e8f0;
border-radius: 6px;
padding: 8px 12px;
background: white;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-size: 0.875rem;
max-width: 280px;
width: max-content;
/* Animazione di entrata */
opacity: 0;
transition: opacity 0.15s ease;
/* Stato visibile (Popover API) */
&:popover-open {
opacity: 1;
}
}
/* Freccia del tooltip */
.tooltip::before {
content: '';
position: absolute;
top: -8px;
left: 50%;
transform: translateX(-50%);
border: 4px solid transparent;
border-bottom-color: #e2e8f0;
}
.tooltip::after {
content: '';
position: absolute;
top: -7px;
left: 50%;
transform: translateX(-50%);
border: 4px solid transparent;
border-bottom-color: white;
}
Meniu complet derulant
Un exemplu mai complet: un meniu drop-down dintr-un buton „Acțiuni” cu CSS Anchor API de poziționare și popover pentru un management accesibil al concentrării:
<!-- Bottone trigger -->
<button
class="actions-btn"
popovertarget="actions-menu"
aria-haspopup="true"
>
Azioni ▼
</button>
<!-- Menu dropdown -->
<menu
id="actions-menu"
popover="auto"
class="dropdown-menu"
>
<li><button>Modifica</button></li>
<li><button>Duplica</button></li>
<li class="separator"></li>
<li><button class="danger">Elimina</button></li>
</menu>
/* CSS del dropdown */
.actions-btn {
anchor-name: --actions-anchor;
}
.dropdown-menu {
position: absolute;
position-anchor: --actions-anchor;
/* Allinea il bordo sinistro del menu con il pulsante */
top: calc(anchor(bottom) + 4px);
left: anchor(left);
/* Larghezza minima pari al pulsante */
min-width: anchor-size(width);
/* Reset stili menu */
margin: 0;
padding: 4px 0;
list-style: none;
background: white;
border: 1px solid #e2e8f0;
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
/* Animazione */
opacity: 0;
scale: 0.95;
transform-origin: top left;
transition: opacity 0.15s, scale 0.15s;
&:popover-open {
opacity: 1;
scale: 1;
}
}
.dropdown-menu li button {
display: block;
width: 100%;
padding: 8px 16px;
text-align: left;
border: none;
background: none;
cursor: pointer;
font-size: 0.875rem;
&:hover {
background: #f8fafc;
}
&.danger {
color: #ef4444;
}
}
.dropdown-menu .separator {
height: 1px;
background: #e2e8f0;
margin: 4px 0;
}
Fallback-uri automate cu poziție-try-fallbacks
Una dintre cele mai plictisitoare probleme cu sfaturile instrumente și meniurile derulante este tratarea cazurilor în care nu există suficient spațiu: un sfat explicativ care ajunge în afara feței de vizualizare de sus sau din stânga trebuie repoziționat automat.
CSS Anchor Positioning rezolvă acest lucru cu position-try-fallbacks, că
specifică o listă de destinații de plasare alternative pe care browserul le testează secvenţial:
/* Definisci i posizionamenti alternativi */
@position-try --below {
top: calc(anchor(bottom) + 8px);
bottom: auto;
left: anchor(center);
right: auto;
}
@position-try --above {
top: auto;
bottom: calc(anchor(top) + 8px);
left: anchor(center);
right: auto;
}
@position-try --right {
top: anchor(center);
left: calc(anchor(right) + 8px);
right: auto;
bottom: auto;
}
@position-try --left {
top: anchor(center);
right: calc(anchor(left) + 8px);
left: auto;
bottom: auto;
}
.tooltip {
position: absolute;
position-anchor: --my-anchor;
/* Posizionamento default: sotto */
top: calc(anchor(bottom) + 8px);
left: anchor(center);
transform: translateX(-50%);
/* Fallback: prova prima sopra, poi destra, poi sinistra */
position-try-fallbacks: --above, --right, --left;
/* Fallback finale: usa la prima opzione disponibile nel viewport */
position-try-order: most-block-size;
}
Îmbunătățire progresivă pentru browsere fără suport
Pentru browserele care nu acceptă încă CSS Anchor Positioning (Firefox stabil
nu îl acceptă încă de la începutul anului 2026), folosește @supports pentru
oferă o rezervă:
/* Fallback: tooltip sempre visibile o con JS */
.tooltip {
/* Stili di default accessibili: mostro un title attribute */
display: none; /* nascosto, gestito da JS fallback */
}
/* Se il browser supporta anchor positioning: CSS puro */
@supports (anchor-name: --test) {
.trigger {
anchor-name: --my-anchor;
}
.tooltip {
display: block; /* visibile, gestito da CSS */
position: absolute;
position-anchor: --my-anchor;
top: calc(anchor(bottom) + 8px);
left: anchor(center);
transform: translateX(-50%);
/* Nascosto di default, mostrato su hover/focus */
opacity: 0;
pointer-events: none;
transition: opacity 0.15s;
}
.trigger:hover + .tooltip,
.trigger:focus + .tooltip {
opacity: 1;
pointer-events: auto;
}
}
/* JavaScript fallback per browser legacy */
if (!CSS.supports('anchor-name', '--test')) {
// Import libreria JS per tooltip
import('./tooltip-fallback.js').then(module => module.init());
}
Firefox: suport încă limitat
La începutul anului 2026, Firefox nu acceptă încă CSS Anchor Positioning în
versiune stabilă (și în dezvoltare activă). Aceasta înseamnă că 20-25% din
Utilizatorii de desktop de pe Firefox vor vedea alternativa. STATELE UNITE ALE AMERICII @supports pentru
asigurați-vă că experiența este întotdeauna funcțională, chiar și fără poziționarea ancorelor.
Următorii pași
Acum aveți sfaturi și meniuri derulante declarative în CSS pur. Următorul articol din seria explorează API-ul View Transitions: Cum să implementați animații fluide navigare nativă în browser, atât pentru Aplicații Single Page, cât și pentru Aplicații cu mai multe pagini, fără biblioteci terțe.
Concluzii
CSS Anchor Positioning este una dintre cele mai așteptate completări la limbajul CSS ultimii ani. Elimină o întreagă categorie de cod JavaScript - calcul manual a coordonatelor de poziționare — înlocuindu-l cu CSS declarativ care browser-ul se ocupă în mod nativ, inclusiv de rezervă și actualizare automată derulați și redimensionați.
Cu suport pentru 86% din browserele globale, îl puteți adopta deja ca îmbunătățire progresiv, asigurându-vă că browserele vechi au încă o experiență funcţional. Combinația cu API-ul Popover pentru gestionarea accesibilității reprezintă stiva modernă și completă pentru construirea de suprapuneri de UI în 2026.







