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

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

Jeśli pamiętasz mój artykuł Spraw, aby Twoja aplikacja PWA wyglądała bardziej jak aplikacja, być może przypomnisz sobie, jak wspomniałem o dostosowywaniu paska tytułu aplikacji jako strategii tworzenia środowiska bardziej przypominającego aplikację. Oto przykład, jak to może wyglądać w aplikacji Podcasty na macOS.

Pasek tytułu aplikacji Podcasty na macOS z przyciskami sterowania multimediami i metadanymi odtwarzanego podcastu.
Dzięki niestandardowemu paskowi tytułu aplikacja PWA wygląda bardziej jak aplikacja na konkretną platformę.

Możesz teraz zaprotestować, mówiąc, że Podcasty to aplikacja na macOS, która nie działa w przeglądarce, więc może robić, co chce, bez konieczności przestrzegania zasad przeglądarki. To prawda, ale dobra wiadomość jest taka, że funkcja nakładki elementów sterujących oknem, której dotyczy ten artykuł, wkrótce umożliwi Ci tworzenie podobnych interfejsów użytkownika dla Twojej progresywnej aplikacji internetowej.

Komponenty nakładki z elementami sterującymi okna

Nakładka z elementami sterującymi okna składa się z 4 funkcji:

  1. Wartość "window-controls-overlay" w polu "display_override" w pliku manifestu 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 regionów, które można przeciągać w treściach internetowych.
  4. Mechanizm wysyłania zapytań dotyczących regionu elementów sterujących oknem i jego obejścia za pomocą elementu windowControlsOverlay interfejsu window.navigator.

Co to jest nakładka z elementami sterującymi okna

Obszar paska tytułu to przestrzeń po lewej lub prawej stronie elementów sterujących oknem (czyli przycisków minimalizowania, maksymalizowania, zamykania itp.), która często zawiera tytuł aplikacji. Nakładka z elementami sterującymi okna pozwala progresywnym aplikacjom internetowym (PWA) działać bardziej jak aplikacje, ponieważ zastępuje istniejący pasek tytułu o pełnej szerokości małą nakładką zawierającą elementy sterujące oknem. Umożliwia to deweloperom umieszczanie niestandardowych treści w obszarze paska tytułu, który wcześniej był kontrolowany przez przeglądarkę.

Obecny stan,

Krok Stan
1. Tworzenie wyjaśnienia Zakończono
2. Tworzenie wstępnej wersji specyfikacji Zakończono
3. Zbieranie opinii i ulepszanie projektu W toku
4. Wersja próbna origin Zakończone
5. Uruchom Zakończono (w Chromium 104)

Jak korzystać z nakładki z elementami sterującymi okna

Dodawanie window-controls-overlay do pliku manifestu aplikacji internetowej

Progresywna aplikacja internetowa może włączyć nakładkę elementów sterujących oknem, dodając "window-controls-overlay" jako głównego członka "display_override" w pliku manifestu aplikacji internetowej:

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

Nakładka elementów sterujących oknem będzie widoczna tylko wtedy, gdy spełnione są wszystkie te warunki:

  1. Aplikacja nie otworzy się w przeglądarce, ale w osobnym oknie PWA.
  2. Plik manifestu zawiera "display_override": ["window-controls-overlay"]. (Dopuszczalne są inne wartości).
  3. Progresywna aplikacja internetowa działa w systemie operacyjnym na komputerze.
  4. Obecne źródło jest zgodne ze źródłem, dla którego zainstalowano PWA.

W efekcie pasek tytułu jest pusty, a standardowe elementy sterujące oknem 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 po lewej stronie.
Pasek tytułu bez treści, gotowy do dodania własnych elementów.

Przenoszenie treści na pasek tytułu

Teraz, gdy na pasku tytułu jest miejsce, możesz przenieść tam element. Na potrzeby tego artykułu stworzyłem progresywną aplikację internetową z polecanymi treściami z Wikipedii. Przydatną funkcją 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ść ten element div na pasek tytułu, potrzebujesz kodu 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 tego kodu możesz zobaczyć na zrzucie ekranu poniżej. Pasek tytułu jest w pełni responsywny. Gdy zmieniasz rozmiar okna aplikacji PWA, pasek tytułu reaguje tak, jakby składał się ze zwykłej treści HTML, co w rzeczywistości ma miejsce.

Okno aplikacji z paskiem wyszukiwania na pasku tytułu.
Nowy pasek tytułu jest aktywny i reaguje na działania użytkownika.

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

Zrzut ekranu powyżej sugeruje, że wszystko jest gotowe, ale to jeszcze nie koniec. Okna aplikacji PWA nie można już przeciągać (z wyjątkiem bardzo małego obszaru), ponieważ przyciski sterujące oknem nie są obszarami przeciągania, a pozostała część paska tytułu składa się z widżetu wyszukiwania. Aby to naprawić, użyj właściwości CSS app-region z wartością drag. W konkretnym przypadku można ustawić, aby wszystkie elementy poza elementem input były możliwe do przeciągania.

/* 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;
}

Po zastosowaniu tego kodu CSS użytkownik może przeciągać okno aplikacji w zwykły sposób, przeciągając div, img lub label. Interaktywny jest tylko element input, dzięki czemu można wpisać zapytanie.

Wykrywanie cech

Obsługę nakładki z elementami sterującymi okna można wykryć, sprawdzając, czy istnieje element windowControlsOverlay:

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

Wysyłanie zapytania do regionu elementów sterujących oknem za pomocą windowControlsOverlay

Dotychczasowy kod ma jeden problem: na niektórych platformach elementy sterujące okna znajdują się po prawej stronie, a na innych – po lewej. Co gorsza, menu Chrome z „3 kropkami” będzie też zmieniać położenie w zależności od platformy. Oznacza to, że obraz tła z gradientem liniowym musi być dynamicznie dostosowywany, aby przebiegał od #131313maroon lub maroon#131313maroon, tak aby pasował do koloru tła maroon paska tytułu, który jest określany przez <meta name="theme-color" content="maroon">. Możesz to zrobić, wysyłając zapytanie do interfejsu getTitlebarAreaRect() API dotyczące 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');
}

W zmodyfikowanym kodzie obraz tła nie jest już umieszczony bezpośrednio w regułach CSS klasy .search (jak wcześniej), ale są używane 2 klasy, które kod powyżej 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);
}

Określanie, czy nakładka z elementami sterującymi okna jest widoczna

Nakładka z elementami sterującymi okna nie będzie widoczna w obszarze paska tytułu we wszystkich okolicznościach. Oczywiście nie będzie go w przeglądarkach, które nie obsługują funkcji nakładki elementów sterujących okna, ani wtedy, gdy dana aplikacja PWA jest uruchomiona na karcie. Aby wykryć taką sytuację, możesz wysłać zapytanie do usługi visiblewindowControlsOverlay:

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 JavaScript i/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. */ 
}

Otrzymywanie powiadomień o zmianach geometrii

W przypadku jednorazowych czynności, takich jak ustawienie odpowiedniego obrazu tła w zależności od położenia elementów sterujących okna, wystarczy zapytanie o obszar nakładki z elementami sterującymi okna za pomocą getTitlebarAreaRect(), ale w innych przypadkach konieczna jest bardziej precyzyjna kontrola. Na przykład możesz dostosować nakładkę z elementami sterującymi okna do dostępnego miejsca i dodać żart bezpośrednio do nakładki, gdy jest wystarczająco dużo miejsca.

Obszar nakładki z elementami sterującymi okna na wąskim oknie ze skróconym tekstem.
Elementy sterujące paska tytułu dostosowane do wąskiego okna.

O zmianach geometrii możesz otrzymywać powiadomienia, subskrybując navigator.windowControlsOverlay.ongeometrychange lub konfigurując odbiornik zdarzeń dla zdarzenia geometrychange. To zdarzenie zostanie wywołane tylko wtedy, gdy widoczna jest nakładka elementów sterujących okna, 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ć do windowControlsOverlay odbiornik zdarzeń, jak poniżej. Różnice między nimi znajdziesz w MDN.

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

Zgodność podczas działania w karcie i w przeglądarkach, które nie obsługują tej funkcji

Możesz rozważyć 2 możliwe przypadki:

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

W obu przypadkach domyślnie kod HTML utworzony na potrzeby nakładki elementów sterujących okna będzie wyświetlany w wierszu, tak jak zwykła treść HTML, a w przypadku pozycjonowania zostaną użyte env() wartości rezerwowe zmiennychenv(). W obsługiwanych przeglądarkach możesz też zdecydować, aby nie wyświetlać kodu HTML przeznaczonego dla nakładki elementów sterujących oknem. Wystarczy, że sprawdzisz właściwość visible nakładki. Jeśli zwraca ona wartość false, ukryj tę zawartość HTML.

Aplikacja PWA działająca na karcie przeglądarki z elementami sterującymi oknem wyświetlanymi w treści.
Elementy sterujące przeznaczone dla paska tytułu można łatwo wyświetlać w treści na starszych przeglądarkach.

Przypominamy, że przeglądarki, które nie obsługują właściwości pliku manifestu aplikacji internetowej "display_override", w ogóle jej nie uwzględniają lub nie rozpoznają "window-controls-overlay", a tym samym używają następnej możliwej wartości zgodnie z łańcuchem rezerwowym, np. "standalone".

Aplikacja PWA działająca w trybie autonomicznym z nakładką elementów sterujących oknem wyświetlaną w treści.
Elementy sterujące przeznaczone dla paska tytułu można łatwo wyświetlać w treści na starszych przeglądarkach.

Wskazówki dotyczące interfejsu

Tworzenie klasycznego menu w obszarze nakładki elementów sterujących oknem może być kuszące, ale nie jest zalecane. Byłoby to sprzeczne z wytycznymi dotyczącymi projektowania w systemie macOS, w którym użytkownicy oczekują, że paski menu (zarówno te dostarczane przez system, jak i niestandardowe) będą znajdować się u góry ekranu.

Jeśli aplikacja działa w trybie pełnoekranowym, zastanów się, czy nakładka elementów sterujących oknem powinna być częścią widoku pełnoekranowego. Gdy zostanie uruchomione zdarzenie onfullscreenchange, możesz zmienić układ.

Prezentacja

Stworzyłem wersję demonstracyjną, w którą możesz zagrać w różnych obsługiwanych i nieobsługiwanych przeglądarkach, a także w wersji zainstalowanej i niezainstalowanej. Aby zobaczyć, jak działa nakładka sterowania oknem, musisz zainstalować aplikację. Poniżej znajdziesz 2 zrzuty ekranu, które pokazują, czego możesz się spodziewać. Kod źródłowy aplikacji jest dostępny w Glitchu.

Aplikacja demonstracyjna Wikimedia Featured Content z nakładką z elementami sterującymi okna.
Aplikacja w wersji demonstracyjnej jest dostępna do eksperymentowania.

Funkcja wyszukiwania w nakładce z elementami sterującymi okna działa w pełni:

Aplikacja demonstracyjna Wikimedia Featured Content z nakładką sterowania oknem i aktywnym wyszukiwaniem terminu „cleopa…”, która wyróżnia jeden z artykułów z pasującym terminem „Kleopatra”.
Funkcja wyszukiwania korzystająca z nakładki z elementami sterującymi okna.

Bezpieczeństwo

Zespół Chromium zaprojektował i wdrożył interfejs Window Controls Overlay API zgodnie z podstawowymi zasadami określonymi w dokumencie Controlling Access to Powerful Web Platform Features, w tym z zasadami dotyczącymi kontroli użytkownika, przejrzystości i ergonomii.

Podszywanie się

Przyznanie stronom częściowej kontroli nad paskiem tytułu pozostawia deweloperom możliwość fałszowania treści w obszarze, który wcześniej był zaufany i kontrolowany przez przeglądarkę. Obecnie w przeglądarkach Chromium tryb autonomiczny zawiera pasek tytułu, który przy pierwszym uruchomieniu wyświetla tytuł strony internetowej po lewej stronie, a po prawej – źródło strony (po którym następuje przycisk „Ustawienia i inne” oraz elementy sterujące oknem). Po kilku sekundach tekst źródłowy zniknie. Jeśli przeglądarka jest ustawiona na język zapisywany od prawej do lewej, ten układ jest odwrócony, tak aby tekst źródłowy znajdował się po lewej stronie. Otworzy się nakładka z elementami sterującymi oknem, która umożliwia podszywanie się pod źródło, jeśli między źródłem a prawą krawędzią nakładki nie ma wystarczającego odstępu. Na przykład do punktu początkowego „evil.ltd” można dodać zaufaną witrynę „google.com”, co może sprawić, że użytkownicy uznają źródło za wiarygodne. Planujemy zachować ten tekst, aby użytkownicy wiedzieli, skąd pochodzi aplikacja, i mogli się upewnić, że spełnia ona ich oczekiwania. W przypadku przeglądarek skonfigurowanych do wyświetlania tekstu od prawej do lewej musi być wystarczająco dużo miejsca po prawej stronie tekstu źródłowego, aby złośliwa witryna nie mogła dołączyć do niebezpiecznego źródła zaufanego źródła.

Odciski cyfrowe

Włączenie nakładki z elementami sterującymi okna i obszarów, które można przeciągać, nie wiąże się z poważnymi problemami dotyczącymi prywatności, poza wykrywaniem funkcji. Jednak ze względu na różne rozmiary i położenia przycisków sterujących oknem w różnych systemach operacyjnych metoda navigator.windowControlsOverlay.getTitlebarAreaRect() zwraca obiekt DOMRect, którego położenie i wymiary ujawniają informacje o systemie operacyjnym, w którym działa przeglądarka. Obecnie deweloperzy mogą już wykrywać system operacyjny na podstawie ciągu znaków agenta użytkownika, ale ze względu na obawy dotyczące fingerprintingu toczą się dyskusje na temat zamrożenia ciągu znaków agenta użytkownika i ujednolicenia wersji systemu operacyjnego. W społeczności przeglądarek trwają prace nad ustaleniem, jak często zmienia się rozmiar nakładki elementów sterujących oknem na różnych platformach. Obecnie zakłada się, że jest on dość stabilny w różnych wersjach systemu operacyjnego, a więc nie byłby przydatny do obserwowania drobnych wersji systemu operacyjnego. Chociaż jest to potencjalny problem z odciskiem cyfrowym, dotyczy on tylko zainstalowanych progresywnych aplikacji internetowych, które korzystają z funkcji niestandardowego paska tytułu, a nie ogólnego korzystania z przeglądarki. Dodatkowo interfejs API navigator.windowControlsOverlay nie będzie dostępny w przypadku elementów iframe osadzonych w aplikacji PWA.

Przejście do innej domeny w aplikacji PWA spowoduje powrót do normalnego paska tytułu w trybie samodzielnym, nawet jeśli spełnia ona powyższe kryteria i została uruchomiona z nakładką z elementami sterującymi okna. Ma to na celu uwzględnienie czarnego paska, który pojawia się podczas przechodzenia do innej domeny. Po powrocie do pierwotnego źródła ponownie będzie używana nakładka elementów sterujących okna.

Czarny pasek adresu URL w przypadku nawigacji poza domeną.
Gdy użytkownik przechodzi do innej domeny, wyświetla się czarny pasek.

Prześlij opinię

Zespół Chromium chce poznać Twoje wrażenia związane z korzystaniem z interfejsu Window Controls Overlay API.

Opisz projekt interfejsu API

Czy w API jest coś, co nie działa tak, jak oczekujesz? Czy brakuje metod lub właściwości, które są potrzebne do realizacji Twojego pomysłu? Masz pytania lub uwagi dotyczące modelu zabezpieczeń? Zgłoś problem ze specyfikacją w odpowiednim repozytorium GitHub lub dodaj swoje uwagi do istniejącego problemu.

Zgłaszanie problemu z implementacją

Czy udało Ci się znaleźć błąd w implementacji Chromium? A może implementacja różni się od specyfikacji? Zgłoś błąd na stronie new.crbug.com. Podaj jak najwięcej szczegółów, proste instrukcje odtwarzania i wpisz UI>Browser>WebAppInstalls w polu Komponenty.

Wyrażanie poparcia dla interfejsu API

Czy zamierzasz używać interfejsu Window Controls Overlay API? Twoje publiczne wsparcie pomaga zespołowi Chromium w określaniu priorytetów dotyczących funkcji i pokazuje innym dostawcom przeglądarek, jak ważne jest ich obsługiwanie.

Wyślij tweeta do @ChromiumDev z hashtagiem #WindowControlsOverlay i napisz, gdzie i jak korzystasz z tej funkcji.

Przydatne linki

Podziękowania

Nakładka z elementami sterującymi okna została wdrożona i określona przez Amandę Baker z zespołu Microsoft Edge. Ten artykuł został sprawdzony przez Joego MedleyaKennetha Rohde Christiansena. Baner powitalny: Sigmund, Unsplash.