PWA 제목 표시줄의 창 컨트롤 오버레이 맞춤설정

창 컨트롤 옆에 있는 제목 표시줄 영역을 사용하여 PWA를 앱처럼 느껴지게 만듭니다.

PWA를 앱처럼 느껴지게 만들기 도움말을 떠올리셨다면 앞서 앱의 제목 표시줄 맞춤설정을 앱과 유사한 환경을 만들기 위한 전략입니다. 여기 표시된 예는 macOS 팟캐스트 앱

<ph type="x-smartling-placeholder">
</ph> 현재 재생 중인 팟캐스트에 관한 미디어 컨트롤 버튼과 메타데이터가 표시된 macOS 팟캐스트 앱 제목 표시줄 <ph type="x-smartling-placeholder">
</ph> 맞춤 제목 표시줄을 사용하면 PWA를 특정 플랫폼 앱처럼 느껴집니다.

이제 Podcast가 브라우저에서 실행되지 않으므로 브라우저의 브라우저에서 실행하지 않고도 원하는 작업을 할 수 있습니다. 있습니다. 참입니다. 하지만 좋은 소식은 곧 PWA에 유사한 사용자 인터페이스를 만들 수 있습니다.

창 컨트롤 오버레이 구성요소

창 컨트롤 오버레이는 4가지 하위 기능으로 구성됩니다.

  1. 다음에서 "display_override" 필드의 "window-controls-overlay" 값 웹 앱 매니페스트에 있습니다
  2. CSS 환경 변수 titlebar-area-x, titlebar-area-y, titlebar-area-width, titlebar-area-height입니다.
  3. 이전에 독점적 CSS 속성인 -webkit-app-region를 웹 콘텐츠에서 드래그 가능한 영역을 정의하는 app-region 속성
  4. 창을 쿼리하고 이를 우회하는 메커니즘은 window.navigator의 멤버 windowControlsOverlay

창 컨트롤 오버레이란 무엇인가요?

제목 표시줄 영역은 창 컨트롤의 왼쪽 또는 오른쪽 공간 (즉, 최소화, 최대화, 닫기 등 버튼)을 사용할 수 있으며 종종 애플리케이션의 제목이 포함됩니다. 창문 컨트롤 오버레이를 사용하면 프로그레시브 웹 애플리케이션 (PWA)이 창 컨트롤이 포함된 작은 오버레이에 대한 기존 전체 너비 제목 표시줄을 반환합니다. 이렇게 하면 개발자가 이전에 브라우저가 제어하는 제목 표시줄 영역에 맞춤 콘텐츠를 배치할 수 있었습니다.

현재 상태

단계 상태
1. 설명 만들기 완전함
2. 사양의 초기 초안 만들기 완전함
3. 의견 수집 및 디자인 반복 진행 중
4. 오리진 트라이얼 완료
5. 출시 완료 (Chromium 104)

창 컨트롤 오버레이를 사용하는 방법

웹 앱 매니페스트에 window-controls-overlay 추가

프로그레시브 웹 앱은 웹 앱 매니페스트에서 기본 "display_override" 멤버로 "window-controls-overlay"를 설정합니다.

{
  "display_override": ["window-controls-overlay"]
}

창 컨트롤 오버레이는 다음 조건이 모두 충족되는 경우에만 표시됩니다.

  1. 앱이 브라우저에서 열리지 않고 별도의 PWA 창에서 열립니다.
  2. 매니페스트에는 "display_override": ["window-controls-overlay"]가 포함되어 있습니다. (다른 값은 합니다.
  3. PWA가 데스크톱 운영 체제에서 실행됩니다.
  4. 현재 출처가 PWA가 설치된 출처와 일치합니다.

그러면 왼쪽에 일반 창 컨트롤이 있는 빈 제목 표시줄 영역이나 할 수 있습니다.

<ph type="x-smartling-placeholder">
</ph> 왼쪽에 창 컨트롤이 있는 빈 제목 표시줄이 있는 앱 창 <ph type="x-smartling-placeholder">
</ph> 맞춤 콘텐츠를 위한 빈 제목 표시줄입니다.

제목 표시줄로 콘텐츠 이동

이제 제목 표시줄에 공간이 생겼으므로 제목 표시줄에 항목을 이동할 수 있습니다. 이 글에서는 Wikimedia Featured Content PWA를 빌드했습니다. 이 앱의 유용한 기능은 기사 제목 등이 있습니다. 검색 기능의 HTML은 다음과 같습니다.

<div class="search">
  <img src="logo.svg" alt="Wikimedia logo." width="32" height="32" />
  <label>
    <input type="search" />
    Search for words in articles
  </label>
</div>

div을 제목 표시줄 위로 이동하려면 CSS가 필요합니다.

.search {
  /* Make sure the `div` stays there, even when scrolling. */
  position: fixed;
  /**
   * Gradient, because why not. Endless opportunities.
   * The gradient ends in `#36c`, which happens to be the app's
   * `<meta name="theme-color" content="#36c">`.
   */
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
  /* Use the environment variable for the left anchoring with a fallback. */
  left: env(titlebar-area-x, 0);
  /* Use the environment variable for the top anchoring with a fallback. */
  top: env(titlebar-area-y, 0);
  /* Use the environment variable for setting the width with a fallback. */
  width: env(titlebar-area-width, 100%);
  /* Use the environment variable for setting the height with a fallback. */
  height: env(titlebar-area-height, 33px);
}

이 코드의 효과를 아래 스크린샷에서 확인할 수 있습니다. 제목 표시줄은 완벽하게 반응합니다. 날짜 PWA 창의 크기를 조절하면 제목 표시줄이 일반 HTML 콘텐츠로 구성된 것처럼 반응합니다. 실제로 그렇습니다.

<ph type="x-smartling-placeholder">
</ph> 제목 표시줄에 검색창이 있는 앱 창 <ph type="x-smartling-placeholder">
</ph> 새 제목 표시줄이 활성 상태이며 반응형입니다.

제목 표시줄의 어느 부분이 드래그 가능한지 결정

위의 스크린샷에서 모든 작업이 완료되었다고 나와 있지만 아직 완료되지 않은 상태입니다. PWA 창은 창 컨트롤 버튼이 드래그되지 않으므로 더 이상 드래그할 수 없음 (아주 작은 영역 제외) 제목 표시줄의 나머지 부분은 검색 위젯으로 구성됩니다. 다음을 사용하여 수정 값이 dragapp-region CSS 속성 구체적인 경우에는 input 요소 이외의 모든 항목을 드래그할 수 있습니다.

/* The entire search `div` is draggable… */
.search {
  -webkit-app-region: drag;
  app-region: drag;
}

/* …except for the `input`. */
input {
  -webkit-app-region: no-drag;
  app-region: no-drag;
}
드림

이 CSS를 사용하면 사용자는 평소와 같이 div, img 또는 label. input 요소만 대화형이므로 검색어를 입력할 수 있습니다.

특성 감지

창 컨트롤 오버레이 지원은 windowControlsOverlay:

if ('windowControlsOverlay' in navigator) {
  // Window Controls Overlay is supported.
}

windowControlsOverlay로 창 제어 영역 쿼리

지금까지의 코드에는 한 가지 문제가 있습니다. 일부 플랫폼에서 창 컨트롤이 오른쪽에 있고 나머지는 왼쪽에 있습니다. 더 심각한 문제는 '점 3개'로 Chrome 메뉴가 변경됩니다 플랫폼을 기반으로 광고를 게재할 수 있습니다. 즉, 선형 그라데이션 배경 이미지에 #131313maroon 또는 maroon#131313maroon에서 실행되도록 동적으로 조정되어 제목 표시줄의 maroon 배경 색상과 섞여서 <meta name="theme-color" content="maroon">입니다. 이렇게 하려면 navigator.windowControlsOverlay 속성의 getTitlebarAreaRect() API

if ('windowControlsOverlay' in navigator) {
  const { x } = navigator.windowControlsOverlay.getTitlebarAreaRect();
  // Window controls are on the right (like on Windows).
  // Chrome menu is left of the window controls.
  // [ windowControlsOverlay___________________ […] [_] [■] [X] ]
  if (x === 0) {
    div.classList.add('search-controls-right');
  }
  // Window controls are on the left (like on macOS).
  // Chrome menu is right of the window controls overlay.
  // [ [X] [_] [■] ___________________windowControlsOverlay [⋮] ]
  else {
    div.classList.add('search-controls-left');
  }
} else {
  // When running in a non-supporting browser tab.
  div.classList.add('search-controls-right');
}

이전과 같이 .search 클래스 CSS 규칙에 배경 이미지를 직접 사용하는 대신 수정된 코드는 이제 위 코드가 동적으로 설정하는 두 개의 클래스를 사용합니다.

/* For macOS: */
.search-controls-left {
  background-image: linear-gradient(90deg, #36c, 45%, #131313, 90%, #36c);
}

/* For Windows: */
.search-controls-right {
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
}

창 컨트롤 오버레이가 표시되는지 확인

모든 상황에서 창 컨트롤 오버레이가 제목 표시줄 영역에 표시되지는 않습니다. 하지만 따라서 창 컨트롤 오버레이 기능을 지원하지 않는 브라우저에는 문제의 PWA가 탭에서 실행될 때도 표시되지 않습니다. 이 상황을 감지하려면 다음과 같이 windowControlsOverlayvisible 속성을 쿼리합니다.

if (navigator.windowControlsOverlay.visible) {
  // The window controls overlay is visible in the title bar area.
}
드림

또는 JavaScript 및 CSS에서 display-mode 미디어 쿼리를 사용할 수도 있습니다.

// Create the query list.
const mediaQueryList = window.matchMedia('(display-mode: window-controls-overlay)');

// Define a callback function for the event listener.
function handleDisplayModeChange(mql) {
  // React on display mode changes.
}

// Run the display mode change handler once.
handleDisplayChange(mediaQueryList);

// Add the callback function as a listener to the query list.
mediaQueryList.addEventListener('change', handleDisplayModeChange);
@media (display-mode: window-controls-overlay) { 
  /* React on display mode changes. */ 
}

도형 변경사항 알림 받기

getTitlebarAreaRect()로 창 컨트롤 오버레이 영역을 쿼리하면 일회성으로 충분할 수 있습니다. 창 컨트롤의 위치에 따라 올바른 배경 이미지를 설정하는 등의 작업을 보다 세분화된 제어가 필요합니다 예를 들어, 가능한 사용 사례는 사용 가능한 공간에 따라 창 컨트롤 오버레이를 조정하고 창에서 바로 농담을 추가합니다. 컨트롤이 오버레이될 수 있습니다.

<ph type="x-smartling-placeholder">
</ph> 창 컨트롤은 짧은 텍스트를 포함하는 좁은 창의 영역을 오버레이합니다. <ph type="x-smartling-placeholder">
</ph> 제목 표시줄 컨트롤이 좁은 창에 맞게 조정됩니다.

다음을 구독하여 도형 변경사항에 대한 알림을 받을 수 있습니다. navigator.windowControlsOverlay.ongeometrychange 또는 geometrychange 이벤트. 이 이벤트는 창 컨트롤 오버레이가 표시될 때만 실행됩니다. navigator.windowControlsOverlay.visibletrue일 때입니다.

const debounce = (func, wait) => {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

if ('windowControlsOverlay' in navigator) {
  navigator.windowControlsOverlay.ongeometrychange = debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250);
}

ongeometrychange에 함수를 할당하는 대신 이벤트 리스너를 추가할 수도 있습니다. windowControlsOverlay입니다. 이 둘의 차이점은 다음 페이지에서 확인할 수 있습니다. MDN

navigator.windowControlsOverlay.addEventListener(
  'geometrychange',
  debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250),
);

탭 및 지원되지 않는 브라우저에서 실행할 때의 호환성

다음과 같은 두 가지 사례를 고려할 수 있습니다.

  • 앱이 창 컨트롤 오버레이를 지원하는 브라우저에서 실행되지만 브라우저 탭에서 앱이 사용되는 위치입니다
  • 창 컨트롤 오버레이를 지원하지 않는 브라우저에서 앱이 실행 중인 경우입니다.

두 경우 모두 창 컨트롤용으로 빌드된 HTML은 기본적으로 오버레이는 일반 HTML 콘텐츠 및 env() 변수처럼 인라인으로 표시됩니다. 대체 값 포지셔닝에 들어갑니다. 지원되는 브라우저에서도 오버레이의 visible 속성을 확인하여 창 컨트롤 오버레이에 지정된 HTML이 표시되며, false를 보고한 후 해당 HTML 콘텐츠를 숨깁니다.

<ph type="x-smartling-placeholder">
</ph> 브라우저 탭에서 실행되고 창 컨트롤 오버레이가 본문에 표시된 PWA <ph type="x-smartling-placeholder">
</ph> 제목 표시줄용 컨트롤은 이전 버전의 브라우저에서 본문에 쉽게 표시될 수 있습니다.

참고로, 지원되지 않는 브라우저는 "display_override" 웹 앱 매니페스트 속성을 전혀 인식하지 못하거나 "window-controls-overlay"이므로 대체 체인에 따라 다음 가능한 값을 사용합니다. 예: "standalone"

<ph type="x-smartling-placeholder">
</ph> 독립형 모드에서 실행되고 창 컨트롤 오버레이가 본문에 표시된 PWA. <ph type="x-smartling-placeholder">
</ph> 제목 표시줄용 컨트롤은 이전 버전의 브라우저에서 본문에 쉽게 표시될 수 있습니다.

UI 고려사항

유혹을 느낄 수 있지만 창 컨트롤 오버레이 영역에서 일반적인 드롭다운 메뉴를 만드는 것은 권장하지 않습니다. 이렇게 하면 macOS의 디자인 가이드라인 사용자가 메뉴 바 (시스템 제공 메뉴 및 메뉴 바 모두)를 기대하는 플랫폼 화면 상단에 맞춤 항목)이 표시됩니다.

앱이 전체 화면 환경을 제공하는 경우 적절한지 신중하게 고려하세요. 창 컨트롤 오버레이가 전체 화면 뷰의 일부가 되도록 해야 합니다. 잠재적으로 레이아웃을 재정렬하려는 경우 onfullscreenchange 드림 있습니다.

데모

실습에 활용할 수 있는 데모를 만들었습니다. 설치 및 설치되지 않은 상태일 수 있습니다. 대상 실제 창 컨트롤 오버레이 환경을 사용하려면 앱을 설치해야 합니다. 아래에서 예상 결과를 보여주는 스크린샷 2개를 확인할 수 있습니다. 이 앱의 소스 코드가 Glitch에서 제공됩니다.

<ph type="x-smartling-placeholder">
</ph> 창 컨트롤 오버레이가 있는 Wikimedia 추천 콘텐츠 데모 앱 <ph type="x-smartling-placeholder">
</ph> 데모 앱은 실험에 사용할 수 있습니다.

창 컨트롤 오버레이의 검색 기능은 완전히 작동합니다.

<ph type="x-smartling-placeholder">
</ph> 창 컨트롤 오버레이와 &#39;cleopa...&#39;를 적극적으로 검색하는 Wikimedia 추천 콘텐츠 데모 앱 &#39;클레오파트라&#39;라는 단어가 포함된 기사를 강조표시 <ph type="x-smartling-placeholder">
</ph> 창 컨트롤 오버레이를 사용하는 검색 기능

보안 고려사항

Chromium팀은 핵심 원칙을 사용하여 Window Controls Overlay API를 설계하고 구현했습니다. 강력한 웹 플랫폼 기능에 대한 액세스 제어에 정의됨(사용자 포함) 관리, 투명도 및 인체공학을 중시합니다.

스푸핑

사이트에서 제목 표시줄을 부분적으로 제어할 수 있게 되면 개발자가 이전에 신뢰할 수 있고 브라우저가 제어되는 리전이었습니다 현재 Chromium 브라우저에서는 독립형 모드는 최초 실행 시 왼쪽에 웹페이지 제목을 표시하는 제목 표시줄을 포함합니다. 오른쪽에 페이지의 출처('설정 및 기타 정보' 버튼 및 창 제어). 몇 초 후 원본 텍스트가 사라집니다. 브라우저가 오른쪽에서 왼쪽으로 설정되어 있는 경우 (RTL) 언어의 경우 원본 텍스트가 왼쪽에 오도록 이 레이아웃이 뒤집힙니다. 그러면 원점과 원점 사이의 패딩이 충분하지 않은 경우 원점을 스푸핑하는 창 컨트롤 오버레이 오버레이의 오른쪽 가장자리에 있습니다. 예를 들어 출처 'evil.ltd'가 신뢰할 수 있는 'google.com' 사이트를 사용하여 사용자가 출처를 신뢰할 수 있다고 믿도록 유도합니다. 계획은 사용자가 앱의 출처를 알고 앱의 출처가 있습니다. RTL로 구성된 브라우저의 경우 출처 오른쪽에 충분한 패딩이 있어야 합니다. 안전하지 않은 출처를 신뢰할 수 있는 출처에 추가하는 것을 방지하는 텍스트

디지털 지문 수집

창 컨트롤을 사용 설정하면 오버레이와 드래그 가능한 영역이 배치되지 않음 상당한 개인 정보 보호 문제를 야기할 수 있습니다. 하지만 윈도우 컨트롤 버튼의 크기와 위치가 익스플로이트가 있는 navigator.windowControlsOverlay.getTitlebarAreaRect() 메서드는 DOMRect를 반환합니다. 운영체제에 대한 정보를 보여주는 위치 및 측정기준이 확인할 수 있습니다 현재, 개발자들은 이미 Kubernetes에서 실행되는 OS를 사용자 에이전트 문자열에서 가져올 수 있지만, 디지털 지문 수집에 대한 우려로 인해 UA 문자열 고정 및 OS 버전 통합에 대한 논의 이 브라우저가 얼마나 자주 실행되는지 파악하기 위해 브라우저 커뮤니티 내에서 창의 크기가 현재 컨트롤에 따라 플랫폼에 따라 OS 버전 간에 상당히 안정적이므로 마이너 OS 버전을 관찰하는 데 유용합니다. 이 방법은 디지털 지문 수집 문제, 커스텀 API를 사용하는 설치된 PWA에만 적용됨 일반적인 브라우저 사용에는 적용되지 않습니다. 또한 navigator.windowControlsOverlay API를 다음 사용자에게 사용할 수 없습니다. PWA 내에 삽입된 iframe

PWA 내에서 다른 출처로 이동하면 일반적인 독립형으로 대체됩니다. 제목 표시줄(위 기준을 충족하고 창 컨트롤 오버레이로 실행되는 경우) 이는 다른 출처로 이동할 때 표시되는 검은색 막대를 수용하기 위함입니다. 후(After) 원래 원점으로 돌아가면 창 컨트롤 오버레이가 다시 사용됩니다.

<ph type="x-smartling-placeholder">
</ph> 외부 탐색을 위한 검은색 URL 표시줄 <ph type="x-smartling-placeholder">
</ph> 사용자가 다른 출발지로 이동하면 검은색 막대가 표시됩니다.

의견

Chromium팀에서 Window Controls Overlay API 사용 경험에 관한 의견을 듣고자 합니다.

API 설계에 대해 알려주세요.

API에서 예상대로 작동하지 않는 부분이 있나요? 또는 누락된 메서드가 있나요? 속성이 있나요? 보안에 대한 질문이나 의견이 있으면 무엇인가요? 해당 GitHub 저장소에서 사양 문제를 신고하거나 문제를 해결할 수 있습니다

구현 문제 신고

Chromium 구현에서 버그를 발견하셨나요? 아니면 구현이 사양과 다른가요? new.crbug.com에서 버그를 신고합니다. 최대한 자세하게 작성해 주시기 바랍니다. 간단한 재현 안내를 따르고 구성요소UI>Browser>WebAppInstalls를 입력합니다. 체크박스를 선택합니다. Glitch는 쉽고 빠른 재현을 공유하는 데 효과적입니다.

API 지원 표시

Window Controls Overlay API를 사용할 계획이신가요? 공개 지원은 Chromium팀에 도움이 됩니다 기능의 우선순위를 정하고 해당 기능을 지원하는 것이 얼마나 중요한지 다른 브라우저 공급업체에 보여줍니다.

@ChromiumDev로 트윗을 #WindowControlsOverlay 해시태그를 사용하고 어디서 어떻게 사용하는지 Google에 알려주세요.

유용한 링크

감사의 말씀

창 컨트롤 오버레이는 Microsoft Edge팀의 아만다 베이커 이 도움말은 Joe Medley가 검토했으며 케네스 로데 크리스티안센. 히어로 이미지 제공자 UnsplashSigmund