새 HTML <permission> 요소에 대한 오리진 트라이얼

웹 앱에서 위치 정보 액세스와 같은 강력한 기능을 사용하기 위한 권한을 요청하는 여러 명령형 메서드가 있습니다. 이러한 메서드에는 여러 가지 문제가 수반되므로 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 이벤트와 같은 사용자 동작을 요구하게 되었습니다. 이 접근 방식의 문제는 브라우저가 특정 사용자 동작으로 인해 권한 메시지가 표시되어야 하는지 여부를 파악하기가 매우 어렵다는 점입니다. 페이지가 로드되는 데 시간이 너무 오래 걸려 사용자가 짜증이 나서 아무 곳이나 클릭했을 수도 있고, 실제로 내 위치 찾기 버튼을 클릭했을 수도 있습니다. 일부 웹사이트는 사용자를 속여 콘텐츠를 클릭하도록 유도하여 메시지를 표시하는 데 능숙해졌습니다.

또 다른 완화 조치는 기능을 완전히 차단하거나 권한 메시지를 모달이 아닌 덜 방해가 되는 방식으로 표시하는 등 메시지 악용 완화 조치를 추가하는 것입니다.

Chrome 브라우저에 표시된

권한 컨텍스트화

또 다른 문제는, 특히 대형 화면에서는 권한 메시지가 일반적으로 표시되는 방식입니다. 즉, 종료 줄 위, 즉 앱이 그릴 수 있는 브라우저 창 영역 밖에 위치해야 합니다. 사용자가 창 하단의 버튼을 클릭한 후 브라우저 창 상단의 메시지를 놓치는 경우가 종종 있습니다. 이 문제는 브라우저 스팸 완화 조치를 적용하면 악화되는 경우가 많습니다.

위치 정보 액세스 권한 메시지가 열려 있는 Google 지도 메시지를 트리거한 위치 정보 액세스 버튼이 멀리 있습니다.

쉽게 실행취소할 수 없음

마지막으로 사용자가 너무 쉽게 막다른 길로 들어갈 수 있습니다. 예를 들어 사용자가 기능에 대한 액세스를 차단한 후에는 권한을 재설정하거나 차단된 권한을 다시 사용 설정할 수 있는 사이트 정보 드롭다운을 알아야 합니다. 최악의 경우 두 옵션 모두 업데이트된 설정이 적용될 때까지 페이지를 완전히 새로고침해야 합니다. 사이트는 사용자가 기존 권한 상태를 쉽게 변경할 수 있는 바로가기를 제공할 수 없으며 다음 Google 지도 스크린샷 하단에 표시된 것처럼 사용자에게 설정을 변경하는 방법을 세심하게 설명해야 합니다.

Google 지도의 Chrome 사이트 제어 기능을 사용하여 권한을 취소합니다.

동영상 회의 애플리케이션의 마이크 액세스와 같이 권한이 환경의 핵심인 경우 Google Meet과 같은 앱은 사용자에게 권한 차단을 해제하는 방법을 안내하는 방해가 되는 대화상자를 표시합니다.

Chrome 사이트 제어 기능을 여는 방법에 관한 Google Meet 안내입니다.

선언적 <permission> 요소

이 게시물에 설명된 문제를 해결하기 위해 Chrome 권한팀은 새로운 HTML 요소인 <permission>의 출처 체험판을 출시했습니다. 이 요소를 사용하면 개발자가 현재 웹사이트에서 사용할 수 있는 강력한 기능의 하위 집합을 선언적으로 사용할 권한을 요청할 수 있습니다. 가장 간단한 형식으로는 다음 예와 같이 사용합니다.

<permission type="camera" />

<permission>가 무효 요소여야 하는지 여부에 대한 적극적인 논쟁은 여전히 진행 중입니다. 무효 요소는 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

smallxxxlarge에 상응하는 값으로 설정해야 합니다. 그렇지 않으면 요소가 사용 중지됩니다. font-size를 계산할 때 확대/축소가 고려됩니다.

outline-offset

음수 값은 0로 수정됩니다.
margin(전체) 음수 값은 0로 수정됩니다.

font-weight

200 미만의 값은 200(으)로 수정됩니다.

font-style

normalitalic 이외의 값은 normal로 수정됩니다.

word-spacing

0.5em를 초과하는 값은 0.5em로 수정됩니다. 0 미만의 값은 0로 수정됩니다.

display

inline-blocknone 이외의 값은 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의 3배입니다. 제공되는 경우 기본값과 제공된 값 사이의 최솟값이 계산됩니다.

padding-top

heightauto로 설정된 경우에만 적용됩니다. 이 경우 1em를 초과하는 값은 1em로 수정되고 padding-bottompadding-top 값으로 설정됩니다.

padding-left

widthauto로 설정된 경우에만 적용됩니다. 이 경우 5em보다 큰 값은 5em로 수정되고 padding-rightpadding-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-sizewidth와 동일함) 동일한 속성과 동일한 규칙을 따릅니다.

의사 클래스

상태에 따라 <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;
}

자바스크립트 이벤트

<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> 요소가 있더라도 브라우저가 이 요소를 모르면 아무 일도 일어나지 않습니다. 일반 <button> 클릭을 통해 트리거되는 권한 메시지를 만들기 위해 JavaScript를 사용하여 지원을 감지하는 것이 좋습니다.

if ('HTMLPermissionElement' in window) {
  // The `<permission>` element is supported.
}

오리진 트라이얼

사이트에서 실제 사용자를 대상으로 <permission> 요소를 사용해 보려면 Origin Trial에 가입하세요. 출처 무료 체험판을 사용하도록 사이트를 준비하는 방법은 출처 무료 체험판 시작하기를 참고하세요. 오리진 트라이얼은 Chrome 126~131 (2025년 2월 19일)에서 실행됩니다.

데모

데모를 살펴보고 GitHub에서 소스 코드를 확인하세요. 다음은 지원되는 브라우저에서의 환경을 보여주는 스크린샷입니다.

세 개의 권한 버튼을 보여주는 권한 요소 데모

의견

사용 사례에 <permission>가 어떻게 작동하는지 알려주세요. 언제든지 저장소의 문제 중 하나에 응답하거나 새 문제를 제출하세요. <permission> 요소의 저장소에 있는 공개 신호를 통해 Google과 다른 브라우저에 이 요소에 관심이 있음을 알릴 수 있습니다.

FAQ

  • 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가 검토했습니다.