Popover = hint

Data publikacji: 26 lutego 2025 r.

Chrome 133 rozwija dotychczasową funkcję wyskakujących okienek, wprowadzając nowy tryb:popover="hint". Ten tryb zarządzany przez przeglądarkę umożliwia nowy kontekst układania, który upraszcza tworzenie etykiet narzędzia i podobnych elementów krótkotrwałych. Zmniejsza wysiłek programistów przy jednoczesnym zachowaniu elastyczności projektu.

Wprowadzenie i historia

Interfejs Popover API, wprowadzony w Chrome 114, umożliwia tworzenie dostępnych interfejsów typu okienka, takich jak menu i etykiety. Domyślnie popover="auto" obsługuje funkcję usuwania i zarządzania fokusem, nie wymagając dodatkowych skryptów. Więcej informacji znajdziesz w artykule Wprowadzenie do interfejsu Popover API. Podczas otwierania wyskakującego okienka popover="auto" wszystkie inne wyskakujące okienka bez elementów nadrzędnych z popover="auto" zostaną zamknięte, co czyni interfejs API bardziej ergonomicznym i odpowiedającym potrzebom użytkowników.

Wyskakujące okienka zamykające inne wyskakujące okienka

<div id="p1" popover>First Popover</div>
<button popovertarget="p1">Open popover 1</button>
<div id="p2" popover>Second Popover</div>
<button popovertarget="p2">Open popover 2</button>

W tym przykładzie otwarcie wyskakującego okienka 2 spowoduje zamknięcie wyskakującego okienka 1, ponieważ popover="auto" pozwala na otwarcie tylko jednego takiego okienka naraz.

Takie zachowanie sprawdza się w przypadku menu i dialogów, ale może powodować problemy, gdy na ekranie wyświetla się kilka typów pływających elementów interfejsu. Na przykład menu i okienko informacyjne, które używają właściwości popover="auto", mogą się ze sobą pokrywać, co spowoduje, że otwarcie okienka informacyjnego spowoduje zamknięcie menu. Może się wydawać, że to nietypowa sytuacja, ale często występuje w interfejsach nowoczesnych aplikacji. Na przykład menu w nagłówku github.com używają popoverów zarówno do menu, jak i etykietek, dzięki czemu w określonych warunkach są widoczne jednocześnie:

Otwarte menu
Menu GitHuba.

Jednym ze sposobów rozwiązania tego problemu jest użycie elementu popover="manual" dla elementów tooltipa, co umożliwia pełną kontrolę nad wyskakującym oknem za pomocą skryptu. Wymaga to jednak ponownego zaimplementowania zachowania nakładania się, lekkiego odrzucenia i zarządzania fokusem – czyli dokładnie tych zadań, do których został stworzony interfejs API Popover. Dlatego zaczęliśmy szukać sposobów rozszerzenia interfejsu API, aby udostępnić tę brakującą funkcję.

W badaniu przeprowadzonym wśród deweloperów zidentyfikowaliśmy 2 najczęstsze konteksty nakładania:

  • Stały interfejs użytkownika: np. menu i okna dialogowe.
  • Interfejs użytkownika o krótkim czasie wyświetlania: na przykład karty informacyjne i etykiety.

Aby uwzględnić oba te przypadki, popover="hint" wprowadza drugi stos, różniący się od popover="auto", dzięki czemu menu pozostają otwarte nawet wtedy, gdy pojawiają się etykiety. Zamiast wprowadzać wiele kontekstów nakładania się dla różnych typów interfejsu (co oznaczałoby w istocie wynalezienie z-index na nowo) to podejście upraszcza sprawy poprzez zdefiniowanie tylko 2 ogólnych kategorii: trwały interfejs użytkownika (auto) i ulotny interfejs użytkownika (hint). Dzięki temu osiąga się równowagę między elastycznością a unikaniem powrotu do tych samych problemów, które występowały przed wprowadzeniem wyskakujących okienek.

Zachowanie nowej wartości

Zarówno popover="auto", jak i popover="hint" obsługują łatwe zamykanie, co oznacza, że zamykane są automatycznie, gdy użytkownik kliknie poza nimi lub naciśnie Esc na klawiaturze. W tym przypadku oba style są identyczne.

Jeśli chodzi o przymusowe ukrywanie innych wyskakujących okienek, popover="auto" zamyka wszystkie inne wyskakujące okienka autohint po ich otwarciu, co zapewnia, że tylko jedno takie wyskakujące okienko jest aktywne w danym momencie (jedynym wyjątkiem są zagnieżdżone wyskakujące okienka, o których mowa poniżej). Z drugiej strony, popover="hint" tylko wymusza ukrycie innych hint, co pozwala menu i etykietkom pozostać otwartymi i współistnieć.

Największe różnice występują w ich zachowaniach związanych z gniazdowaniem. popover="auto"obsługuje zagnieżdżanie, co pozwala na pozostawienie otwartego wyskakującego okienka podrzędnego w ramach innego nadrzędnego wyskakującego okienka. popover="hint" ma specjalne zachowanie dotyczące zagnieżdżania, które wykorzystuje oddzielne „zbiory”. Gdy wyskakujące okienko hint znajduje się w wyskakującym okienku auto, dołącza się do grupy auto, aby zachować grupowanie kontekstowe. Oznacza to, że będzie otwarte, dopóki inne wyskakujące okienka auto lub hint nie zmuszą go do przymusowego ukrycia. Dzięki temu tooltipy nie będą przerywać innych menu ani wyskakujących okienek.

Na koniec, w przypadku bardzo różnych przypadków użycia, zawsze możesz użyć elementu popover="manual", który nie ma wbudowanych żadnych z tych zachowań, co pozwala Ci określić dokładną funkcję i pożądane zachowanie.

popover="auto" popover="hint" popover="manual"
Odrzuć światło Tak Tak Nie
Wymuszenie ukrycia: Niepowiązane auto i hint Niepowiązane elementy hint Nothing
Umieszczanie: Tak Specjalne (opisane wcześniej) Nie dotyczy – brak możliwości wyłączenia światła

Aktywacja po najechaniu

Typowym wzorcem UX jest użycie kursora do wywołania informacji. Jeśli najedziesz kursorem na element przez jakiś czas, wyświetli się wizytówka. Obecnie takie działanie musisz zaimplementować za pomocą kodu JavaScriptu, np. przez dodanie odbiorników dla zdarzeń mouseentermouseleave. Trwają jednak prace nad innym interfejsem API, który powinien umożliwić deklaratywny sposób uruchamiania akcji po najechaniu kursorem: interfejsem API wywołujących zainteresowanie.

Ten interfejs API jest nadal w fazie rozwoju, ale ogólna idea polega na dodaniu atrybutu interesttarget do wielu typów elementów, co powoduje, że po najechaniu na nie kursorem myszy będą one się zachowywać w określony sposób:

<a interesttarget="my-hovercard" href="...">
  Hover to show the hovercard
</a>
<span popover="hint" id="my-hovercard">
  This is the hovercard
</span> 

Poniższy kod HTML spowoduje, że po najechaniu kursorem na link <a> automatycznie wyświetli się wyskakujące okienko my-hovercard. Przesunięcie wskaźnika poza ten element spowoduje ukrycie wyskakującego okienka. Wszystko bez JavaScriptu.

Przykłady

<button>An interesting button</button>
<div popover="hint">More info about the button</div>
[popover] {
  margin: 0;
  inset: auto;
  position-area: bottom right;
}
const button = document.querySelector('button');
const popover = document.querySelector('[popover]');

button.onmouseenter = () => {
  setTimeout(() => {
    popover.showPopover({source: button});
  }, 500);
}

button.onmouseleave = () => {
  setTimeout(() => {
    popover.hidePopover();
  }, 500);
}
Przycisk z etykietą
Wypróbuj to na żywo.

W tym przykładzie użyto funkcji popover="hint" do utworzenia podstawowej etykiety, która wyświetla więcej informacji o przycisku po najechaniu na niego kursorem myszy. Aktywacja przez najechanie kursorem jest obsługiwana przez metody obsługi zdarzeń mouseentermouseleave z opóźnieniem 0,5 s. Pamiętaj, że ten przykład nie uwzględnia kilku szczegółów:

  1. Najechanie kursorem na samą kartę nie powoduje jej zamknięcia, gdy odsuniesz kursor od elementu wywołującego. Nie można więc kopiować ani wklejać tekstu z wyskakującego okienka.
  2. Nie ma „odblokowywania”: najechanie kursorem na przycisk przez ułamek sekundy powoduje wyświetlenie wyskakującego okienka, nawet jeśli kursor szybko zniknie z przycisku przed upływem czasu opóźnienia. W takim przypadku podpowiedź „miga”, otwierając się i zamykając bardzo szybko.
  3. Przykład jest całkowicie niedostępny: użytkownik, który nie używa myszy, nie może wyświetlić zawartości opisu.

Te niedociągnięcia można naprawić za pomocą dodatkowego kodu JavaScript. Na przykład, aby umożliwić obsługę aktywacji wyskakującego okienka za pomocą klawiatury, należy dodać metody obsługi zdarzeń focus (lub keydownkeyup)). Aby dowiedzieć się, na co zwrócić uwagę, aby tooltip był dostępny, przeczytaj ten świetny post na blogu autorstwa Sarah Higley. Wszystkie te problemy (i nie tylko) będą automatycznie obsługiwane w sposób deklaratywny przez interfejs API invokers Interest.

Więcej informacji

Więcej informacji znajdziesz w opisie funkcji lub w specyfikacji HTML.