新 HTML <權限> 元素的來源試用

有許多必要方法可要求使用位置存取權等強大功能的權限,以便在網路應用程式中使用。這些方法存在許多挑戰,因此 Chrome 權限團隊正在嘗試使用新的宣告式方法:專屬的 HTML <permission> 元素。這個元素在 Chrome 126 的來源試用計畫中,我們最終希望將其標準化。

要求權限的命令式方法

如果網頁應用程式需要存取強大功能,就必須要求授權。舉例來說,當 Google 地圖使用 Geolocation API 要求使用者提供地理位置時,瀏覽器會向使用者發出提示,通常會提供儲存該決定的選項。這是權限規格中明確定義的概念

在首次使用時隱含要求,而非事先明確要求

Geolocation API 是功能強大的 API,採用隱含的首次使用時詢問方法。舉例來說,當應用程式呼叫 navigator.geolocation.getCurrentPosition() 方法時,系統會在第一次呼叫時自動顯示權限提示。另一個例子是 navigator.mediaDevices.getUserMedia()

其他 API (例如 Notification APIDevice Orientation and Motion API) 通常提供明確的方式,讓您透過 Notification.requestPermission()DeviceMotionEvent.requestPermission() 等靜態方法要求權限。

使用命令式方法要求權限的挑戰

權限垃圾內容

過去,網站可以呼叫 navigator.mediaDevices.getUserMedia()Notification.requestPermission() 等方法,但在網站載入時會立即呼叫 navigator.geolocation.getCurrentPosition()。在使用者與網站互動之前,會彈出權限提示。這有時會被稱為權限垃圾訊息,並會影響兩種方法,包括首次使用時間接要求,以及事先明確要求。

載入網站時顯示的麥克風權限提示。

瀏覽器緩解措施和使用者手勢需求

權限垃圾訊息導致瀏覽器供應商在顯示權限提示前,要求使用者手勢 (例如按鈕點擊或按下鍵事件)。這種做法的問題是,瀏覽器很難 (甚至不可能) 判斷特定使用者手勢是否應顯示權限提示。也許是因為網頁載入時間過長,使用者才會在感到挫折時隨意點選網頁上的任何位置,或是他們確實按下「定位我的位置」按鈕。有些網站也非常擅長誘騙使用者點按內容,觸發提示。

另一個緩解措施是加入提示濫用緩解措施,例如一開始就完全封鎖功能,或是以非模組、較不會造成乾擾的方式顯示權限提示。

Chrome 瀏覽器顯示

權限情境化

另一個挑戰 (特別是在大螢幕上) 是權限提示的常見顯示方式:在死亡線上方 (也就是應用程式可繪製的瀏覽器視窗區域之外)。使用者在點選視窗底部的按鈕時,可能會錯過瀏覽器視窗頂端的提示,這並非罕見現象。在瀏覽器垃圾內容緩解措施生效時,這個問題通常會更加嚴重。

開啟位置存取權提示的 Google 地圖。觸發提示的位置資訊存取權按鈕很遠。

無法輕鬆復原

最後,使用者很容易誤觸死路。舉例來說,如果使用者封鎖某項功能的存取權,就必須注意網站資訊下拉式選單,才能重設權限或重新啟用已封鎖的權限。在最壞的情況下,這兩種做法都需要重新載入整個網頁,更新設定才會生效。網站無法提供簡單的捷徑,讓使用者輕鬆變更現有權限狀態,因此必須費心向使用者說明如何變更設定,如下方 Google 地圖螢幕截圖底部所示。

使用 Chrome 的 Google 地圖網站控制項撤銷權限。

如果權限是體驗的關鍵,例如視訊會議應用程式的麥克風存取權,Google Meet 等應用程式就會顯示侵入式對話方塊,指示使用者如何解除權限封鎖。

Google Meet 操作說明:如何開啟 Chrome 網站控制項。

宣告式 <permission> 元素

為解決這篇文章中提到的挑戰,Chrome 權限團隊已針對新的 HTML 元素 <permission> 推出來源試用版。這個元素可讓開發人員以宣告方式要求使用權限,目前僅限於網站可用的強大功能子集。在最簡單的形式中,您可以按照以下範例使用:

<permission type="camera" />

是否應將 <permission> 設為空元素,目前仍在積極討論中。空元素是 HTML 中的自關閉元素,不能有任何子節點,也就是說,在 HTML 中,它可能沒有結尾標記。

type 屬性

type 屬性包含您要要求的權限清單 (以空格分隔)。在撰寫本文時,允許的值為 'camera''microphone'camera microphone (以空格分隔)。根據預設,這個元素會以類似使用者代理程式樣式的按鈕呈現。

各種權限元素按鈕,包括相機、麥克風、相機和麥克風權限。

type-ext 屬性

對於某些允許使用其他參數的權限,type-ext 屬性會接受以空格分隔的鍵/值組合,例如,用於取得地理位置權限的 precise:true

lang 屬性

按鈕文字由瀏覽器提供,且應保持一致,因此無法直接自訂。瀏覽器會根據文件或父元素鏈結的繼承語言,或選用的 lang 屬性,變更文字的語言。也就是說,開發人員不需要自行將 <permission> 元素本地化。如果 <permission> 元素繼續進行來源試用階段,為了增加彈性,系統可能會支援多個字串或圖示。如果您想要使用 <permission> 元素且需要特定字串或圖示,請與我們聯絡

行為

當使用者與 <permission> 元素互動時,他們可以循環切換各個階段:

  • 如果他們先前不允許使用某項功能,則可在每次造訪時允許該功能,或允許在目前造訪期間使用這項功能。

    選擇權限提示,讓系統在每次造訪時或每次造訪時允許特定功能。

  • 如果使用者先前已允許這項功能,可以繼續允許或停止允許。

    權限提示,要求使用者繼續允許或停止允許。

  • 如果使用者先前已禁止某項功能,可以繼續禁止,也可以這次允許。

    權限提示表示「不允許」或「允許」這次不允許。

<permission> 元素的文字會根據狀態自動更新。舉例來說,如果已授予使用某項功能的權限,文字就會變更為「允許使用」功能。如果需要先授予權限,文字會變更為邀請使用者使用該功能。請比較先前的螢幕截圖和下方的螢幕截圖,瞭解這兩種狀態。

權限按鈕,文字為

CSS 設計

為確保使用者能輕鬆辨識按鈕,並瞭解如何存取強大的功能,我們限制了 <permission> 元素的樣式。如果您認為樣式限制不適用於您的用途,歡迎告訴我們原因和原因!雖然無法滿足所有樣式需求,但我們希望在原點試驗後,能找到安全的方式,讓 <permission> 元素有更多樣式。下表詳細說明部分屬性適用的限制或特殊規則。如果違反任何規則,<permission> 元素將會停用,也無法與使用者互動。任何嘗試與其互動的動作都會導致例外狀況,而這些例外狀況可透過 JavaScript 擷取。錯誤訊息會針對偵測到的違規項目提供詳細資料。

屬性 規則

colorbackground-color

可分別用於設定文字和背景顏色。兩種顏色的對比度必須足以讓文字清晰易讀 (至少 3 的對比度)。Alpha 版必須為 1。

font-sizezoom

必須在與 smallxxxlarge 相等的範圍內設定。否則元素會停用。計算 font-size 時,系統會考量縮放功能。

outline-offset

負值會修正為 0
margin (全部) 負值會更正為 0

font-weight

200 以下的值會修正為 200

font-style

normalitalic 以外的值會更正為 normal

word-spacing

超過 0.5em 的值會修正為 0.5em0 以下的值會修正為 0

display

inline-blocknone 以外的值會修正為 inline-block

letter-spacing

超過 0.2em 的值會修正為 0.2em-0.05em 以下的值會修正為 -0.05em

min-height

預設值為 1em。如果提供此值,系統會考量預設值和提供值之間的最大計算值。

max-height

預設值為 3em。如果提供,系統會考量預設值和提供值之間的最低計算值。

min-width

預設值為 fit-content。如有提供,將會考慮計算預設值和提供值之間的最大值。

max-width

預設值為 fit-content 的三倍。如果提供,系統會考量預設值和提供值之間的最低計算值。

padding-top

只有在 height 設為 auto 時才會生效。在此情況下,系統會將超過 1em 的值修正為 1em,並將 padding-bottom 設為 padding-top 的值。

padding-left

只有在 width 設為 auto 時才會生效。在這種情況下,超過 5em 的值會修正為 5em,而 padding-right 會設為 padding-left. 的值。

transform

我們不允許使用扭曲的視覺效果。目前我們只接受 2D 翻譯和按比例向上調整。

以下 CSS 屬性可正常使用:

  • 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 (和所有 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-* (例外狀況: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

此外,所有邏輯上等價的屬性 (例如 inline-size 等同於 width) 都可以使用,並遵循等價屬性相同的規則。

擬類別

有兩個特殊的擬造類別可讓您根據狀態為 <permission> 元素設定樣式:

  • :granted:granted 虛擬類別可在獲得權限時用於特殊樣式。
  • :invalid:當元素處於無效狀態時 (例如在跨來源 iframe 中提供),:invalid 擬類別可允許特殊樣式。
permission {
  background-color: green;
}

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

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

JavaScript 事件

<permission> 元素應與 Permissions API 搭配使用。以下列舉幾個可監聽的事件:

  • onpromptdismiss:當使用者關閉元素觸發的權限提示 (例如按一下關閉按鈕或點選提示以外的區域) 時,系統會觸發此事件。

  • onpromptaction:當使用者對提示本身採取某些動作,解決元素觸發的權限提示時,系統會觸發此事件。這不一定代表權限狀態已變更,使用者可能已採取可維持現狀的操作 (例如持續允許權限)。

  • onvalidationstatuschange:當元素從 "valid" 切換為 "invalid" 時,系統會觸發此事件。如果瀏覽器信任信號的完整性 (例如使用者點選信號),就會將元素視為 "valid";如果不是,則會視為 "invalid",例如元素遭其他 HTML 內容部分遮蔽時。

您可以直接在 HTML 程式碼 (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />) 中註冊這些事件的事件監聽器,也可以在 <permission> 元素上使用 addEventListener(),如以下範例所示。

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

特徵偵測

如果瀏覽器不支援 HTML 元素,就不會顯示該元素。這表示如果您的 HTML 程式碼中包含 <permission> 元素,如果瀏覽器不知道該元素,不會進行任何操作。您可能仍想使用 JavaScript 偵測支援功能,例如透過點選一般 <button> 觸發權限提示。

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

來源試用

如要讓實際使用者在網站上試用 <permission> 元素,請註冊原始試用版。如要瞭解如何準備網站以使用原始伺服器試用功能,請參閱「開始使用原始伺服器試用功能」一文。來源試用將從 Chrome 126 到 131 版 (2025 年 2 月 19 日) 進行。

示範

請參閱示範,並查看 GitHub 上的原始碼。以下是支援的瀏覽器體驗螢幕截圖。

權限元素示範,顯示三個權限按鈕。

意見回饋

我們很樂意瞭解 <permission> 在您的使用情境中如何發揮作用。歡迎回覆其中一個存放區中的問題,或提出新問題。<permission> 元素的 repo 中的公開信號會讓我們和其他瀏覽器知道您對此感興趣。

常見問題

  • 與搭配 Permissions API 的一般 <button> 相比,這有何優勢?點按 <button> 是使用者動作,但瀏覽器無法驗證該動作是否與要求權限的請求相關。如果使用者點選 <permission>,瀏覽器就可以確保點擊與權限要求相關。這樣一來,瀏覽器就能促進原本風險較高的流程。例如,允許使用者輕鬆撤銷對權限的封鎖。
  • 如果其他瀏覽器不支援 <permission> 元素,該怎麼辦?<permission> 元素可用於漸進式增強功能。在未支援的瀏覽器上,您可以使用傳統權限流程。例如,根據一般 <button> 的點擊次數。權限團隊也正在處理 polyfill。為 GitHub 存放區按讚,即可在可使用時收到通知。
  • 是否與其他瀏覽器供應商討論過這個問題?<permission> 元素在 2023 年的 W3C TPAC 中,曾在分組會議中積極討論。您可以閱讀公開工作階段附註。Chrome 團隊也要求兩家供應商提供正式的標準立場,請參閱「相關連結」一節。<permission> 元素是與其他瀏覽器持續進行的討論主題,希望將這項元素標準化。
  • 這是否應為空元素?是否應將 <permission> 設為空元素,目前仍在積極討論中。如有任何意見,請在問題中提出。

特別銘謝

本文件由 Balázs EngedyThomas NguyenPenelope McLachlanMarian HarbachDavid WarrenRachel Andrew 審查。