Uji coba origin untuk elemen <permission> HTML baru

Ada sejumlah metode imperatif untuk meminta izin menggunakan fitur-fitur canggih seperti akses lokasi di aplikasi web. Metode ini memiliki sejumlah tantangan. Itulah sebabnya tim izin Chrome bereksperimen dengan metode deklaratif baru: elemen <permission> HTML khusus. Elemen ini masih dalam uji coba origin dari Chrome 126, dan pada akhirnya kami berharap dapat menstandarkannya.

Metode penting untuk meminta izin

Saat memerlukan akses ke fitur yang canggih, aplikasi web harus meminta izin. Misalnya, jika Google Maps memerlukan lokasi pengguna menggunakan Geolocation API, browser akan meminta pengguna, sering kali dengan opsi untuk menyimpan keputusan tersebut. Ini adalah konsep yang didefinisikan dengan baik dalam spesifikasi Izin.

Tanyakan secara implisit pada penggunaan pertama versus permintaan secara eksplisit di awal

Geolocation API adalah API yang andal dan mengandalkan pertanyaan implisit pada pendekatan penggunaan pertama. Misalnya, saat aplikasi memanggil metode navigator.geolocation.getCurrentPosition(), dialog izin akan otomatis muncul pada panggilan pertama. Contoh lainnya adalah navigator.mediaDevices.getUserMedia().

API lain, seperti Notification API atau Device Orientation dan Motion API, biasanya memiliki cara eksplisit untuk meminta izin melalui metode statis seperti Notification.requestPermission() atau DeviceMotionEvent.requestPermission().

Tantangan dengan metode penting untuk meminta izin

Spam izin

Sebelumnya, situs dapat memanggil metode seperti navigator.mediaDevices.getUserMedia() atau Notification.requestPermission(), tetapi juga navigator.geolocation.getCurrentPosition() segera saat situs dimuat. Permintaan izin akan muncul sebelum pengguna berinteraksi dengan situs. Hal ini terkadang dijelaskan sebagai spam izin dan memengaruhi kedua pendekatan, secara implisit meminta penggunaan pertama serta permintaan secara eksplisit di awal.

Dialog izin mikrofon ditampilkan saat memuat situs.

Mitigasi browser dan persyaratan gestur pengguna

Spam izin menyebabkan vendor browser memerlukan gestur pengguna seperti klik tombol atau peristiwa keydown sebelum menampilkan dialog izin. Masalah dengan pendekatan ini adalah sangat sulit, atau bahkan tidak mungkin, bagi browser untuk mengetahui apakah gestur pengguna tertentu harus menghasilkan dialog izin ditampilkan atau tidak. Mungkin pengguna hanya mengklik halaman karena merasa frustrasi karena halaman membutuhkan waktu lama untuk dimuat, atau mungkin mereka memang mengklik tombol Temukan saya. Beberapa {i>website<i} juga sangat mahir dalam mengelabui pengguna agar mengklik konten untuk memicu dialog.

Mitigasi lainnya adalah menambahkan mitigasi penyalahgunaan prompt, seperti sepenuhnya memblokir fitur untuk memulai, atau menampilkan prompt izin dengan cara yang tidak mengganggu dan tidak terlalu mengganggu.

Browser Chrome menampilkan

Kontekstualisasi izin

Tantangan lainnya, terutama di layar TV, adalah cara permintaan izin ditampilkan secara umum: di atas garis kematian, yaitu di luar area jendela browser tempat aplikasi dapat menggambar. Tidak jarang pengguna akan melewatkan dialog di bagian atas jendela browser saat mereka mengklik tombol di bagian bawah jendela. Masalah ini sering diperburuk ketika mitigasi spam browser diterapkan.

Google Maps dengan dialog izin akses lokasi terbuka. Tombol akses lokasi yang memicu dialog terlalu jauh.

Tidak mudah untuk mengurungkan

Terakhir, terlalu mudah bagi pengguna untuk mengarahkan diri mereka ke jalan buntu. Misalnya, setelah pengguna memblokir akses ke fitur, mereka harus mengetahui menu drop-down informasi situs tempat mereka dapat Mereset izin atau mengaktifkan kembali izin yang diblokir. Dalam kasus terburuk, kedua opsi tersebut mengharuskan halaman dimuat ulang secara penuh hingga setelan yang diperbarui diterapkan. Situs tidak memiliki kemampuan untuk menyediakan pintasan mudah bagi pengguna untuk mengubah status izin yang ada dan harus dengan susah payah menjelaskan kepada pengguna cara mengubah setelan seperti yang ditunjukkan di bagian bawah screenshot Google Maps berikut.

Kontrol situs Chrome di Google Maps untuk mencabut izin.

Jika izin adalah kunci untuk pengalaman, misalnya, akses mikrofon untuk aplikasi konferensi video, aplikasi seperti Google Meet akan menampilkan dialog mengganggu yang memberi tahu pengguna cara berhenti memblokir izin.

Petunjuk Google Meet tentang cara membuka kontrol situs Chrome.

Elemen <permission> deklaratif

Untuk mengatasi tantangan yang dijelaskan dalam postingan ini, tim izin Chrome telah meluncurkan uji coba origin untuk elemen HTML baru, <permission>. Elemen ini memungkinkan developer meminta izin secara deklaratif untuk menggunakan, untuk saat ini, sebagian dari fitur canggih yang tersedia untuk situs. Dalam bentuk yang paling sederhana, Anda menggunakannya seperti dalam contoh berikut:

<permission type="camera" />

Masih aktif diperdebatkan apakah <permission> harus merupakan elemen void atau tidak. Elemen kosong adalah elemen yang menutup sendiri pada HTML yang tidak dapat memiliki node turunan, yang dalam HTML berarti elemen tersebut mungkin tidak memiliki tag akhir.

Atribut type

Atribut type berisi daftar izin yang Anda minta yang dipisahkan spasi. Pada saat penulisan ini, nilai yang diizinkan adalah 'camera', 'microphone', dan camera microphone (dipisahkan dengan spasi). Elemen ini secara default dirender mirip dengan tombol yang memiliki gaya visual agen pengguna barebone.

Berbagai tombol elemen izin dengan izin kamera, mikrofon, dan kamera plus mikrofon.

Atribut type-ext

Untuk beberapa izin yang mengizinkan parameter tambahan, atribut type-ext menerima key-value pair yang dipisahkan spasi, seperti, misalnya, precise:true untuk izin geolokasi.

Atribut lang

Teks tombol disediakan oleh browser dan dimaksudkan agar konsisten, sehingga tidak dapat disesuaikan secara langsung. Browser mengubah bahasa teks berdasarkan bahasa yang diwarisi dari dokumen atau rantai elemen induk, atau atribut lang opsional. Artinya, developer tidak perlu melokalkan elemen <permission> sendiri. Jika elemen <permission> berlanjut di luar tahap uji coba origin, beberapa string atau ikon mungkin didukung untuk setiap jenis izin guna meningkatkan fleksibilitas. Jika Anda tertarik menggunakan elemen <permission> dan memerlukan string atau ikon tertentu, hubungi kami.

Perilaku

Saat pengguna berinteraksi dengan elemen <permission>, mereka dapat melewati berbagai tahapan:

  • Jika mereka tidak mengizinkan fitur sebelumnya, mereka dapat mengizinkannya pada setiap kunjungan, atau mengizinkannya untuk kunjungan saat ini.

    Dialog izin untuk mengizinkan fitur kali ini atau pada setiap kunjungan.

  • Jika mereka telah mengizinkan fitur sebelumnya, mereka dapat terus mengizinkannya, atau berhenti mengizinkannya.

    Perintah izin untuk terus mengizinkan atau menghentikan pemberian izin.

  • Jika sebelumnya tidak mengizinkan fitur, mereka dapat tetap tidak mengizinkannya, atau mengizinkannya kali ini.

    Permintaan izin untuk terus tidak mengizinkan atau mengizinkan kali ini.

Teks elemen <permission> otomatis diperbarui berdasarkan status. Misalnya, jika izin diberikan untuk menggunakan suatu fitur, teks akan berubah untuk menyatakan bahwa fitur tersebut diizinkan. Jika izin perlu diberikan terlebih dahulu, teks akan berubah untuk mengundang pengguna menggunakan fitur tersebut. Bandingkan screenshot sebelumnya dengan screenshot berikut untuk melihat kedua status tersebut.

Tombol izin dengan teks

Desain CSS

Untuk memastikan pengguna dapat dengan mudah mengenali tombol sebagai platform untuk mengakses kemampuan yang canggih, gaya visual elemen <permission> dibatasi. Jika pembatasan gaya visual tidak sesuai untuk kasus penggunaan Anda, kami ingin mendengar bagaimana dan mengapa! Meskipun tidak semua kebutuhan gaya visual dapat diakomodasi, kami berharap menemukan cara yang aman untuk memungkinkan lebih banyak penataan gaya elemen <permission> setelah uji coba origin. Tabel berikut menjelaskan beberapa properti yang memiliki batasan atau aturan khusus yang diterapkan padanya. Jika ada aturan yang dilanggar, elemen <permission> akan dinonaktifkan dan tidak dapat berinteraksi dengannya. Setiap upaya untuk berinteraksi dengannya akan menghasilkan pengecualian yang dapat ditangkap dengan JavaScript. Pesan error akan berisi detail selengkapnya tentang pelanggaran yang terdeteksi.

Properti Aturan

color, background-color

Dapat digunakan untuk menyetel warna teks dan latar belakang. Kontras antara kedua warna harus memadai untuk teks yang dapat dibaca dengan jelas (rasio kontras minimal 3). Saluran alfa harus 1.

font-size, zoom

Harus ditetapkan dalam nilai yang setara dengan small dan xxxlarge. Jika tidak, elemen akan dinonaktifkan. Zoom akan diperhitungkan saat menghitung font-size.

outline-offset

Nilai negatif akan dikoreksi menjadi 0.
margin (semua) Nilai negatif akan dikoreksi menjadi 0.

font-weight

Nilai di bawah 200 akan diperbaiki menjadi 200.

font-style

Nilai selain normal dan italic akan dikoreksi menjadi normal.

word-spacing

Nilai di atas 0.5em akan dikoreksi menjadi 0.5em. Nilai di bagian 0 akan diperbaiki menjadi 0.

display

Nilai selain inline-block dan none akan dikoreksi menjadi inline-block.

letter-spacing

Nilai di atas 0.2em akan dikoreksi menjadi 0.2em. Nilai di bagian -0.05em akan dikoreksi menjadi -0.05em.

min-height

Akan memiliki nilai default 1em. Jika disediakan, nilai komputasi maksimum antara nilai default dan nilai yang diberikan akan dipertimbangkan.

max-height

Akan memiliki nilai default 3em. Jika disediakan, nilai minimum yang dihitung antara nilai default dan nilai yang diberikan akan dipertimbangkan.

min-width

Akan memiliki nilai default fit-content. Jika disediakan, nilai komputasi maksimum antara nilai default dan nilai yang diberikan akan dipertimbangkan.

max-width

Akan memiliki nilai default tiga kali fit-content. Jika diberikan, nilai komputasi minimum antara nilai default dan nilai yang diberikan akan dipertimbangkan.

padding-top

Hanya akan berlaku jika height ditetapkan ke auto. Dalam hal ini, nilai di atas 1em akan dikoreksi menjadi 1em dan padding-bottom akan ditetapkan ke nilai padding-top.

padding-left

Hanya akan berlaku jika width ditetapkan ke auto. Dalam hal ini, nilai di atas 5em akan dikoreksi menjadi 5em dan padding-right akan ditetapkan ke nilai padding-left.

transform

Efek visual yang mendistorsi tidak diizinkan. Untuk saat ini, kami hanya menerima terjemahan 2D dan peningkatan skala proporsional.

Properti CSS berikut dapat digunakan seperti biasa:

  • font-kerning
  • font-optical-sizing
  • font-stretch
  • font-synthesis-weight
  • font-synthesis-style
  • font-synthesis-small-caps
  • font-feature-settings
  • forced-color-adjust
  • text-rendering
  • align-self
  • anchor-name aspect-ratio
  • border (dan semua properti border-*)
  • clear
  • color-scheme
  • contain
  • contain-intrinsic-width
  • contain-intrinsic-height
  • container-name
  • container-type
  • counter-*
  • flex-*
  • float
  • height
  • isolation
  • justify-self
  • left
  • order
  • orphans
  • outline-* (dengan pengecualian yang disebutkan sebelumnya untuk outline-offset)
  • overflow-anchor
  • overscroll-behavior-*
  • page
  • position
  • position-anchor
  • content-visibility
  • right
  • scroll-margin-*
  • scroll-padding-*
  • text-spacing-trim
  • top
  • visibility
  • x
  • y
  • ruby-position
  • user-select
  • width
  • will-change
  • z-index

Selain itu, semua properti yang setara secara logis dapat digunakan (misalnya, inline-size setara dengan width), mengikuti aturan yang sama dengan padanannya.

Class Pseudo

Ada dua class semu khusus yang memungkinkan penataan gaya elemen <permission> berdasarkan status:

  • :granted: Class semu :granted memungkinkan gaya visual khusus saat izin diberikan.
  • :invalid: Class semu :invalid memungkinkan gaya visual khusus saat elemen berada dalam status tidak valid, misalnya, saat ditayangkan dalam iframe lintas origin.
permission {
  background-color: green;
}

permission:granted {
  background-color: light-green;
}

/* Not supported during the origin trial. */
permission:invalid {
  background-color: gray;
}

Peristiwa JavaScript

Elemen <permission> dimaksudkan untuk digunakan bersama dengan Permissions API. Ada sejumlah peristiwa yang dapat diproses:

  • onpromptdismiss: Peristiwa ini diaktifkan saat dialog izin yang dipicu oleh elemen telah ditutup oleh pengguna (misalnya, dengan mengklik tombol tutup atau mengklik di luar perintah).

  • onpromptaction: Peristiwa ini diaktifkan saat dialog izin yang dipicu oleh elemen telah diselesaikan oleh pengguna yang melakukan beberapa tindakan atas perintah itu sendiri. Hal ini tidak berarti status izin telah berubah, tetapi pengguna mungkin telah mengambil tindakan yang mempertahankan status quo (seperti melanjutkan memberikan izin).

  • onvalidationstatuschange: Peristiwa ini diaktifkan saat elemen beralih dari "valid" menjadi "invalid". Elemen ini dianggap "valid" jika browser memercayai integritas sinyal jika pengguna mengkliknya, dan "invalid" jika tidak, misalnya, saat elemen dihalangi sebagian oleh konten HTML lainnya.

Anda dapat mendaftarkan pemroses peristiwa untuk peristiwa ini secara langsung secara inline dalam kode HTML (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />), atau menggunakan addEventListener() pada elemen <permission>, seperti ditunjukkan dalam contoh berikut.

<permission type="camera" />
<script>
  const permission = document.querySelector('permission');
  permission.addEventListener('promptdismiss', showCameraWarning);

  function showCameraWarning() {
    // Show warning that the app isn't fully usable
    // unless the camera permission is granted.
  }

  const permissionStatus = await navigator.permissions.query({name: "camera"});
  
  permissionStatus.addEventListener('change', () => {
    // Run the check when the status changes.
    if (permissionStatus.state === "granted") {
      useCamera();
    }
  });

  // Run the initial check.
  if (permissionStatus.state === "granted") {
    useCamera();
  }
</script>

Deteksi fitur

Jika browser tidak mendukung elemen HTML, browser tidak akan menampilkannya. Artinya, jika Anda memiliki elemen <permission> di kode HTML, tidak akan ada yang terjadi jika browser tidak mengetahuinya. Anda mungkin masih ingin mendeteksi dukungan menggunakan JavaScript, misalnya, untuk membuat dialog izin yang dipicu melalui klik <button> reguler.

if ('HTMLPermissionElement' in window) {
  // The `<permission>` element is supported.
}

Uji coba origin

Untuk mencoba elemen <permission> di situs Anda dengan pengguna sungguhan, daftar ke uji coba origin. Baca Memulai uji coba origin untuk mengetahui petunjuk cara menyiapkan situs Anda untuk menggunakan uji coba origin. Uji coba origin akan berjalan dari Chrome 126 hingga 131 (19 Februari 2025).

Demo

Jelajahi demo dan lihat kode sumber di GitHub. Berikut screenshot pengalaman di browser pendukung.

Demo elemen izin yang menampilkan tiga tombol izin.

Masukan

Kami ingin mendengar pendapat Anda tentang cara kerja <permission> untuk kasus penggunaan Anda. Jangan ragu untuk menanggapi salah satu Masalah dalam repositori, atau mengajukan masalah baru. Sinyal publik dalam repo untuk elemen <permission> akan memberi tahu kami dan browser lain bahwa Anda berminat dengan elemen tersebut.

FAQ

  • Bagaimana cara ini lebih baik daripada <button> biasa yang disambungkan dengan Permissions API? Klik <button> adalah gestur pengguna, tetapi browser tidak memiliki cara untuk memverifikasi bahwa klik tersebut terhubung ke permintaan untuk meminta izin. Jika pengguna telah mengklik <permission>, browser dapat memastikan bahwa klik tersebut terkait dengan permintaan izin. Hal ini memungkinkan browser memfasilitasi alur yang jika tidak dilakukan akan jauh lebih berisiko. Misalnya, memungkinkan pengguna untuk dengan mudah mengurungkan pemblokiran izin.
  • Bagaimana jika browser lain tidak mendukung elemen <permission>? Elemen <permission> dapat digunakan sebagai progressive enhancement. Pada browser yang tidak mendukung, alur izin klasik dapat digunakan. Misalnya, berdasarkan klik <button> reguler. Tim izin juga sedang mengerjakan polyfill. Bintangi repositori GitHub untuk diberi tahu jika sudah siap.
  • Apakah hal ini telah dibahas dengan vendor browser lain? Elemen <permission> dibahas secara aktif di W3C TPAC pada tahun 2023 dalam sesi grup. Anda dapat membaca catatan sesi publik. Tim Chrome juga meminta Posisi Standar formal dari kedua vendor, lihat bagian Link terkait. Elemen <permission> adalah topik diskusi berkelanjutan dengan browser lain dan kami berharap dapat membakukannya.
  • Haruskah ini benar-benar merupakan elemen void? Masih diperdebatkansecara aktif apakah <permission> harus merupakan elemen void atau tidak. Jika Anda memiliki masukan, sampaikan Masalah ini.

Ucapan terima kasih

Dokumen ini ditinjau oleh Balázs Engedy, Thomas Nguyen, Penelope McLachlan, Marian Harbach, David Warren, dan Rachel Andrew.