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

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

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

Когда веб-приложениям требуется доступ к мощным функциям , им нужно запросить разрешение. Например, когда Google Maps запрашивает местоположение пользователя с помощью 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 Maps с открытым запросом на разрешение местоположения. Кнопка доступа к местоположению, которая вызвала запрос, находится далеко.

Нет легкой отмены

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

Управление сайтом Chrome на Картах Google для отзыва разрешений.

Если разрешение является ключевым для взаимодействия, например, доступ к микрофону для приложения видеоконференций, такие приложения, как Google Meet, показывают навязчивые диалоговые окна, которые инструктируют пользователя, как разблокировать разрешение.

Инструкции Google Meet по открытию элементов управления сайтом Chrome.

Декларативный элемент <permission>

Чтобы решить проблемы, описанные в этом посте, команда Chrome permissions запустила origin trial для нового элемента 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> после пробной версии origin. В следующей таблице подробно описаны некоторые свойства, к которым применяются ограничения или специальные правила. В случае нарушения любого из правил элемент <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> предназначен для использования вместе с 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> работает в вашем случае использования. Не стесняйтесь ответить на один из Issues в репозитории или подать новый. Публичные сигналы в репозитории для элемента <permission> дадут нам и другим браузерам знать, что вы заинтересованы в нем.

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

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

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

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