Quando inserisci una descrizione comando o un menu a discesa, spesso vuoi posizionarlo rispetto a un altro elemento della pagina. Sebbene esistano modi per ottenere questo effetto utilizzando il posizionamento assoluto, i requisiti più complessi hanno storicamente fatto ricorso al posizionamento degli elementi tramite JavaScript.
Il posizionamento dell'ancora CSS consente di posizionare in modo dichiarativo un elemento rispetto a un altro.
Elementi di tethering
Per trasformare un elemento in un ancoraggio, devi assegnargli un valore anchor-name
di qualsiasi stringa che inizi con due trattini. Questo è l'identificatore che l'elemento posizionato utilizzerà per trovare il suo ancoraggio ed è utile assegnargli un nome descrittivo. Puoi anche assegnare a un elemento più nomi di ancoraggio, se verrà utilizzato come ancoraggio in modi diversi.
Devi impostare alcune proprietà sull'elemento posizionato in modo che possa essere agganciato. Innanzitutto, devi estrarre l'elemento dal flusso del documento, in modo che fluttui, impostando position: absolute
o position: fixed
.
Successivamente, devi impostare l'ancora a cui vuoi collegarti impostando position-anchor
sul nome dell'ancora che hai impostato.
Infine, dovrai impostare il posizionamento dell'ancora. Scoprirai di più su position-area
più avanti in questo modulo.
#anchor {
anchor-name: --my-anchor;
}
#positionedElement {
position: absolute;
position-anchor: --my-anchor;
position-area: end;
}
Tethering impliciti
I popup sono ancora più semplici da collegare. Quando apri un popover utilizzando un pulsante con popovertarget
o impostando un source
con showPopover({source})
, il popover ha già impostato un "ancoraggio implicito". Poiché per impostazione predefinita è già presente un popover mobile con position: fixed
, per posizionarlo è sufficiente impostare la posizione.
#anchor{}
#positionedElement {
position-area: end;
margin: unset;
}
Definizione dell'ambito dei potenziali ancoraggi
Puoi implementare il posizionamento dell'ancora come parte di un componente, in modo da poter utilizzare un pattern come un menu a discesa in più posizioni. Se utilizzi lo stesso anchor-name
più volte, come fai ad assicurarti che ogni elemento posizionato trovi l'ancora corretta?
Le soluzioni JavaScript prevedono l'aggiunta di ID univoci a ogni ancoraggio e il riferimento a questi dall'elemento posizionato. Questo diventa complicato e CSS offre una soluzione più semplice con anchor-scope
.
La proprietà anchor-scope
imposta i nomi degli ancoraggi che verranno abbinati solo tra un elemento e i relativi discendenti. Accetta un elenco di uno o più nomi di ancoraggio o la parola chiave all
per limitare l'ambito di tutti i nomi di ancoraggio definiti.
Un anchor-scope
viene aggiunto idealmente a un elemento principale sia dell'elemento posizionato sia dell'elemento di ancoraggio che non contiene altri elementi di ancoraggio con lo stesso nome. Spesso si trova nella radice del componente riutilizzabile.
L'esempio seguente mostra la differenza che anchor-scope
fa quando viene applicato a elementi ripetuti con lo stesso anchor-name
. Nell'esempio, tutti gli elementi <img>
e i banner delle immagini fanno riferimento al nome dell'ancora --image
. Quando anchor-scope
viene applicato agli elementi <li>
, position-anchor: --image
corrisponderà solo all'elemento <img>
all'interno dello stesso elemento <li>
del banner, altrimenti corrisponderà all'ultimo <img>
visualizzato.
Presentazione
Ora che hai collegato l'elemento all'ancora, è il momento di posizionarlo. Il posizionamento dell'ancora fornisce due metodi di posizionamento: position-area
e la funzione anchor()
.
position-area
La proprietà position-area
ti consente di posizionare un elemento intorno all'ancora specificando una o due parole chiave. Ciò copre molti casi d'uso comuni ed è spesso un buon punto di partenza.
Come funziona position-area
position-area
funziona creando un nuovo blocco contenitore per l'elemento posizionato in un'area generata dai bordi dell'ancora e dal blocco contenitore originale dell'elemento posizionato.
Sebbene siano disponibili molte parole chiave per position-area
, possono essere suddivise in alcune categorie per renderle più comprensibili. Anchor-tool.com è un ottimo strumento per esplorare la sintassi.
Parole chiave fisiche
Puoi utilizzare le scorciatoie fisiche top
, left
, bottom
, right
e center
. Ad esempio, position-area: top right
posizionerà l'elemento posizionato sopra e a destra dell'ancoraggio. Queste parole chiave hanno anche equivalenti per gli assi fisici: y-start
, x-start
, y-end
e x-end
.
Parole chiave logiche
Puoi anche utilizzare le parole chiave logiche block-start
, block-end
, inline-start
e inline-end
. Ad esempio, position-area: block-end inline-start
posizionerà l'elemento posizionato sotto e a sinistra dell'ancora in lingue come l'inglese oppure dopo l'ancora sull'asse del blocco e prima dell'ancora sull'asse in linea nella modalità di scrittura del documento. center
può essere utilizzato anche con una parola chiave logica.
Puoi anche omettere l'asse se specifichi parole chiave logiche, con l'asse del blocco per primo e l'asse in linea per secondo. position-area: start end
è uguale a position-area: block-start inline-end
o anche a position-area: inline-end block-start
.
Estensione su più aree della griglia
Finora, avrai notato che queste opzioni ti consentono di posizionare l'elemento posizionato in un singolo spazio della griglia. L'aggiunta del prefisso span
alle proprietà fisiche o logiche aggiunge lo spazio della griglia centrale adiacente. position-area: span-top right
verrà posizionato a destra dell'ancora, dal basso dell'ancora alla parte superiore del blocco contenitore originale dell'elemento posizionato.
Una posizione comune per un menu a discesa è position-area: block-end span-inline-end
.
La parola chiave span-all
si estende su tre righe o colonne.
Singola parola chiave
Se imposti una sola parola chiave, l'altro asse viene impostato automaticamente. Il funzionamento è in gran parte quello che ti aspetteresti, ma può essere utile capire come funziona.
Se la parola chiave fornita indica chiaramente l'asse, l'altro asse viene calcolato come span-all
. Ciò significa che position-area: bottom
è equivalente a position-area: bottom span-all
e che l'elemento posizionato si troverà sotto l'ancora e avrà a disposizione l'intera larghezza del blocco contenitore.
D'altra parte, se la parola chiave non indica chiaramente un asse, viene ripetuta. position-area: start
equivale a start start
e viene posizionato in alto a sinistra dell'ancora nelle lingue con direzione da sinistra a destra.
La funzione anchor()
Per casi d'uso più avanzati, position-area
potrebbe non soddisfare i tuoi requisiti. La funzione anchor()
ti consente di impostare singole proprietà di rientro in base alla posizione di un altro elemento. Questo valore viene risolto in una lunghezza CSS, il che significa che puoi utilizzarlo nei calcoli e con altre funzioni CSS. Inoltre, puoi anche collegare lati diversi ad ancore diverse.
La funzione anchor()
accetta un nome di ancoraggio e un lato di ancoraggio. Se l'elemento ha un ancoraggio predefinito, impostato con position-anchor
o implicitamente, ad esempio con un popover, puoi omettere il nome dell'ancoraggio.
.positionedElement {
block-start: anchor(--my-anchor start);
/* OR */
position-anchor: --my-anchor;
block-start: anchor(start);
}
Valori di riserva
Se non è possibile trovare un ancoraggio per una funzione anchor()
, l'intera dichiarazione non sarà valida. Ciò potrebbe accadere se l'ancora viene visualizzata dopo l'elemento posizionato o se non esiste un elemento con anchor-name
corrispondente. Per gestire questo problema, puoi impostare una durata o una percentuale di riserva.
.positionedElement {
block-start: anchor(--my-anchor, 100px)
}
Nell'esempio precedente, il valore left dell'elemento posizionato è ancorato a --focused-anchor
, ma anchor-name
esiste solo quando il cursore passa sopra o lo stato attivo è sul primo pulsante. Poiché una funzione anchor()
viene risolta in una lunghezza, puoi utilizzare un altro ancoraggio come fallback. Se non avessimo fornito un fallback, l'elemento posizionato non sarebbe stato posizionato.
Parole chiave lato ancoraggio
Il valore del lato di ancoraggio sceglie il bordo dell'ancoraggio da posizionare. Analogamente a position-area
, il valore del lato di ancoraggio supporta diversi tipi di sintassi.
Tipo | Valori | Descrizione |
---|---|---|
Fisico | top , left , bottom , right |
Le parole chiave fisiche corrispondono a un lato specifico dell'ancora, ma possono essere utilizzate solo sullo stesso asse dell'insetto dell'elemento posizionato che stai impostando. Ad esempio, |
Laterale | inside , outside |
La parola chiave Ad esempio, |
Logico | start , end , self-start , self-end |
Le parole chiave logiche si riferiscono ai lati dell'ancora in base alla modalità di scrittura dell'elemento posizionato con |
Percentuale | 0% - 100% |
Un valore percentuale posiziona l'elemento posizionato lungo l'asse dall'inizio alla fine dell'ancora sull'asse specificato. |
Questo esempio mostra come un valore percentuale va sempre dall'inizio alla fine dell'asse specificato:
In uso: anchor()
Poiché anchor()
è una lunghezza, è molto flessibile. Puoi manipolare il valore con funzioni CSS come max()
e calc()
.
Una limitazione è che puoi utilizzare solo le funzioni anchor()
sulle proprietà di inserimento.
L'esempio precedente aggiunge uno sfondo dietro il riquadro dei dettagli aperto che viene animato in modo uniforme quando viene aperto un altro riquadro e si estende per includere un riquadro dei dettagli su cui è stato passato il mouse. A questo scopo, utilizza min()
per scegliere la lunghezza più breve tra due punti di ancoraggio.
#indicator{
/* Use the smaller of the 2 values: */
inset-block-start: min(
/* 1. The start side of the default anchor, which is the open `<details>` element */
anchor(start),
/* 2. The start side of the hovered `<details>` element. */
anchor(--hovered start,
/* If no `<details>` element is hovered, this falls back to infinity px, so that the other value is smaller, and therefore used. */
var(calc(1px * infinity)))
);
}
L'esempio utilizza anche calc()
per aggiungere spazio in linea attorno al riquadro aperto.
Utilizzo delle dimensioni dell'ancora
Puoi anche utilizzare la funzione anchor-size()
per utilizzare le dimensioni dell'ancora per la dimensione, la posizione o il margine dell'elemento posizionato.
anchor-size()
accetta un nome di ancoraggio o utilizza l'ancoraggio predefinito. Per impostazione predefinita, utilizza le dimensioni dell'ancora sull'asse in cui viene utilizzata, quindi width: anchor-size()
restituirà la larghezza dell'ancora. Puoi anche utilizzare l'altro asse specificando la durata che preferisci, con le parole chiave fisiche width
e height
o le parole chiave logiche block
, inline
, self-block
e self-inline
.
Gestione dell'overflow
Hai creato un componente di menu a discesa e hai utilizzato il posizionamento dell'ancora per posizionare il menu a discesa dove vuoi. Ma poi sposti il menu sull'altro lato dello schermo o lo utilizzi per un menu utente e il nome dell'utente è molto lungo. All'improvviso, il menu a discesa non è più visibile sullo schermo. Ti chiedi cosa fare adesso?
Il posizionamento degli ancoraggi CSS ha un sistema integrato che ti consente di creare rapidamente un insieme robusto di fallback quando l'elemento posizionato finisce al di fuori del blocco contenitore.
Opzioni di riserva
La regola position-try-fallbacks
accetta un elenco di opzioni di riserva. Quando la posizione predefinita va in overflow, ogni opzione viene provata in ordine finché non viene trovata una posizione che non va in overflow.
Puoi utilizzare qualsiasi valore position-area
come opzione di riserva. In questo esempio, nelle modalità di scrittura da sinistra a destra come l'inglese, l'elemento posizionato tenterà di essere posizionato nella parte inferiore dell'ancora, estendendosi sulle colonne centrale e destra. Se non c'è spazio, verrà posizionato nella parte inferiore dell'ancora, a cavallo tra le colonne sinistra e centrale. Se anche questo valore supera il limite, la posizione tornerà a quella predefinita, anche se supera il limite.
.positioned-element {
position-area: block-end span-inline-end;
position-try-fallbacks: block-end span-inline-start;
}
Esistono anche diverse parole chiave flip-
che gestiscono i casi di fallback comuni. flip-block
e flip-inline
provano a capovolgere l'elemento sugli assi di blocco e in linea. Possono anche essere combinati con flip-block flip-inline
per invertire entrambi gli assi. Il valore flip-start
capovolge l'elemento posizionato su una linea diagonale dagli angoli iniziale e finale dell'ancora.
Puoi anche creare un'opzione di riserva personalizzata con @position-try
, che ti consente di impostare i margini, l'allineamento e persino modificare l'ancoraggio.
@position-try --menu-below {
position-area: bottom span-right;
margin-top: 1em;
}
#positioned-element {
position-try: --menu-below;
}
flip-block
e flip-inline
possono essere aggiunti alle opzioni di riserva @position-try
per creare una variante.
#positioned-element {
position-try: --menu-below, flip-inline --menu-below;
}
Nell'esempio precedente, il browser segue questi passaggi, arrestandosi non appena trova una soluzione che non causa overflow.
- L'elemento è posizionato con
position-area: end
, in basso a destra dell'ancoraggio. - Se si verifica un overflow, l'elemento viene posizionato con l'opzione di riserva personalizzata denominata
--bottom-span-right
, che lo posiziona conposition-area: bottom span-right
, con un margine aggiuntivo sotto. - Se si verifica un overflow, l'elemento viene posizionato con
flip-inline --bottom-span-right
, che combina l'opzione di riserva personalizzata conflip-inline
, che è essenzialmenteposition-area: bottom span-left
. - Se si verifica un overflow, l'elemento viene posizionato utilizzando l'opzione di riserva personalizzata
--use-alternate
, che lo posiziona sotto un ancoraggio completamente diverso. - Se si verifica un overflow, l'elemento torna al posizionamento originale, con
position-area: end
, anche se è noto che si verifica un overflow.
Ordine di riserva
Per impostazione predefinita, quando la posizione iniziale va in overflow, il browser prova ogni opzione in position-try-fallbacks
finché non trova una posizione che non vada in overflow. Puoi ignorare questo comportamento con position-try-order
per testare ogni opzione di riserva e utilizzare quella che ha più spazio su un asse specificato.
Puoi specificare l'asse con le parole chiave logiche most-block-size
e most-inline-size
oppure con le parole chiave fisiche most-height
e most-width
.
position-try-order
e position-try-fallbacks
possono essere combinati con l'abbreviazione position-try
, con l'ordine che viene per primo.
Scorrimento
Quando un utente scorre la pagina, si aspetta che il movimento sia fluido. Per fare ciò, i browser hanno limiti su come può essere utilizzato il posizionamento dell'ancora durante lo scorrimento.
Anche se puoi collegare un elemento posizionato ad ancore in diversi contenitori di scorrimento, l'elemento si sposterà solo in risposta allo scorrimento di una delle ancore. Questo sarà l'ancora predefinita, ovvero l'ancora implicita di un popover o il valore di position-anchor
.
Noterai che l'elemento posizionato rimane visibile anche quando l'ancora non è più visibile. Per nascondere l'elemento posizionato quando l'ancora è nascosta, imposta position-visibility: anchors-visible
. Questo vale non solo quando l'ancora viene scorre in modo eccessivo, ma anche se è nascosta in altri modi, ad esempio con visibility: hidden
.
Verifica la tua comprensione
Quali sono i valori validi per il lato in anchor()
?
inside
25%
25px
25px
possa essere utilizzata come valore di riserva, solo le percentuali possono essere utilizzate per il lato.block-start
start
Quali sono i valori validi per position-area
?
top
block-end inline-end
block-start block-end
Quali proprietà supportano la funzione anchor()
?
top
margin-left
inset-block-start
transform
Se sono presenti più ancore con lo stesso anchor-name
, cosa succede?