Пробная версия источника для нового HTML <permission> элемент

Существует ряд обязательных методов запроса разрешения на использование мощных функций, таких как доступ к местоположению, в веб-приложениях. Эти методы сопряжены с рядом проблем, поэтому команда по разрешениям Chrome экспериментирует с новым декларативным методом: выделенным HTML-элементом <permission> . Этот элемент находится в пробной версии Chrome 126, и в конечном итоге мы надеемся его стандартизировать.

Императивные методы запроса разрешения

Когда веб-приложениям требуется доступ к мощным функциям , им необходимо запрашивать разрешение. Например, когда Карты Google запрашивают местоположение пользователя с помощью API геолокации , браузеры отправляют пользователю запрос, часто с возможностью сохранить это решение. Это четко определенная концепция в спецификации разрешений.

Неявно спрашивать при первом использовании вместо явного запроса заранее

API геолокации — это мощный API, основанный на неявном запросе при первом использовании. Например, когда приложение вызывает метод navigator.geolocation.getCurrentPosition() , запрос разрешений автоматически появляется при первом вызове. Другой пример — navigator.mediaDevices.getUserMedia() .

Другие API, такие как Notification API или Device 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> быть элементом void или нет. Элемент void — это самозакрывающийся элемент в 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. Сообщение об ошибке будет содержать более подробную информацию об обнаруженном нарушении.

Свойство Правила

color , background-color

Может использоваться для установки цвета текста и фона соответственно. Контраст между двумя цветами должен быть достаточным для четкого чтения текста (коэффициент контрастности не менее 3). Альфа-канал должен быть равен 1.

font-size , zoom

Должно быть установлено в пределах, эквивалентных small и xxxlarge . В противном случае элемент будет отключен. Масштаб будет учитываться при вычислении font-size .

outline-offset

Отрицательные значения будут исправлены на 0 .
margin (все) Отрицательные значения будут исправлены на 0 .

font-weight

Значения ниже 200 будут исправлены до 200 .

font-style

Значения, отличные от normal и italic будут исправлены на normal .

word-spacing

Значения более 0.5em будут исправлены до 0.5em . Значения ниже 0 будут исправлены на 0 .

display

Значения, отличные от inline-block и none , будут исправлены на 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 : Псевдокласс :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');" /> ) или с помощью addEventListener() в <permission> элемент, как показано в следующем примере.

<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> на своем сайте с реальными пользователями, подпишитесь на пробную версию Origin . Прочтите раздел Начало работы с пробными версиями Origin , чтобы узнать, как подготовить сайт к использованию пробных версий Origin. Пробная версия Origin будет работать с Chrome 126 по 131 (19 февраля 2025 г.).

Демо

Изучите демо-версию и ознакомьтесь с исходным кодом на GitHub. Вот скриншот опыта в поддерживающем браузере.

Демонстрация элемента разрешения с тремя кнопками разрешений.

Обратная связь

Мы хотели бы услышать от вас, как <permission> работает в вашем случае. Не стесняйтесь ответить на одну из проблем в репозитории или создать новую. Публичные сигналы в репозитории для элемента <permission> сообщат нам и другим браузерам, что вы заинтересованы в нем.

Часто задаваемые вопросы

  • Чем это лучше, чем обычная <button> в сочетании с API разрешений? Нажатие <button> — это жест пользователя, но у браузеров нет возможности проверить, связано ли оно с запросом разрешения. Если пользователь нажал <permission> , браузер может быть уверен, что щелчок связан с запросом разрешения. Это позволяет браузеру облегчать потоки, которые в противном случае были бы намного более рискованными. Например, позволяя пользователю легко отменить блокировку разрешения.
  • Что делать, если другие браузеры не поддерживают элемент <permission> ? Элемент <permission> можно использовать в качестве прогрессивного улучшения. В неподдерживающих браузерах можно использовать классический поток разрешений. Например, на основе нажатия обычной <button> . Команда по разрешениям также работает над полифилом. Отметьте репозиторий GitHub, чтобы получить уведомление, когда он будет готов.
  • Обсуждалось ли это с другими поставщиками браузеров? Элемент <permission> активно обсуждался на секционном заседании W3C TPAC в 2023 году. Вы можете прочитать протоколы публичного заседания . Команда Chrome также запросила у обоих поставщиков официальные позиции по стандартам, см. раздел «Связанные ссылки» . Элемент <permission> — постоянная тема дискуссий с другими браузерами, и мы надеемся его стандартизировать.
  • Должно ли это быть пустым элементом? До сих пор активно обсуждается, должен ли <permission> быть элементом void или нет. Если у вас есть отзывы, присоединяйтесь к проблеме.

Благодарности

Этот документ рецензировали Балаж Энгеди , Томас Нгуен , Пенелопа Маклахлан , Мэриан Харбах , Дэвид Уоррен и Рэйчел Эндрю .