ウェブアプリでの位置情報アクセスなどの強力な機能を使用するための権限をリクエストする命令型の方法はいくつかあります。これらの方法にはいくつかの課題が伴うため、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()
を呼び出すこともできました。ユーザーがウェブサイトを操作する前に、権限のプロンプトがポップアップ表示された。これは権限スパムと呼ばれることがあり、両方のアプローチに影響します。最初の使用時に暗黙的にリクエストするだけでなく、事前に明示的にリクエストします。
ブラウザでのリスク軽減策とユーザー操作の要件
権限スパムにより、ブラウザ ベンダーは権限プロンプトを表示する前に、ボタンのクリックや keydown イベントなどのユーザー操作を要求しました。この方法の問題は、特定のユーザー操作によって権限プロンプトを表示するかどうかをブラウザが判断するのは、不可能ではないにしても非常に困難であることです。ページの読み込みに時間がかかったために、ユーザーがどこかで不満を感じてページをクリックしただけであったり、実際に [Find me] ボタンをクリックしていたのかもしれません。一部のウェブサイトは、ユーザーをだましてコンテンツをクリックさせながらプロンプトをトリガーするのが得意なものもありました。
もう一つの緩和策は、プロンプトの不正使用対策を追加することです。たとえば、そもそも機能を完全にブロックする、権限プロンプトを非モーダルで邪魔にならない方法で表示するなどです。
権限のコンテキスト化
もう一つの課題は、特に大画面では、権限プロンプトがよく表示されることです。つまり、終了線の上、つまりアプリが描画できるブラウザ ウィンドウの領域外です。ユーザーがブラウザ ウィンドウの下部にあるボタンをクリックしただけで、上部のプロンプトを見逃してしまうことは珍しくありません。ブラウザのスパム対策が実施されると、この問題はしばしば悪化します。
簡単に元に戻せない
最後に、ユーザーが行き詰まりやすい状況に移ります。たとえば、ユーザーが機能へのアクセスをブロックした場合、ユーザーはサイト情報のプルダウンを認識する必要があります。このプルダウンでは、権限をリセットするか、ブロックされた権限をオンに戻すことができます。最悪のケースでは、どちらのオプションでも、更新された設定が有効になるまでページを完全に再読み込みする必要があります。サイトでは、ユーザーが既存の権限の状態を簡単に変更できるショートカットを用意できず、次の Google マップのスクリーンショットの下部に示すように、設定の変更方法をユーザーに丁寧に説明する必要があります。
権限がエクスペリエンスの鍵となる場合(たとえば、ビデオ会議アプリのマイクへのアクセスなど)、Google Meet などのアプリでは、権限のブロックを解除する方法をユーザーに指示する煩わしいダイアログが表示されます。
宣言型の <permission>
要素
この投稿でご紹介した課題に対処するために、Chrome の権限チームは新しい HTML 要素 <permission>
のオリジン トライアルを開始しました。この要素を使用すると、デベロッパーはウェブサイトで利用できる高度な機能のサブセットである現時点では、使用する権限を宣言的にリクエストできます。最も単純な形式では、次の例のように使用します。
<permission type="camera" />
<permission>
を void 要素にするかどうかについては、まだ議論が活発に行われています。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 です。指定した場合、デフォルト値と指定した値の間の最大計算値が考慮されます。 |
|
デフォルト値は 3 × fit-content です。指定した場合、デフォルト値と指定された値の間で最小の計算値が考慮されます。 |
|
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"
とみなされます。信頼できない場合(たとえば、要素が他の HTML コンテンツによって部分的に覆われている場合など)は"invalid"
と見なされます。
これらのイベントのイベント リスナーは、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>
要素のリポの公開シグナルにより、お客様が関心を持っていることが Google や他のブラウザに知らせることができます。
よくある質問
- これは、Permissions API と組み合わせた通常の
<button>
と比べてどのように優れているのですか?<button>
のクリックはユーザー操作です。ただし、ブラウザには、そのクリックが権限のリクエスト リクエストに関連付けられていることを確認できません。ユーザーが<permission>
をクリックした場合、ブラウザはそのクリックが権限リクエストに関連していることを確認できます。これによりブラウザは、他の方法ではよりリスクの高いフローを容易に進めることができます。たとえば、権限のブロックをユーザーが簡単に元に戻せるようにします。 - 他のブラウザが
<permission>
要素をサポートしていない場合はどうなりますか?<permission>
要素はプログレッシブ エンハンスメントとして使用できます。対応していないブラウザでは、従来の権限フローを使用できます。たとえば、通常の<button>
のクリックに基づいています。権限チームもポリフィルの開発に取り組んでいますGitHub リポジトリにスターを付けると、準備ができたときに通知を受け取ることができます。 - この問題は他のブラウザ ベンダーと議論されましたか?
<permission>
要素は、2023 年の W3C TPAC のブレイクアウト セッションで積極的に議論されました。公開セッションのメモをご覧ください。また、Chrome チームは、両方のベンダーに正式な標準ポジショニングも求めています。関連リンクセクションをご覧ください。<permission>
要素は他のブラウザとの議論が進められているトピックであり、標準化を目指しています。 - これは実際に void 要素にすべきでしょうか?
<permission>
を void 要素にするかどうかについては、まだ議論が活発に議論されています。フィードバックがある場合は、問題に関与します。
関連リンク
謝辞
このドキュメントは、Balázs Engedy、Thomas Nguyen、Penelope McLachlan、Marian Harbach、David Warren、Rachel Andrew がレビューしました。