Menyesuaikan overlay kontrol jendela pada kolom judul PWA Anda

Gunakan area panel judul di samping kontrol jendela untuk membuat PWA Anda terasa lebih seperti aplikasi.

Jika Anda ingat artikel saya yang Membuat PWA Anda terasa lebih seperti sebuah aplikasi, Anda mungkin ingat bagaimana saya menyebutkan menyesuaikan bilah judul aplikasi sebagai strategi untuk menciptakan pengalaman yang lebih mirip aplikasi. Berikut adalah contoh tampilan menampilkan aplikasi Podcast macOS.

Kolom judul aplikasi macOS Podcast yang menampilkan tombol kontrol media dan metadata tentang podcast yang sedang diputar.
Panel judul kustom membuat PWA Anda terasa lebih seperti aplikasi khusus platform.

Sekarang Anda mungkin tergoda untuk keberatan dengan mengatakan bahwa Podcast adalah aplikasi macOS khusus platform yang melakukan tidak berjalan di browser dan karenanya dapat melakukan apa yang diinginkannya tanpa harus menjalankan aturan. Benar, tetapi kabar baiknya adalah fitur Overlay Kontrol Jendela, yang merupakan topik dalam artikel ini, Anda akan segera dapat membuat antarmuka pengguna yang serupa untuk PWA.

Komponen Overlay Kontrol Jendela

Overlay Kontrol Jendela terdiri dari empat sub-fitur:

  1. Nilai "window-controls-overlay" untuk kolom "display_override" di manifes aplikasi web.
  2. Variabel lingkungan CSS titlebar-area-x, titlebar-area-y, titlebar-area-width, dan titlebar-area-height.
  3. Standardisasi properti CSS yang sebelumnya eksklusif, -webkit-app-region sebagai app-region untuk menentukan area yang dapat ditarik di konten web.
  4. Mekanisme untuk melakukan kueri dan mengatasi region kontrol jendela melalui windowControlsOverlay anggota dari window.navigator.

Apa itu Overlay Kontrol Jendela

Area bilah judul mengacu pada ruang di sebelah kiri atau kanan kontrol jendela (yaitu, untuk meminimalkan, membesarkan, menutup, dll.) dan sering kali berisi judul aplikasi. Jendela Overlay Kontrol memungkinkan aplikasi web progresif (PWA) memberikan nuansa yang lebih mirip aplikasi dengan menukar bilah judul lebar penuh yang ada untuk overlay kecil yang berisi kontrol jendela. Hal ini memungkinkan pengembang untuk menempatkan konten khusus di area yang sebelumnya dikontrol oleh browser.

Status saat ini

Langkah Status
1. Buat penjelasan Selesai
2. Membuat draf awal spesifikasi Selesai
3. Kumpulkan masukan & mengulangi desain Dalam proses
4. Uji coba origin Selesai
5. Peluncuran Selesai (di Chromium 104)

Cara menggunakan Overlay Kontrol Jendela

Menambahkan window-controls-overlay ke manifes aplikasi web

{i>Progressive web app<i} dapat memilih untuk menggunakan {i>overlay <i}kontrol jendela dengan menambahkan "window-controls-overlay" sebagai anggota "display_override" utama di manifes aplikasi web:

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

Overlay kontrol jendela hanya akan terlihat jika semua kondisi berikut terpenuhi:

  1. Aplikasi tidak dibuka di browser, tetapi di jendela PWA terpisah.
  2. Manifes menyertakan "display_override": ["window-controls-overlay"]. (Nilai lainnya adalah diizinkan setelahnya.)
  3. PWA berjalan di sistem operasi desktop.
  4. Asal saat ini cocok dengan origin tempat PWA diinstal.

Hasilnya adalah area bilah judul kosong dengan kontrol jendela reguler di sebelah kiri atau benar, tergantung pada sistem operasinya.

Jendela aplikasi dengan kolom judul kosong dengan kontrol jendela di sebelah kiri.
Panel judul kosong siap untuk konten kustom.

Memindahkan konten ke kolom judul

Setelah ada ruang di bilah judul, Anda dapat memindahkan sesuatu ke sana. Untuk artikel ini, saya membuat PWA Konten Unggulan Wikimedia. Fitur yang berguna untuk aplikasi ini mungkin adalah penelusuran kata dalam judul artikel. HTML untuk fitur penelusuran akan terlihat seperti ini:

<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>

Untuk memindahkan div ini ke atas kolom judul, diperlukan beberapa 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);
}

Anda dapat melihat efek kode ini di screenshot di bawah. Kolom judul sepenuhnya responsif. Kapan Anda mengubah ukuran jendela PWA, bilah judul bereaksi seolah-olah terdiri dari konten HTML biasa, dan pada kenyataannya, begitulah kenyataannya.

Jendela aplikasi dengan kotak penelusuran di kolom judul.
Kolom judul baru aktif dan responsif.

Menentukan bagian bilah judul yang dapat ditarik

Meskipun tangkapan layar di atas menunjukkan bahwa Anda sudah selesai, namun Anda belum selesai. Jendela PWA tidak lagi dapat ditarik (selain area yang sangat kecil), karena tombol kontrol jendela tidak ditarik area, dan bagian lain bilah judul terdiri dari widget penelusuran. Perbaiki menggunakan properti CSS app-region dengan nilai drag. Dalam kasus konkret, tidak masalah untuk membuat semua selain elemen input yang dapat ditarik.

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

Dengan CSS ini, pengguna dapat menarik jendela aplikasi seperti biasa dengan menarik div, img, atau label. Hanya elemen input yang interaktif sehingga kueri penelusuran dapat dimasukkan.

Deteksi fitur

Dukungan untuk Overlay Kontrol Jendela dapat dideteksi dengan menguji keberadaan windowControlsOverlay:

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

Membuat kueri region kontrol jendela dengan windowControlsOverlay

Kode sejauh ini memiliki satu masalah: pada beberapa platform, kontrol jendela berada di sebelah kanan, di yang lain mereka ada di sebelah kiri. Untuk memperburuk keadaan, "tiga titik" Menu Chrome akan berubah posisi juga berdasarkan platform. Artinya, gambar latar belakang gradien linier harus disesuaikan secara dinamis untuk dijalankan dari #131313maroon atau maroon#131313maroon, sehingga akan menyatu dengan warna latar belakang maroon bilah judul yang ditentukan oleh <meta name="theme-color" content="maroon">. Hal ini dapat dilakukan dengan membuat kueri data getTitlebarAreaRect() API di properti 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');
}

Daripada memiliki gambar latar dalam aturan CSS class .search secara langsung (seperti sebelumnya), kode yang dimodifikasi sekarang menggunakan dua class yang ditetapkan secara dinamis oleh kode di atas.

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

Menentukan apakah overlay kontrol jendela terlihat atau tidak

Overlay kontrol jendela tidak akan terlihat di area panel judul dalam semua situasi. Meskipun secara alami tidak akan ada di browser yang tidak mendukung fitur Overlay Kontrol Jendela, juga tidak akan ada saat PWA yang dimaksud berjalan di tab. Untuk mendeteksi situasi ini, Anda dapat buat kueri properti visible dari windowControlsOverlay:

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

Atau, Anda juga dapat menggunakan kueri media display-mode di JavaScript dan/atau 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. */ 
}

Mendapatkan notifikasi tentang perubahan geometri

Membuat kueri area overlay kontrol jendela dengan getTitlebarAreaRect() sudah cukup untuk satu kali hal-hal seperti mengatur gambar latar yang benar berdasarkan lokasi kontrol jendela, tetapi di dalam kasus lain, diperlukan kontrol yang lebih terperinci. Misalnya, kasus penggunaan yang mungkin terjadi adalah menyesuaikan overlay kontrol jendela berdasarkan ruang yang tersedia dan menambahkan lelucon langsung di jendela {i>overlay <i}pada saat ada cukup ruang.

Jendela kontrol area overlay pada jendela sempit dengan teks singkat.
Kontrol panel judul disesuaikan dengan jendela sempit.

Anda dapat diberi tahu tentang perubahan geometri dengan berlangganan navigator.windowControlsOverlay.ongeometrychange atau dengan menyiapkan pemroses peristiwa untuk Peristiwa geometrychange. Peristiwa ini hanya akan diaktifkan saat overlay kontrol jendela terlihat, yaitu adalah, jika navigator.windowControlsOverlay.visible adalah 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);
}

Daripada menetapkan fungsi ke ongeometrychange, Anda juga dapat menambahkan pemroses peristiwa ke windowControlsOverlay seperti di bawah ini. Anda dapat membaca tentang perbedaan antara keduanya di MDN.

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

Kompatibilitas saat berjalan di tab dan di browser yang tidak mendukung

Ada dua kemungkinan kasus yang perlu dipertimbangkan:

  • Kasus saat aplikasi berjalan di browser yang mendukung Overlay Kontrol Jendela, tetapi tempat aplikasi digunakan di tab browser.
  • Kasus saat aplikasi berjalan di browser yang tidak mendukung Overlay Kontrol Jendela.

Pada kedua kasus tersebut, secara default HTML yang dibuat untuk kontrol jendela overlay akan ditampilkan inline seperti konten HTML biasa dan variabel env() nilai penggantian akan memulai pemosisian. Pada browser pendukung, Anda juga dapat memutuskan untuk tidak menampilkan HTML yang ditetapkan untuk overlay kontrol jendela dengan memeriksa properti visible overlay, dan jika perintah itu melaporkan false, lalu menyembunyikan konten HTML tersebut.

PWA yang berjalan di tab browser dengan overlay kontrol jendela ditampilkan di dalam isi.
Kontrol yang dimaksudkan untuk bilah judul dapat dengan mudah ditampilkan dalam isi di browser lama.

Sebagai pengingat, browser yang tidak mendukung juga tidak akan mempertimbangkan "display_override" properti manifes aplikasi web, atau tidak mengenali "window-controls-overlay", sehingga menggunakan kemungkinan nilai berikutnya sesuai dengan rantai penggantian, misalnya "standalone".

PWA yang berjalan dalam mode mandiri dengan overlay kontrol jendela ditampilkan dalam isi.
Kontrol yang dimaksudkan untuk bilah judul dapat dengan mudah ditampilkan dalam isi di browser lama.

Pertimbangan UI

Meskipun Anda tergoda, membuat menu dropdown klasik di area Overlay Kontrol Jendela tidak disarankan. Melakukan hal tersebut akan melanggar pedoman desain terkait macOS, platform di mana pengguna mengharapkan bilah menu (baik yang disediakan sistem maupun yang khusus) di bagian atas layar.

Jika aplikasi Anda memberikan pengalaman layar penuh, pertimbangkan dengan cermat apakah itu masuk akal agar Overlay Kontrol Jendela menjadi bagian dari tampilan layar penuh. Kemungkinan Anda dapat ingin mengatur ulang tata letak Anda ketika onfullscreenchange jika terjadi kebakaran.

Demo

Saya telah membuat demo yang dapat Anda mainkan di browser yang mendukung dan tidak mendukung, serta dalam status terinstal dan tidak terinstal. Sebagai pengalaman Overlay Kontrol Jendela yang sebenarnya, Anda harus menginstal aplikasi. Anda akan melihat dua screenshot yang akan menampilkan hal tersebut di bawah. Tujuan kode sumber untuk aplikasi ini tersedia di Glitch.

Aplikasi demo Konten Unggulan Wikimedia dengan Overlay Kontrol Jendela.
Aplikasi demo tersedia untuk eksperimen.

Fitur penelusuran di overlay kontrol jendela berfungsi sepenuhnya:

Aplikasi demo Konten Unggulan Wikimedia dengan Overlay Kontrol Jendela dan penelusuran aktif untuk istilah &#39;cleopa...&#39; menyorot salah satu artikel dengan istilah yang cocok &#39;Cleopatra&#39;.
Fitur penelusuran menggunakan Overlay Kontrol Jendela.

Pertimbangan keamanan

Tim Chromium merancang dan menerapkan Window Controls Overlay API menggunakan prinsip inti didefinisikan dalam Mengontrol Akses ke Fitur Platform Web yang Canggih, termasuk informasi kontrol, transparansi, dan ergonomi.

{i>Spoofing<i}

Memberi situs kontrol sebagian pada kolom judul memberi ruang bagi developer untuk melakukan spoofing terhadap konten sebelumnya merupakan region tepercaya yang dikontrol browser. Saat ini, di browser Chromium, mandiri termasuk bilah judul yang saat peluncuran awal menampilkan judul laman web di sebelah kiri, dan asal halaman di sebelah kanan (diikuti dengan tombol "setelan dan lainnya" dan jendela Anda). Setelah beberapa detik, teks origin akan hilang. Jika browser disetel dari kanan-ke-kiri (RTL), tata letak ini dibalik sehingga teks asal berada di sebelah kiri. Tindakan ini akan membuka overlay kontrol jendela untuk memalsukan origin jika tidak ada padding yang cukup antara origin dan tepi kanan overlay. Misalnya, origin "evil.ltd" dapat dilengkapi dengan situs "google.com", membuat pengguna yakin bahwa sumber tersebut dapat dipercaya. Rencananya adalah untuk menjaga agar teks asal sehingga pengguna mengetahui asal aplikasi dan dapat memastikan bahwa aplikasi tersebut cocok ekspektasi perusahaan. Untuk browser yang dikonfigurasi RTL, harus ada cukup padding di sebelah kanan origin teks untuk mencegah situs berbahaya menambahkan origin yang tidak aman ke origin tepercaya.

Pelacakan sidik jari

Mengaktifkan overlay kontrol jendela dan area yang dapat ditarik tidak muncul masalah privasi yang cukup penting selain deteksi fitur. Namun, karena ukuran dan posisi yang berbeda dari tombol kontrol jendela di seluruh pengoperasian sistem-sistem, navigator.windowControlsOverlay.getTitlebarAreaRect() metode akan menampilkan DOMRect yang posisi dan dimensinya mengungkapkan informasi tentang sistem operasi setelah yang dijalankan browser. Saat ini, developer sudah dapat menemukan OS dari {i>string<i} agen pengguna, tetapi karena masalah sidik jari, ada diskusi tentang pembekuan string UA dan menyatukan versi OS. Terdapat upaya berkelanjutan dalam komunitas browser untuk memahami seberapa sering ukuran jendela mengontrol overlay yang berubah di seluruh platform, karena ukuran Asumsinya adalah bahwa ini cukup stabil di seluruh versi OS dan dengan demikian tidak akan untuk mengamati versi OS minor. Meskipun ini adalah potensi sidik jari, hanya berlaku untuk PWA terinstal yang menggunakan fitur bilah judul dan tidak berlaku untuk penggunaan {i>browser<i} umum. Selain itu, navigator.windowControlsOverlay API tidak akan tersedia untuk iframe yang disematkan di dalam PWA.

Membuka origin yang berbeda dalam PWA akan menyebabkannya kembali ke origin mandiri normal bilah judul, walaupun memenuhi kriteria di atas dan diluncurkan dengan overlay kontrol jendela. Hal ini untuk mengakomodasi bilah hitam yang muncul pada navigasi ke asal yang berbeda. Sesudah menavigasi kembali ke asal yang asli, overlay kontrol jendela akan digunakan lagi.

Kolom URL hitam untuk navigasi di luar asal.
Batang hitam ditampilkan saat pengguna membuka asal yang berbeda.

Masukan

Tim Chromium ingin mengetahui pengalaman Anda saat menggunakan Window Controls Overlay API.

Beri tahu kami tentang desain API

Apakah ada sesuatu tentang API yang tidak berfungsi seperti yang Anda harapkan? Atau apakah ada metode yang hilang yang dibutuhkan untuk menerapkan ide Anda? Memiliki pertanyaan atau komentar tentang keamanan model? Ajukan masalah spesifikasi di repo GitHub yang sesuai, atau tambahkan pendapat Anda ke masalah yang ada.

Laporkan masalah terkait penerapan

Apakah Anda menemukan bug pada implementasi Chromium? Atau apakah implementasinya berbeda dengan spesifikasi? Laporkan bug di new.crbug.com. Pastikan untuk menyertakan detail sebanyak mungkin, petunjuk sederhana untuk mereproduksi, dan masukkan UI>Browser>WebAppInstalls dalam Komponen . Glitch sangat cocok untuk membagikan repro dengan cepat dan mudah.

Menunjukkan dukungan untuk API

Anda berencana menggunakan Window Controls Overlay API? Dukungan publik Anda membantu tim Chromium untuk memprioritaskan fitur dan menunjukkan kepada vendor browser lain betapa pentingnya mendukung mereka.

Kirim Tweet ke @ChromiumDev dengan #WindowControlsOverlay tagar dan beri tahu kami tempat dan cara Anda menggunakannya.

Link bermanfaat

Ucapan terima kasih

Overlay Kontrol Jendela diterapkan dan ditentukan oleh Amanda Baker dari tim Microsoft Edge. Artikel ini ditinjau oleh Joe Medley dan Kenneth Rohde Christiansen. Banner besar oleh Sigmund di Unsplash.