ウェブアプリで位置情報へのアクセスなどの強力な機能を使用する権限をリクエストするには、いくつかの命令型メソッドがあります。これらの方法には多くの課題があるため、Chrome 権限チームは、新しい宣言型の方法(専用の HTML <permission>
要素)をテストしています。この要素は Chrome 126 からオリジン トライアルで使用されており、最終的には標準化される予定です。
権限をリクエストする命令型メソッド
ウェブアプリが高度な機能にアクセスする必要がある場合は、権限をリクエストする必要があります。たとえば、Google マップが Geolocation API を使用してユーザーの位置情報を必要とする場合は、ブラウザからユーザーにプロンプトが表示されます。多くの場合、その決定を保存するオプションも表示されます。これは、権限仕様で明確に定義されたコンセプトです。
初回使用時に暗黙的にリクエストする、または事前に明示的にリクエストする
Geolocation API は強力な API で、初回使用時に暗黙的にリクエストするアプローチを採用しています。たとえば、アプリが navigator.geolocation.getCurrentPosition()
メソッドを呼び出すと、最初の呼び出し時に権限プロンプトが自動的にポップアップ表示されます。別の例として、navigator.mediaDevices.getUserMedia()
が挙げられます。
Notification API や Device Orientation and Motion API などの他の API には、通常、Notification.requestPermission()
や DeviceMotionEvent.requestPermission()
などの静的メソッドを介して権限を明示的にリクエストする方法があります。
権限をリクエストする命令型メソッドの課題
権限に関するスパム
これまで、ウェブサイトは navigator.mediaDevices.getUserMedia()
や Notification.requestPermission()
などのメソッドを呼び出すことができましたが、ウェブサイトの読み込み時に navigator.geolocation.getCurrentPosition()
をすぐに呼び出すこともできました。ユーザーがウェブサイトを操作する前に、権限プロンプトがポップアップ表示されます。これは、許可スパムと呼ばれることもあります。これは、初回使用時に暗黙的に尋ねるアプローチと、事前に明示的にリクエストするアプローチの両方に影響します。
ブラウザによる緩和策とユーザー操作の要件
権限スパムの増加により、ブラウザ ベンダーは、権限プロンプトを表示する前に、ボタンのクリックやキーダウン イベントなどのユーザー操作を必要とするようにしました。このアプローチの問題は、特定のユーザー操作で権限プロンプトを表示する必要があるかどうかをブラウザが判断するのが非常に困難(不可能ではないが)なことです。ページの読み込みに時間がかかり、ユーザーがイライラしてページのどこかをクリックしただけかもしれません。または、ユーザーが本当に [現在地を検索] ボタンをクリックしたのかもしれません。また、一部のウェブサイトは、ユーザーをだましてコンテンツをクリックさせ、プロンプトをトリガーする手法に長けていました。
別の緩和策として、プロンプト濫用の緩和策を追加することもできます。たとえば、最初から機能を完全にブロックしたり、権限プロンプトをモーダル以外の、より邪魔にならない方法で表示したりします。
権限のコンテキスト化
特に大画面の場合、権限プロンプトが通常表示される場所がデッドラインの上、つまりアプリが描画できるブラウザ ウィンドウの領域外にあることも、もう 1 つの課題です。ウィンドウの下部にあるボタンをクリックしたばかりのユーザーが、ブラウザ ウィンドウの上部にあるプロンプトを見逃してしまうことは珍しくありません。この問題は、ブラウザのスパム対策が適用されている場合に悪化することがあります。
簡単に元に戻せない
最後に、ユーザーが行き止まりに迷い込む可能性も高くなります。たとえば、ユーザーが機能へのアクセスをブロックすると、サイト情報のプルダウンが表示されます。このプルダウンで、権限をリセットしたり、ブロックした権限を再度有効にしたりできます。どちらのオプションでも、最悪の場合、更新された設定が有効になるまでページを完全に再読み込みする必要があります。サイトは、ユーザーが既存の権限の状態を簡単に変更できる簡単なショートカットを提供できません。次の Google マップのスクリーンショットの下部に示すように、設定を変更する方法についてユーザーに丁寧に説明する必要があります。
ビデオ会議アプリのマイクへのアクセスなど、権限がエクスペリエンスの鍵となる場合は、Google Meet などのアプリに、権限のブロックを解除する方法を指示する侵入的なダイアログが表示されます。
宣言型の <permission>
要素
この投稿で説明した課題に対処するため、Chrome 権限チームは新しい HTML 要素 <permission>
のオリジン トライアルを開始しました。この要素を使用すると、デベロッパーは、ウェブサイトで利用可能な強力な機能のサブセットの使用許可を宣言的にリクエストできます。最も単純な形式では、次の例のように使用します。
<permission type="camera" />
<permission>
を void 要素にすべきかどうかについては、現在も活発に議論されています。無効な要素は、子ノードを持てない HTML の自己終了要素です。つまり、HTML では終了タグがなくてもかまいません。
type
属性
type
属性には、リクエストする権限のスペース区切りのリストが含まれます。執筆時点では、指定できる値は 'camera'
、'microphone'
、camera microphone
です(スペースで区切ります)。この要素は、デフォルトでは、最低限のユーザー エージェント スタイル設定が適用されたボタンのようにレンダリングされます。
type-ext
属性
追加のパラメータを許可する権限では、type-ext
属性にスペース区切りの Key-Value ペアを指定できます。たとえば、位置情報の権限の場合は precise:true
です。
lang
属性
ボタンのテキストはブラウザから提供され、一貫性を持たせることを目的としているため、直接カスタマイズすることはできません。ブラウザは、ドキュメントまたは親要素チェーンの継承された言語、または省略可能な lang
属性に基づいてテキストの言語を変更します。つまり、デベロッパーは <permission>
要素をローカライズする必要はありません。<permission>
要素がオリジンのトライアル ステージを超えると、柔軟性を高めるために、権限タイプごとに複数の文字列またはアイコンがサポートされる場合があります。<permission>
要素の使用に関心をお持ちで、特定の文字列やアイコンが必要な場合は、お問い合わせください。
動作
ユーザーが <permission>
要素を操作すると、さまざまなステージを切り替えることができます。
以前に機能を許可していない場合は、すべてのアクセスで許可するか、現在のアクセスで許可できます。
以前に機能を許可していた場合は、引き続き許可するか、許可を停止できます。
以前に機能を許可しなかった場合は、引き続き許可しないようにするか、今回は許可するようにします。
<permission>
要素のテキストは、ステータスに基づいて自動的に更新されます。たとえば、機能の使用が許可された場合、テキストが変更され、機能が許可されていることを示します。最初に権限を付与する必要がある場合は、テキストが変更され、ユーザーに機能を使用するよう求めるメッセージが表示されます。前のスクリーンショットと次のスクリーンショットを比較して、2 つの状態を確認します。
CSS 設計
ユーザーが強力な機能にアクセスするためのサーフェスとしてボタンを簡単に認識できるように、<permission>
要素のスタイル設定は制限されています。スタイル設定の制限がユースケースで機能しない場合は、その理由をお知らせください。すべてのスタイル設定ニーズに対応できるわけではありませんが、オリジン トライアル後に <permission>
要素のより多くのスタイル設定を許可する安全な方法を見つけることを期待しています。次の表に、制限または特別なルールが適用されるプロパティの詳細を示します。いずれかのルールに違反すると、<permission>
要素が無効になり、操作できなくなります。これを操作しようとすると、JavaScript でキャッチできる例外が発生します。エラー メッセージには、検出された違反の詳細が含まれます。
プロパティ | ルール |
---|---|
|
テキストと背景の色をそれぞれ設定できます。2 つの色のコントラストは、テキストを明瞭に判読できる程度に十分である必要があります(コントラスト比 3 以上)。アルファ版チャンネルは 1 にする必要があります。 |
|
small と xxxlarge と同等の範囲内に設定する必要があります。そうでない場合、要素は無効になります。font-size の計算では、ズームが考慮されます。 |
|
負の値は 0 に修正されます。 |
margin (すべて) |
負の値は 0 に修正されます。 |
|
200 未満の値は 200 に修正されます。 |
|
normal と italic 以外の値は normal に修正されます。 |
|
0.5em を超える値は 0.5em に修正されます。0 の値は 0 に修正されます。 |
|
inline-block と none 以外の値は inline-block に修正されます。 |
|
0.2em を超える値は 0.2em に修正されます。-0.05em 未満の値は -0.05em に修正されます。 |
|
デフォルト値は 1em です。指定されている場合、デフォルト値と指定された値の間で計算された最大値が考慮されます。 |
|
デフォルト値は 3em です。指定されている場合、デフォルト値と指定された値の間で計算された最小値が考慮されます。 |
|
デフォルト値は fit-content です。指定されている場合、デフォルト値と指定された値の間で計算された最大値が考慮されます。 |
|
デフォルト値は fit-content の 3 倍です。指定されている場合、デフォルト値と指定された値の間で計算された最小値が考慮されます。 |
|
height が auto に設定されている場合にのみ有効になります。この場合、1em を超える値は 1em に修正され、padding-bottom は padding-top の値に設定されます。 |
|
width が auto に設定されている場合にのみ有効になります。この場合、5em を超える値は 5em に修正され、padding-right は padding-left. の値に設定されます。 |
|
歪みを伴う視覚効果は許可されません。現時点では、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>
要素のスタイル設定を可能にする特別な疑似クラスが 2 つあります。
:granted
::granted
疑似クラスを使用すると、権限が付与された場合に特別なスタイル設定を行うことができます。:invalid
::invalid
疑似クラスを使用すると、要素が無効な状態(クロスオリジン iframe で提供されている場合など)に応じて特別なスタイルを適用できます。
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にある公開シグナルにより、ユーザーがこの要素に関心を持っていることが Google と他のブラウザに通知されます。
よくある質問
- Permissions API とペア設定された通常の
<button>
と比べて、この方法はどのような点で優れていますか?<button>
のクリックはユーザー操作ですが、ブラウザは権限をリクエストするリクエストに関連付けられていることを検証できません。ユーザーが<permission>
をクリックした場合、ブラウザはクリックが権限リクエストに関連していることを確信できます。これにより、ブラウザは、リスクが非常に高いフローを容易に行うことができます。たとえば、ユーザーが権限のブロックを簡単に元に戻せるようにする。 - 他のブラウザで
<permission>
要素がサポートされていない場合はどうなりますか?<permission>
要素は、段階的な拡張機能として使用できます。サポートされていないブラウザでは、従来の権限フローを使用できます。たとえば、通常の<button>
のクリックに基づいて、権限チームはポリフィルにも取り組んでいます。GitHub リポジトリにスターを付けると、準備が整うと通知が届きます。 - この件は他のブラウザ ベンダーと話し合いましたか?
<permission>
要素は、2023 年の W3C TPAC のブレークアウト セッションで活発に議論されました。公開セッションのメモを読むことができます。Chrome チームは、両方のベンダーに正式な標準化の立場を求めています。詳しくは、関連リンクをご覧ください。<permission>
要素は、他のブラウザとの継続的な議論のトピックであり、標準化を目指しています。 - これは実際には空要素にすべきですか?
<permission>
を void 要素にすべきかどうかについては、現在も活発に議論されています。フィードバックがある場合は、Issue にコメントしてください。
関連リンク
謝辞
このドキュメントは、Balázs Engedy、Thomas Nguyen、Penelope McLachlan、Marian Harbach、David Warren、Rachel Andrew が確認しました。