Dostosuj nakładkę elementów sterujących oknami na pasku tytułu PWA

Użyj paska tytułu obok elementów sterujących okna, aby aplikacja PWA wyglądała bardziej jak aplikacja.

Jeśli pamiętasz artykuł Spraw, by Twoja aplikacja PWA wyglądała bardziej jak aplikacja, być może pamiętasz, że o dostosowywaniu paska tytułu aplikacji mówiliśmy wcześniej jako o strategii, dzięki której aplikacja będzie bardziej działać. Oto przykład, jak może to wyglądać aplikacja Podcasty w systemie macOS.

Pasek tytułu aplikacji Podcasty w systemie macOS z przyciskami sterowania multimediami i metadanymi dotyczącymi aktualnie odtwarzanego podcastu.
Dzięki niestandardowemu pasku tytułu Twoja aplikacja PWA przypomina aplikację na danej platformie.

Może cię kusić, by stwierdzić, że Podcasty to aplikacja na macOS na określoną platformę. Nie działa w przeglądarce, więc może robić to, co chcesz, bez konieczności odtwarzania jej reguł. Prawda, ale dobra wiadomość jest taka, że dzięki funkcji nakładki elementów sterujących oknami, o której jest mowa w tym artykule, wkrótce utworzysz podobne interfejsy do Twojej aplikacji PWA.

Komponenty nakładek z elementami sterującymi okna

Nakładka elementów sterujących okna składa się z 4 podfunkcji:

  1. Wartość "window-controls-overlay" pola "display_override" w manifeście aplikacji internetowej.
  2. Zmienne środowiskowe CSS titlebar-area-x, titlebar-area-y, titlebar-area-width i titlebar-area-height.
  3. Standaryzacja wcześniej zastrzeżonej właściwości CSS -webkit-app-region jako właściwości app-region do definiowania możliwych do przeciągania regionów w treści internetowej.
  4. Mechanizm wysyłania zapytań dotyczących regionu elementów sterujących oknami i obchodzenie się z nim za pomocą elementu windowControlsOverlay window.navigator.

Czym jest nakładka z elementami sterującymi okna

Obszar paska tytułu to obszar po lewej lub prawej stronie elementów sterujących okna (czyli przycisków do minimalizowania, maksymalizacji, zamykania itp.) i często zawiera tytuł aplikacji. Elementy sterujące okienkiem Nakładki pozwalają progresywnym aplikacjom internetowym (PWA) działać w sposób podobny do aplikacji, zastępując dotychczasowy pasek tytułu o pełnej szerokości na małą nakładkę z elementami sterującymi okna. Dzięki temu deweloperzy mogą umieszczać niestandardowe treści w obszarze, który wcześniej był kontrolowany przez przeglądarkę.

Obecny stan,

Step Stan
1. Utwórz wyjaśnienie Zakończono
2. Utwórz wstępną wersję roboczą specyfikacji Zakończono
3. Zbieranie opinii i ulepszanie projektu W toku
4. Testowanie origin Ukończono
5. Uruchomienie kampanii Zakończono (w Chromium 104)

Jak używać nakładki z elementami sterującymi okna

Dodaję window-controls-overlay do pliku manifestu aplikacji internetowej

Progresywna aplikacja internetowa może włączyć nakładkę z elementami sterującymi okna, dodając "window-controls-overlay" jako głównego użytkownika "display_override" w manifeście aplikacji internetowej:

{
  "display_override": ["window-controls-overlay"]
}

Nakładka z elementami sterującymi okna jest widoczna tylko wtedy, gdy są spełnione wszystkie te warunki:

  1. Aplikacja nie jest otwarta w przeglądarce, ale w osobnym oknie PWA.
  2. Plik manifestu zawiera "display_override": ["window-controls-overlay"]. (później dozwolone są inne wartości).
  3. Progresywna aplikacja internetowa działa w systemie operacyjnym na komputerze.
  4. Bieżące źródło jest zgodne ze źródłem, dla którego została zainstalowana aplikacja PWA.

W efekcie powstaje pusty obszar paska tytułu z elementami sterującymi okna, które znajdują się po lewej lub prawej stronie (w zależności od systemu operacyjnego).

Okno aplikacji z pustym paskiem tytułu i elementami sterującymi okna po lewej stronie.
Pusty pasek tytułu gotowy z własną treścią.

Przenoszenie treści na pasek tytułu

Teraz na pasku tytułu jest miejsce, więc możesz coś tam przenieść. Na potrzeby tego artykułu stworzyłem aplikację PWA Polecane treści w Wikimedia. Przydatną funkcją w tej aplikacji może być wyszukiwanie słów w tytułach artykułów. Kod HTML funkcji wyszukiwania wygląda tak:

<div class="search">
  <img src="logo.svg" alt="Wikimedia logo." width="32" height="32" />
  <label>
    <input type="search" />
    Search for words in articles
  </label>
</div>

Aby przenieść element div w górę na pasek tytułu, potrzebny jest kod CSS:

.search {
  /* Make sure the `div` stays there, even when scrolling. */
  position: fixed;
  /**
   * Gradient, because why not. Endless opportunities.
   * The gradient ends in `#36c`, which happens to be the app's
   * `<meta name="theme-color" content="#36c">`.
   */
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
  /* Use the environment variable for the left anchoring with a fallback. */
  left: env(titlebar-area-x, 0);
  /* Use the environment variable for the top anchoring with a fallback. */
  top: env(titlebar-area-y, 0);
  /* Use the environment variable for setting the width with a fallback. */
  width: env(titlebar-area-width, 100%);
  /* Use the environment variable for setting the height with a fallback. */
  height: env(titlebar-area-height, 33px);
}

Efekt użycia tego kodu widać na zrzucie ekranu poniżej. Pasek tytułu jest w pełni responsywny. Przy zmianie rozmiaru okna PWA pasek tytułu zachowuje się tak, jakby składał się ze zwykłej treści HTML, co w rzeczywistości jest.

Okno aplikacji z paskiem wyszukiwania na pasku tytułu.
Nowy pasek tytułu jest aktywny i elastyczny.

Określanie, które części paska tytułu można przeciągać

Powyższy zrzut ekranu sugeruje, że to już wszystko. Okna PWA nie można już przeciągać (oprócz bardzo małego obszaru), ponieważ przyciski ich elementów nie są obszarami przeciągania, a reszta paska tytułu składa się z widżetu wyszukiwania. Napraw to, korzystając z właściwości CSS app-region o wartości drag. W konkretnym przypadku można przeciągać wszystko poza elementem input.

/* The entire search `div` is draggable… */
.search {
  -webkit-app-region: drag;
  app-region: drag;
}

/* …except for the `input`. */
input {
  -webkit-app-region: no-drag;
  app-region: no-drag;
}

Gdy ta usługa jest zainstalowana, użytkownik może jak zwykle przeciągać okno aplikacji, przeciągając div, img lub label. Interaktywny jest tylko element input, dlatego można wpisać zapytanie.

Wykrywanie funkcji

Obsługa nakładki z elementami sterującymi okna można wykryć, testując element windowControlsOverlay:

if ('windowControlsOverlay' in navigator) {
  // Window Controls Overlay is supported.
}

Wysyłanie zapytania o region elementów sterujących okna za pomocą funkcji windowControlsOverlay

Z kodem jest na razie tylko jeden problem: na niektórych platformach elementy sterujące oknami znajdują się po prawej stronie, a na innych po lewej. Aby jeszcze bardziej pogorszyć sytuację, również menu Chrome z 3 kropkami zmieni się w zależności od platformy. Oznacza to, że obraz tła z gradientem liniowym musi być dynamicznie dostosowywany w taki sposób, aby zaczynał się od #131313maroon lub maroon#131313maroon w taki sposób, aby wtapiał się w kolor tła paska tytułu maroon określony przez <meta name="theme-color" content="maroon">. Można to osiągnąć, wysyłając zapytanie do interfejsu getTitlebarAreaRect() API we właściwości navigator.windowControlsOverlay.

if ('windowControlsOverlay' in navigator) {
  const { x } = navigator.windowControlsOverlay.getTitlebarAreaRect();
  // Window controls are on the right (like on Windows).
  // Chrome menu is left of the window controls.
  // [ windowControlsOverlay___________________ […] [_] [■] [X] ]
  if (x === 0) {
    div.classList.add('search-controls-right');
  }
  // Window controls are on the left (like on macOS).
  // Chrome menu is right of the window controls overlay.
  // [ [X] [_] [■] ___________________windowControlsOverlay [⋮] ]
  else {
    div.classList.add('search-controls-left');
  }
} else {
  // When running in a non-supporting browser tab.
  div.classList.add('search-controls-right');
}

Zamiast obrazu tła bezpośrednio w regułach CSS klasy .search (jak wcześniej) zmodyfikowany kod wykorzystuje teraz 2 klasy, które powyższy kod ustawia dynamicznie.

/* For macOS: */
.search-controls-left {
  background-image: linear-gradient(90deg, #36c, 45%, #131313, 90%, #36c);
}

/* For Windows: */
.search-controls-right {
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
}

Ustalam, czy nakładka elementów sterujących okna jest widoczna

Nakładka z elementami sterującymi okna nie zawsze będzie widoczna w obszarze paska tytułu. Zwykle nie ma jej w przeglądarkach, które nie obsługują nakładki elementów sterujących oknami, ale nie będzie ona również dostępna, gdy dana PWA zostanie uruchomiona na karcie. Aby wykryć taką sytuację, możesz wysłać zapytanie do właściwości visible obiektu windowControlsOverlay:

if (navigator.windowControlsOverlay.visible) {
  // The window controls overlay is visible in the title bar area.
}

Możesz też użyć zapytania o media display-mode w kodzie JavaScript lub CSS:

// Create the query list.
const mediaQueryList = window.matchMedia('(display-mode: window-controls-overlay)');

// Define a callback function for the event listener.
function handleDisplayModeChange(mql) {
  // React on display mode changes.
}

// Run the display mode change handler once.
handleDisplayChange(mediaQueryList);

// Add the callback function as a listener to the query list.
mediaQueryList.addEventListener('change', handleDisplayModeChange);
@media (display-mode: window-controls-overlay) { 
  /* React on display mode changes. */ 
}

Powiadomienia o zmianach geometrii

Zapytanie o obszar nakładki elementów sterujących oknami getTitlebarAreaRect() może wystarczyć na przykład na ustawienie prawidłowego obrazu tła w zależności od tego, gdzie znajdują się elementy sterujące okna. Jednak w innych przypadkach konieczna jest bardziej szczegółowa kontrola. Można na przykład dostosować nakładkę z elementami sterującymi okna do ilości dostępnego miejsca i dodać żart bezpośrednio do nakładki z elementami sterującymi okna, gdy jest na niej wystarczająco dużo miejsca.

Okno umożliwia nakładanie obszaru na wąskie okno ze skróconym tekstem.
Elementy sterujące na pasku tytułu przystosowane do wąskiego okna.

Aby otrzymywać powiadomienia o zmianach geometrycznych, zasubskrybuj navigator.windowControlsOverlay.ongeometrychange lub skonfiguruj odbiornik zdarzenia geometrychange. To zdarzenie jest uruchamiane tylko wtedy, gdy widoczna jest nakładka elementów sterujących oknami, czyli gdy navigator.windowControlsOverlay.visible ma wartość true.

const debounce = (func, wait) => {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

if ('windowControlsOverlay' in navigator) {
  navigator.windowControlsOverlay.ongeometrychange = debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250);
}

Zamiast przypisywać funkcję do ongeometrychange, możesz też dodać detektor zdarzeń do: windowControlsOverlay, jak pokazano poniżej. Więcej informacji o różnicach między nimi znajdziesz na MDN.

navigator.windowControlsOverlay.addEventListener(
  'geometrychange',
  debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250),
);

Zgodność w przypadku uruchamiania na karcie i w nieobsługiwanych przeglądarkach

Dostępne są 2 przypadki, które warto wziąć pod uwagę:

  • Aplikacja działa w przeglądarce, która obsługuje nakładkę z elementami sterującymi okna, ale aplikacja jest używana na karcie przeglądarki.
  • Problem z działaniem aplikacji w przeglądarce, która nie obsługuje nakładki elementów sterujących oknami.

W obu przypadkach domyślnie kod HTML utworzony na potrzeby nakładki z elementami sterującymi okna będzie wyświetlany w tekście, tak jak zwykła treść HTML, a wartości zastępcze zmiennych env() będą używane do pozycjonowania. W obsługiwanych przeglądarkach możesz też zrezygnować z wyświetlania kodu HTML przeznaczonego dla nakładki z elementami sterującymi okna. W tym celu sprawdź właściwość visible nakładki, a jeśli zawiera ona wartość false, ukryj tę treść HTML.

PWA działająca w karcie przeglądarki z nakładką z elementami sterującymi okna wyświetlaną w treści.
W starszych przeglądarkach elementy sterujące na pasku tytułu mogą się łatwo wyświetlać w treści strony.

Przypominamy, że przeglądarki, które nie obsługują takiej właściwości, w ogóle nie biorą pod uwagę właściwości manifestu aplikacji internetowej "display_override" lub nie rozpoznają parametru "window-controls-overlay" i dlatego korzystają z następnej możliwej wartości zgodnie z łańcuchem kreacji zastępczych, np. "standalone".

PWA działająca w trybie samodzielnym z nakładką z elementami sterującymi okna wyświetlaną w treści.
W starszych przeglądarkach elementy sterujące na pasku tytułu mogą się łatwo wyświetlać w treści strony.

Uwagi na temat interfejsu użytkownika

Chociaż może to być kuszące, nie zalecamy tworzenia klasycznego menu w obszarze Nakładka elementów sterujących oknami. Takie działanie narusza wytyczne dotyczące projektowania w systemie macOS, czyli platformy, na której użytkownicy oczekują pasków menu (zarówno dostarczanych przez system, jak i niestandardowych) u góry ekranu.

Jeśli aplikacja działa w trybie pełnoekranowym, zastanów się, czy nakładka z elementami sterującymi okna powinna być częścią widoku pełnoekranowego. Być może zechcesz zmienić układ układu po uruchomieniu zdarzenia onfullscreenchange.

Pokaz

Przygotowałem demonstrację, z której możesz korzystać w różnych przeglądarkach, które obsługują i nie obsługują, oraz w zainstalowanych i niezainstalowanych przeglądarkach. Aby korzystać z nakładki z elementami sterującymi okna, musisz zainstalować aplikację. Poniżej znajdziesz dwa zrzuty ekranu. Kod źródłowy aplikacji jest dostępny w Glitch.

Aplikacja demonstracyjna Polecane treści z witryny Wikimedia z nakładką elementów sterujących oknami.
Aplikacja demonstracyjna umożliwia eksperymentowanie.

Funkcja wyszukiwania w nakładce z elementami sterującymi w oknie jest w pełni funkcjonalna:

Aplikacja demonstracyjna Polecane treści w serwisie Wikimedia z nałożonymi elementami sterującymi oknami i aktywnym wyszukiwaniem hasła „kleopa...” wyróżniająca jeden z artykułów z dopasowanym hasłem „Kleopatra”.
Funkcja wyszukiwania z nakładką elementów sterujących okna.

Bezpieczeństwo

Zespół Chromium zaprojektował i wdrożył interfejs Window Controls Overlay API zgodnie z podstawowymi zasadami określonymi w artykule Kontrolowanie dostępu do zaawansowanych funkcji platformy internetowej, w tym dotyczących kontroli użytkownika, przejrzystości i ergonomii.

Podszywanie się

Dzięki temu, że witryny mają częściową kontrolę nad paskiem tytułu, deweloperzy mogą podszyć się pod treści w regionie, który wcześniej był zaufany i kontrolowany przez przeglądarkę. Obecnie w przeglądarce Chromium w trybie samodzielnym znajduje się pasek tytułu, który przy pierwszym uruchomieniu wyświetla tytuł strony internetowej po lewej stronie, a po prawej stronie – źródło strony (po prawej stronie – przycisk „Ustawienia i inne opcje” oraz opcje okna). Po kilku sekundach tekst źródłowy zniknie. Jeśli w przeglądarce jest ustawiony język od prawej do lewej (RTL), ten układ jest odwrócony, tak aby tekst źródłowy znajdował się po lewej stronie. Powoduje to otwarcie nakładki z elementami sterującymi okna, która umożliwia podszywanie się pod źródło, jeśli dopełnienie między punktem początkowym a prawą krawędzią nakładki jest niewystarczające. Na przykład do adresu „evil.ltd” można dodać zaufaną witrynę „google.com”, dzięki czemu użytkownicy będą myśleć, że to źródło jest wiarygodne. Planujemy zachować tekst źródłowy, aby użytkownicy wiedzieli, jakie jest źródło aplikacji, i mogli mieć pewność, że jest on zgodny z ich oczekiwaniami. W przypadku przeglądarek skonfigurowanych od prawej do lewej strony musi znajdować się wystarczające dopełnienie z prawej strony tekstu, aby złośliwa witryna nie mogła dołączyć niebezpiecznego źródła do zaufanego źródła.

Odcisk cyfrowy

Włączenie nakładek z elementami sterującymi okna i obszarów, które można przeciągać, nie stwarzają istotnych problemów z ochroną prywatności poza wykrywaniem cech. Jednak ze względu na różne rozmiary i położenie przycisków sterowania oknami w różnych systemach operacyjnych metoda navigator.windowControlsOverlay.getTitlebarAreaRect() zwraca jednak wartość DOMRect, której pozycja i wymiary ujawniają informacje o systemie operacyjnym, na którym działa przeglądarka. Obecnie deweloperzy mogą już wykrywać system operacyjny na podstawie ciągu znaków klienta użytkownika, ale z powodu problemów z odciskami cyfrowymi trwa dyskusja na temat blokowania ciągu znaków UA i ujednolicania wersji systemu operacyjnego. Nieustannie pracujemy w społeczności przeglądarek, aby zrozumieć, jak często rozmiar elementów sterujących oknami zmienia się na różnych platformach. Obecnie przyjmuje się, że rozwiązania te są dość stabilne niezależnie od wersji systemu operacyjnego i dlatego nie są przydatne przy obserwacjach mniejszych wersji systemów operacyjnych. Chociaż może to być problem z odciskiem cyfrowym, dotyczy tylko zainstalowanych aplikacji PWA, które korzystają z funkcji niestandardowego paska tytułu i nie dotyczy używania przeglądarki. Dodatkowo interfejs navigator.windowControlsOverlay API nie będzie dostępny w przypadku elementów iframe umieszczonych w PWA.

Przejście do innego źródła w aplikacji PWA spowoduje powrót do normalnego, niezależnego paska tytułu, nawet jeśli spełnia on powyższe kryteria i jest uruchomiony z nakładką z elementami sterującymi okna. Ma to na celu dostosowanie czarnego paska, który pojawia się podczas przechodzenia do innego źródła. Po powrocie do pierwotnego źródła zostanie ponownie użyta nakładka z elementami sterującymi okna.

Czarny pasek adresu URL do nawigacji poza źródłem.
Gdy użytkownik przechodzi do innego źródła, wyświetla się czarny pasek.

Prześlij opinię

Zespół Chromium chce poznać Twoją opinię o interfejsie Window Controls Overlay API.

Opowiedz nam o projekcie interfejsu API

Czy jest coś, co nie działa w interfejsie API zgodnie z oczekiwaniami? A może brakuje metod lub właściwości, które potrzebujesz do realizacji swojego pomysłu? Masz pytanie lub komentarz na temat modelu bezpieczeństwa? Zgłoś problem ze specyfikacją w odpowiednim repozytorium GitHub lub dodaj swoje uwagi na temat istniejącego problemu.

Zgłoś problem z implementacją

Czy wystąpił błąd w implementacji Chromium? A może implementacja różni się od specyfikacji? Zgłoś błąd na new.crbug.com. Podaj jak najwięcej szczegółów i proste instrukcje dotyczące odtwarzania oraz wpisz UI>Browser>WebAppInstalls w polu Komponenty. Usterki to świetny sposób na udostępnianie szybkich i łatwych replik.

Pokaż obsługę interfejsu API

Czy zamierzasz użyć interfejsu Window Controls Overlay API? Twoja publiczna pomoc pomaga zespołowi Chromium priorytetowo traktować funkcje i pokazuje innym dostawcom przeglądarek, jak ważne jest ich wsparcie.

Wyślij tweeta na adres @ChromiumDev, używając hashtagu #WindowControlsOverlay, i daj nam znać, gdzie i w jaki sposób go używasz.

Przydatne linki

Podziękowania

Nakładka elementów sterujących okna została zaimplementowana i określona przez Amanda Baker z zespołu Microsoft Edge. Ten artykuł napisali Joe Medley i Kenneth Rohde Christiansen. Baner powitalny od Sigmunda w serwisie Unsplash.