Uji coba origin untuk elemen <permission> HTML baru

Ada sejumlah metode imperatif untuk meminta izin guna menggunakan 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 sedang dalam uji coba origin dari Chrome 126, dan pada akhirnya kami berharap dapat menstandarkannya.

Metode imperatif untuk meminta izin

Jika memerlukan akses ke fitur canggih, aplikasi web harus meminta izin. Misalnya, saat 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 efektif dan mengandalkan pendekatan tanya secara implisit pada penggunaan pertama. Misalnya, saat aplikasi memanggil metode navigator.geolocation.getCurrentPosition(), perintah izin akan otomatis muncul setelah panggilan pertama. Contoh lainnya adalah navigator.mediaDevices.getUserMedia().

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

Tantangan dengan metode imperatif untuk meminta izin

Spam izin

Sebelumnya, situs dapat memanggil metode seperti navigator.mediaDevices.getUserMedia() atau Notification.requestPermission(), tetapi juga navigator.geolocation.getCurrentPosition() langsung 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 mewajibkan gestur pengguna seperti klik tombol atau peristiwa keydown sebelum menampilkan perintah 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 tersebut membutuhkan waktu lama untuk dimuat, atau mungkin mereka memang mengklik tombol Temukan saya. Beberapa situs juga menjadi sangat mahir menipu pengguna agar mengklik konten untuk memicu perintah.

Mitigasi lainnya adalah menambahkan mitigasi penyalahgunaan perintah, seperti memblokir fitur sepenuhnya untuk memulai, atau menampilkan perintah izin dengan cara yang tidak intrusif dan non-modal.

Browser Chrome menampilkan

Kontekstualisasi izin

Tantangan lainnya, terutama di perangkat layar besar, adalah cara perintah izin biasanya ditampilkan: di atas garis kematian, yaitu di luar area jendela browser yang dapat digambar oleh aplikasi. Tidak jarang pengguna melewatkan perintah di bagian atas jendela browser mereka saat baru saja mengklik tombol di bagian bawah jendela. Masalah ini sering diperburuk saat mitigasi spam browser diterapkan.

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

Tidak mudah untuk mengurungkan

Terakhir, pengguna terlalu mudah tersesat. 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 memerlukan pemuatan ulang halaman sepenuhnya hingga setelan yang diperbarui diterapkan. Situs tidak dapat memberikan pintasan mudah bagi pengguna untuk mengubah status izin yang ada dan harus menjelaskan dengan cermat kepada pengguna cara mengubah setelan mereka seperti yang ditunjukkan di bagian bawah screenshot Google Maps berikut.

Kontrol situs Chrome di Google Maps untuk mencabut izin.

Jika izin tersebut merupakan kunci pengalaman, misalnya, akses mikrofon untuk aplikasi konferensi video, aplikasi seperti Google Meet akan menampilkan dialog yang 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 secara deklaratif meminta izin untuk menggunakan, untuk saat ini, subkumpulan fitur canggih yang tersedia untuk situs. Dalam bentuk yang paling sederhana, Anda menggunakannya seperti dalam contoh berikut:

<permission type="camera" />

Masih diperdebatkan secara aktif apakah <permission> harus berupa elemen void atau tidak. Elemen void adalah elemen penutup mandiri di 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 dipisahkan spasi yang Anda minta. Pada saat penulisan ini, nilai yang diizinkan adalah 'camera', 'microphone', dan camera microphone (dipisahkan oleh spasi). Elemen ini secara default dirender seperti tombol dengan gaya visual agen pengguna yang sederhana.

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

Atribut type-ext

Untuk beberapa izin yang memungkinkan parameter tambahan, atribut type-ext menerima pasangan nilai kunci yang dipisahkan spasi, seperti, misalnya, precise:true untuk izin geolokasi.

Atribut lang

Teks tombol disediakan oleh browser dan dimaksudkan untuk 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 setelah tahap uji coba origin, beberapa string atau ikon dapat didukung untuk setiap jenis izin guna meningkatkan fleksibilitas. Jika Anda tertarik untuk menggunakan elemen <permission> dan memerlukan string atau ikon tertentu, hubungi kami.

Perilaku

Saat pengguna berinteraksi dengan elemen <permission>, mereka dapat beralih melalui berbagai tahap:

  • Jika belum mengizinkan fitur sebelumnya, pengguna dapat mengizinkannya di setiap kunjungan, atau mengizinkannya untuk kunjungan saat ini.

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

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

    Permintaan izin untuk terus mengizinkan atau berhenti mengizinkan.

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

    Permintaan izin untuk tetap 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 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 salah satu aturan dilanggar, elemen <permission> akan dinonaktifkan dan tidak dapat berinteraksi. 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 jelas terbaca (rasio kontras minimal 3). Saluran alfa harus bernilai 1.

font-size, zoom

Harus ditetapkan dalam nilai yang setara dengan small dan xxxlarge. Jika tidak, elemen akan dinonaktifkan. Zoom akan dipertimbangkan 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 diperbaiki 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 bawah -0.05em akan diperbaiki menjadi -0.05em.

min-height

Akan memiliki nilai default 1em. Jika diberikan, nilai maksimum yang dihitung 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 diberikan, nilai maksimum yang dihitung antara nilai default dan nilai yang diberikan akan dipertimbangkan.

max-width

Akan memiliki nilai default tiga kali fit-content. Jika diberikan, nilai minimum yang dihitung 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 diperbaiki 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 diperbaiki menjadi 5em dan padding-right akan ditetapkan ke nilai padding-left.

transform

Efek visual yang mendistorsi tidak akan diizinkan. Untuk saat ini, kami hanya menerima terjemahan 2D dan penskalaan ke atas yang 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), dengan mengikuti aturan yang sama seperti setaranya.

Pseudo-class

Ada dua pseudo-class khusus yang memungkinkan gaya elemen <permission> berdasarkan status:

  • :granted: Pseudo-class :granted memungkinkan gaya khusus saat izin diberikan.
  • :invalid: Class semu :invalid memungkinkan gaya khusus saat elemen dalam status yang tidak valid, misalnya, saat ditayangkan di iframe lintas-asal.
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 perintah izin yang dipicu oleh elemen telah diselesaikan oleh pengguna yang melakukan beberapa tindakan pada perintah itu sendiri. Hal ini tidak berarti status izin telah berubah, pengguna mungkin telah mengambil tindakan yang mempertahankan status quo (seperti terus mengizinkan izin).

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

Anda dapat mendaftarkan pemroses peristiwa untuk peristiwa ini secara langsung inline dalam kode HTML (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />), atau menggunakan addEventListener() pada elemen <permission>, seperti yang 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> dalam kode HTML, tidak akan terjadi apa pun jika browser tidak mengetahuinya. Anda mungkin masih ingin mendeteksi dukungan menggunakan JavaScript, misalnya, untuk membuat perintah 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 untuk 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 merespons 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

  • Apa yang membuatnya lebih baik daripada <button> biasa yang disambungkan dengan Permissions API? Klik <button> adalah gestur pengguna, tetapi browser tidak dapat memverifikasi bahwa klik tersebut terhubung ke permintaan untuk meminta izin. Jika pengguna telah mengklik <permission>, browser dapat yakin bahwa klik tersebut terkait dengan permintaan izin. Hal ini memungkinkan browser memfasilitasi alur yang 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. Di browser yang tidak mendukung, alur izin klasik dapat digunakan. Misalnya, berdasarkan klik <button> reguler. Tim izin juga sedang mengerjakan polyfill. Beri bintang pada repo GitHub untuk mendapatkan notifikasi saat sudah siap.
  • Apakah hal ini dibahas dengan vendor browser lain? Elemen <permission> dibahas secara aktif di W3C TPAC pada tahun 2023 dalam sesi terpisah. Anda dapat membaca catatan sesi publik. Tim Chrome juga telah meminta Posisi Standar formal dari kedua vendor, lihat bagian Link terkait. Elemen <permission> merupakan topik diskusi yang sedang berlangsung dengan browser lain dan kami berharap dapat menstandarkannya.
  • Apakah ini benar-benar harus berupa elemen void? Masih diperdebatkan secara aktif apakah <permission> harus berupa elemen void atau tidak. Jika Anda memiliki masukan, berikan masukan di Masalah.

Ucapan terima kasih

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