ウェブアプリでの位置情報へのアクセスなどの強力な機能を使用するための権限をリクエストする、命令型のメソッドはいくつかあります。これらの方法には多くの課題があるため、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()
をすぐに呼び出すこともできました。ユーザーがウェブサイトを操作する前に、権限プロンプトがポップアップ表示されます。これは、許可スパムと呼ばれることもあります。初回使用時に暗黙的に尋ねるアプローチと、事前に明示的にリクエストするアプローチの両方に影響します。
ブラウザでのリスク軽減策とユーザー操作の要件
権限スパムの増加により、ブラウザ ベンダーは、権限プロンプトを表示する前に、ボタンのクリックやキーダウン イベントなどのユーザー操作を必要とするようにしました。このアプローチの問題は、特定のユーザー操作で権限プロンプトを表示する必要があるかどうかをブラウザが判断するのが非常に困難(不可能ではないが)なことです。ページの読み込みに時間がかかったために、ユーザーがどこかで不満を感じてページをクリックしただけであったり、実際に [Visit me] ボタンをクリックしていた可能性もあります。一部のウェブサイトは、ユーザーをだましてコンテンツをクリックさせながらプロンプトをトリガーすることを得意としています。
別の緩和策として、プロンプト濫用を軽減する対策を追加することもできます。たとえば、最初から機能を完全にブロックしたり、権限プロンプトをモーダル以外の、より目立たない方法で表示したりします。
権限のコンテキスト化
特に大画面の場合、権限プロンプトが通常表示される場所がデッドラインの上、つまりアプリが描画できるブラウザ ウィンドウの領域外にあることも、もう 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>
要素のリポの公開シグナルにより、お客様が関心を持っていることが Google や他のブラウザに知らせることができます。
よくある質問
- これは、Permissions API と組み合わせた通常の
<button>
と比べてどのように優れているのですか?<button>
のクリックはユーザー操作ですが、ブラウザは権限をリクエストするリクエストに関連付けられていることを検証できません。ユーザーが<permission>
をクリックした場合、ブラウザはそのクリックが権限リクエストに関連していることを確認できます。これにより、ブラウザは、リスクが非常に高いフローを容易に行うことができます。たとえば、ユーザーが権限のブロックを簡単に元に戻せるようにする。 - 他のブラウザで
<permission>
要素がサポートされていない場合はどうなりますか?<permission>
要素はプログレッシブ エンハンスメントとして使用できます。対応していないブラウザでは、従来の権限フローを使用できます。たとえば、通常の<button>
のクリックに基づいています。権限チームはポリフィルにも取り組んでいます。GitHub リポジトリにスターを付けると、準備が整うと通知が届きます。 - この問題は他のブラウザ ベンダーと議論されましたか?
<permission>
要素は、2023 年の W3C TPAC のブレイクアウト セッションで積極的に議論されました。公開セッションのメモを読むことができます。また、Chrome チームは、両ベンダーに正式な標準ポジショニングも求めています。関連リンクセクションをご覧ください。<permission>
要素は、他のブラウザとの継続的な議論のトピックであり、標準化を目指しています。 - これは実際には空要素にすべきですか?
<permission>
を void 要素にすべきかどうかについては、現在も活発に議論されています。フィードバックがある場合は、問題に関与します。
関連リンク
謝辞
このドキュメントは、Balázs Engedy、Thomas Nguyen、Penelope McLachlan、Marian Harbach、David Warren、Rachel Andrew によって確認されました。