Podczas tworzenia etykietek lub wyskakujących okienek za pomocą pozycjonowania zakotwiczonego CSS przeglądarka może automatycznie „odwrócić” element do pozycji zastępczej, jeśli w przeciwnym razie przekroczyłby on widoczny obszar. W takich przypadkach możesz dostosować styl pozycjonowanej treści, np. zmienić położenie strzałki, która wskazuje od pozycjonowanej treści do kotwicy.
Zapytania o zakotwiczone kontenery rozwiązują ten problem, umożliwiając wysyłanie zapytań o aktywny stan pozycjonowania elementu i odpowiednie stosowanie stylów. Ogólne informacje o pozycjonowaniu zakotwiczonych menu i menu wysuwanych z odwracaniem kolizji widocznego obszaru (bez zmiany stylu strzałki kierunkowej) znajdziesz w artykule Menu uwzględniające widoczny obszar.
Problem
Wyobraź sobie etykietkę, która domyślnie pojawia się nad kotwicą. Na dole znajduje się strzałka w dół. Jeśli użytkownik przewinie stronę i etykietka pojawi się poniżej kotwicy, strzałka będzie wskazywać niewłaściwy kierunek i będzie znajdować się po niewłaściwej stronie etykietki.
Rozwiązanie: zapytania dotyczące kontenerów zakotwiczonych
Ustawiając container-type: anchored na elemencie pozycjonowanym, zmieniasz go w kontener zapytania, który zna swój stan pozycjonowania zakotwiczonego. Następnie możesz użyć zapytania @container anchored(), aby zaktualizować elementy podrzędne lub pseudoelementy.
1. Tworzenie etykietki i aktywatora
Użyj interfejsu Popover API, aby utworzyć etykietkę. Wywołanie elementu popover za pomocą popovertarget automatycznie ustanawia niejawne połączenie zakotwiczone z przyciskiem aktywującym, więc nie jest wymagane jawne użycie anchor-name ani position-anchor.
<button popovertarget="tooltip" id="anchor" aria-describedby="tooltip">anchor</button>
<div id="tooltip" popover role="tooltip"></div>
Resetowanie stylów wstawki i marginesu wyskakującego okienka do użycia z pozycjonowaniem zakotwiczonym, ale tylko wtedy, gdy pozycjonowanie zakotwiczone jest obsługiwane.
@supports (anchor-name: --my-anchor) {
[popover] {
inset: auto;
margin: unset;
}
}
2. Konfigurowanie kontenera
Zastosuj container-type: anchored do elementu, który ma zostać umieszczony. Aby włączyć odwracanie, ten element musi mieć też zdefiniowany atrybut position-try-fallbacks.
#tooltip {
position: fixed;
position-area: block-start;
position-try-fallbacks: flip-block;
/* Enable anchored container queries */
container-type: anchored;
}
3. Styl oparty na kreacji zastępczej
Użyj @container anchored(fallback: <value>), aby zastosować style, gdy aktywna jest określona kreacja zastępcza.
Podobnie jak w przypadku wszystkich zapytań o kontener, @container może stylizować tylko elementy podrzędne kontenera. Częstą strategią tworzenia strzałek jest użycie pseudoelementów ::before i ::after, które są traktowane jako elementy podrzędne i mogą być stylizowane bezpośrednio. Aby jednak nadać styl samej etykiecie (jak w kroku 4), dodamy do niej element podrzędny i utworzymy strzałkę w jego pseudoelemencie ::before.
<div id="tooltip" popover role="tooltip">
<div class="tooltip-content">Tooltip</div>
</div>
.tooltip-content::before {
/* Default "down" arrow for the 'top' position */
content: "▼";
position: absolute;
inset-block-end: 0;
inset-inline-start: 1rem;
}
/* Update to an "up" arrow when the 'flip-block' fallback (bottom) is active */
@container anchored(fallback: flip-block) {
.tooltip-content::before {
content: "▲";
inset-block-start: 0;
inset-block-end: auto;
}
}
4. Stylizowanie samego kontenera
Jeśli chcesz zmienić właściwości samego kontenera (np. margin lub background-color) podczas jego odwracania, użyj wewnętrznego elementu opakowującego.
- Zastosuj
container-type: anchoreddo zewnętrznego elementu pozycjonowanego. - Ustaw element wewnętrzny w bloku
@containerjako element docelowy.
@container anchored(fallback: flip-block) {
.tooltip-content {
border-radius: 0 0 .5rem .5rem;
margin-block-start: 0.25rem;
}
}
Sprawdzone metody
- Preferuj logiczne wartości zastępcze: używaj słów kluczowych takich jak
flip-blockiflip-inlinewposition-try-fallbacks, aby uprościć zapytania, które automatycznie obsługują języki zapisywane od prawej do lewej i różne tryby pisania. - Używaj pseudoelementów do strzałek: strzałki etykietek mają charakter czysto dekoracyjny i doskonale nadają się do użycia z
::beforelub::after, które można stylizować za pomocą zapytań o zakotwiczony kontener bez dodatkowego modelu DOM.
Strategie zastępcze
Pozycjonowanie strzałki na podstawie zastosowanego elementu zastępczego to progresywne ulepszanie i nie ma innego sposobu reagowania na pozycję elementu zastępczego. Aby ukryć strzałkę w przeglądarkach, które nie obsługują zapytań o kontener pozycji zakotwiczenia, przetestuj obsługę CSS za pomocą @supports (container-type: anchored).
@supports (container-type: anchored) {
.tooltip-content::before {
content: "▼";
}
}
Kreacje zastępcze i obsługa wyskakujących okienek w przeglądarkach
Interfejs Popover API to głównie progresywne ulepszanie, ale jego definiujące zachowania – promowanie warstwy górnej, lekkie odrzucanie i wywoływanie popovertarget – nie mają odpowiednika tylko w CSS. Starsze przeglądarki wymagają polyfilla lub ręcznego rozwiązania zastępczego, jeśli nie chcesz go dostarczać.
Polyfill: aby obsługiwać atrybut popover w starszych przeglądarkach, warunkowo wczytuj @oddbird/popover-polyfill. OBOWIĄZKOWO: wykryj funkcję, sprawdzając właściwość popover w HTMLElement.prototype, i wczytaj polyfill tylko wtedy, gdy brakuje obsługi natywnej – NIE wczytuj go bezwarunkowo.
Za pomocą bundlera lub mapy importu:
// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
if (!("popover" in HTMLElement.prototype)) {
import("@oddbird/popover-polyfill");
}
Bez bundlera, importuj z sieci CDN w tagu <script type="module">:
<script type="module">
if (!("popover" in HTMLElement.prototype)) {
import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
}
</script>
Uwaga dotycząca stylów: polyfill nie może zdefiniować rzeczywistej pseudoklasy :popover-open, więc zamiast tego stosuje klasę .\:popover-open. OBOWIĄZKOWO: połącz te 2 właściwości za pomocą :is() lub :where(), w przeciwnym razie przeglądarki, które nie obsługują :popover-open, odrzucą całą regułę:
[popover]:is(:popover-open, .\:popover-open) {
display: block;
}
Możesz też użyć position: fixed i ręcznie obliczyć współrzędne za pomocą getBoundingClientRect() lub polegać na domyślnym pozycjonowaniu za pomocą inset: auto, jeśli jest to akceptowalne w danym przypadku użycia.
Przeglądarki, które nie obsługują interfejsu Popover API, nie obsługują też pozycjonowania kotwicy, więc etykietka pojawi się na środku ekranu.