Sử dụng khu vực thanh tiêu đề bên cạnh các chế độ điều khiển cửa sổ để giúp PWA của bạn trông giống một ứng dụng hơn.
Nếu còn nhớ bài viết của tôi Làm cho PWA cảm giác như một ứng dụng, bạn có thể nhớ cách tôi đề cập đến việc tuỳ chỉnh thanh tiêu đề của ứng dụng làm để tạo trải nghiệm giống ứng dụng hơn. Dưới đây là một ví dụ về giao diện cho thấy ứng dụng Podcasts trên macOS.
Giờ đây, có thể bạn sẽ muốn phản đối bằng cách nói rằng Podcasts là một ứng dụng macOS dành riêng cho nền tảng này, không chạy trong trình duyệt và do đó có thể làm những gì nó muốn mà không phải chạy bởi quy tắc. Đúng, nhưng tin tốt là tính năng Lớp phủ chế độ điều khiển cửa sổ, vốn là chủ đề của trong bài viết này, chúng tôi sẽ sớm hỗ trợ bạn tạo giao diện người dùng tương tự cho PWA của bạn.
Thành phần lớp phủ chế độ điều khiển cửa sổ
Lớp phủ điều khiển cửa sổ bao gồm bốn tính năng phụ:
- Giá trị
"window-controls-overlay"
cho trường"display_override"
trong tệp kê khai ứng dụng web. - Các biến môi trường CSS
titlebar-area-x
,titlebar-area-y
,titlebar-area-width
vàtitlebar-area-height
. - Tiêu chuẩn hoá thuộc tính CSS thuộc quyền sở hữu riêng trước đây
-webkit-app-region
dưới dạng Thuộc tínhapp-region
để xác định các vùng có thể kéo trong nội dung web. - Cơ chế truy vấn và xử lý vùng kiểm soát cửa sổ thông qua
windowControlsOverlay
thành viên củawindow.navigator
.
Lớp phủ chế độ điều khiển cửa sổ là gì
Khu vực thanh tiêu đề là không gian ở bên trái hoặc bên phải của các thành phần điều khiển cửa sổ (tức là các nút để thu nhỏ, phóng to, đóng, v.v.) và thường chứa tiêu đề của ứng dụng. Cửa sổ Lớp phủ chế độ điều khiển giúp các ứng dụng web tiến bộ (PWA) mang lại trải nghiệm giống ứng dụng hơn bằng cách hoán đổi thanh tiêu đề hiện có trên toàn bộ chiều rộng cho lớp phủ nhỏ chứa các nút điều khiển cửa sổ. Điều này cho phép đặt nội dung tuỳ chỉnh vào khu vực mà trước đây là vùng thanh tiêu đề do trình duyệt kiểm soát.
Trạng thái hiện tại
Bước | Trạng thái |
---|---|
1. Tạo thông báo giải thích | Hoàn tất |
2. Tạo bản nháp ban đầu của thông số kỹ thuật | Hoàn tất |
3. Thu thập ý kiến phản hồi và lặp lại thiết kế | Đang tiến hành |
4. Bản dùng thử theo nguyên gốc | Hoàn thành |
5. Ra mắt | Hoàn tất (trong Chromium 104) |
Cách sử dụng lớp phủ chế độ điều khiển cửa sổ
Thêm window-controls-overlay
vào tệp kê khai ứng dụng web
Một ứng dụng web tiến bộ có thể chọn sử dụng lớp phủ kiểm soát cửa sổ bằng cách thêm
"window-controls-overlay"
là thành phần chính của "display_override"
trong tệp kê khai ứng dụng web:
{
"display_override": ["window-controls-overlay"]
}
Lớp phủ điều khiển cửa sổ sẽ chỉ hiển thị khi tất cả các điều kiện sau được đáp ứng:
- Ứng dụng không được mở trong trình duyệt mà mở trong một cửa sổ PWA riêng.
- Tệp kê khai bao gồm
"display_override": ["window-controls-overlay"]
. (Các giá trị khác là được phép sau đó). - PWA đang chạy trên hệ điều hành máy tính.
- Nguồn gốc hiện tại khớp với nguồn gốc mà PWA được cài đặt.
Kết quả là một vùng thanh tiêu đề trống với các nút điều khiển cửa sổ thông thường ở bên trái hoặc phải, tuỳ thuộc vào hệ điều hành.
Đang di chuyển nội dung vào thanh tiêu đề
Giờ đây khi đã có khoảng trống trong thanh tiêu đề, bạn có thể di chuyển nội dung nào đó tới đó. Đối với bài viết này, tôi tạo một ứng dụng web tiến bộ (PWA) Nội dung nổi bật Wikimedia. Một tính năng hữu ích của ứng dụng này là tìm kiếm các từ bằng tiêu đề bài viết. HTML cho tính năng tìm kiếm có dạng như sau:
<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>
Để di chuyển div
này lên thanh tiêu đề, cần có một số 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);
}
Bạn có thể thấy tác dụng của mã này trong ảnh chụp màn hình bên dưới. Thanh tiêu đề hoàn toàn phản hồi. Thời gian bạn đổi kích thước cửa sổ PWA, thanh tiêu đề sẽ phản ứng như thể nó bao gồm nội dung HTML thông thường, và trên thực tế, nó là như vậy.
Xác định các phần của thanh tiêu đề có thể kéo được
Mặc dù ảnh chụp màn hình ở trên cho thấy rằng bạn đã hoàn thành, nhưng bạn vẫn chưa hoàn tất. Cửa sổ PWA đang
không còn kéo được (ngoài một khu vực rất nhỏ) vì các nút điều khiển cửa sổ không kéo được
và phần còn lại của thanh tiêu đề bao gồm tiện ích tìm kiếm. Khắc phục vấn đề này bằng
thuộc tính CSS app-region
có giá trị drag
. Trong trường hợp cụ thể, bạn có thể
mọi thứ ngoài phần tử input
có thể kéo được.
/* 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;
}
Với CSS này vào đúng vị trí, người dùng có thể kéo cửa sổ ứng dụng như bình thường bằng cách kéo div
, img
hoặc label
. Chỉ có phần tử input
là có tính tương tác nên có thể nhập cụm từ tìm kiếm.
Phát hiện tính năng
Có thể phát hiện khả năng hỗ trợ Lớp phủ điều khiển cửa sổ bằng cách kiểm tra sự tồn tại của
windowControlsOverlay
:
if ('windowControlsOverlay' in navigator) {
// Window Controls Overlay is supported.
}
Truy vấn khu vực kiểm soát cửa sổ bằng windowControlsOverlay
Cho đến nay, mã có một vấn đề: trên một số nền tảng, các chế độ điều khiển cửa sổ nằm ở bên phải, trên
những người khác, họ ở bên trái. Tệ hơn là "ba dấu chấm" Trình đơn Chrome sẽ thay đổi
vị trí dựa trên nền tảng. Điều này có nghĩa là hình nền chuyển màu tuyến tính cần phải
được điều chỉnh một cách linh hoạt để chạy từ #131313
→maroon
hoặc maroon
→#131313
→maroon
, để
pha trộn với màu nền maroon
của thanh tiêu đề được xác định bằng
<meta name="theme-color" content="maroon">
. Có thể đạt được điều này bằng cách truy vấn
API getTitlebarAreaRect()
trên thuộc tính navigator.windowControlsOverlay
.
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');
}
Thay vì đặt hình nền trực tiếp trong các quy tắc CSS của lớp .search
(như trước đây),
mã được sửa đổi hiện sử dụng hai lớp mà mã ở trên đặt động.
/* 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);
}
Xác định xem lớp phủ điều khiển cửa sổ có hiển thị hay không
Không phải trường hợp nào lớp phủ điều khiển cửa sổ cũng xuất hiện trong khu vực thanh tiêu đề. Trong khi
tất nhiên sẽ không có trên các trình duyệt không hỗ trợ tính năng Lớp phủ điều khiển cửa sổ, tính năng này
cũng sẽ không xuất hiện khi PWA được đề cập chạy trong một thẻ. Để phát hiện tình huống này, bạn có thể
truy vấn thuộc tính visible
của windowControlsOverlay
:
if (navigator.windowControlsOverlay.visible) {
// The window controls overlay is visible in the title bar area.
}
Ngoài ra, bạn cũng có thể sử dụng truy vấn phương tiện display-mode
trong JavaScript và/hoặc CSS:
// 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. */
}
Nhận thông báo về các thay đổi về hình học
Chỉ cần truy vấn khu vực lớp phủ kiểm soát cửa sổ bằng getTitlebarAreaRect()
là bạn có thể thực hiện một lần
những việc như đặt hình nền chính xác dựa vào vị trí của các nút điều khiển cửa sổ, nhưng trong
các trường hợp khác, cần kiểm soát chi tiết hơn. Ví dụ: một trường hợp sử dụng có thể là
điều chỉnh lớp phủ điều khiển cửa sổ cho phù hợp với không gian có sẵn và để thêm một câu chuyện cười ngay trong cửa sổ
kiểm soát lớp phủ khi có đủ dung lượng.
Bạn có thể được thông báo về những thay đổi về hình học bằng cách đăng ký
navigator.windowControlsOverlay.ongeometrychange
hoặc bằng cách thiết lập trình nghe sự kiện cho
Sự kiện geometrychange
. Sự kiện này sẽ chỉ kích hoạt khi lớp phủ điều khiển cửa sổ hiển thị,
là khi navigator.windowControlsOverlay.visible
là true
.
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);
}
Thay vì chỉ định một hàm cho ongeometrychange
, bạn cũng có thể thêm một trình nghe sự kiện vào
windowControlsOverlay
như bên dưới. Bạn có thể đọc về sự khác biệt giữa hai công cụ này trên
MDN.
navigator.windowControlsOverlay.addEventListener(
'geometrychange',
debounce((e) => {
span.hidden = e.titlebarAreaRect.width < 800;
}, 250),
);
Khả năng tương thích khi chạy trong một thẻ và trên các trình duyệt không hỗ trợ
Có hai trường hợp có thể xảy ra để xem xét:
- Trường hợp ứng dụng đang chạy trong trình duyệt hỗ trợ Lớp phủ điều khiển cửa sổ, nhưng nơi ứng dụng được sử dụng trong thẻ trình duyệt.
- Trường hợp ứng dụng đang chạy trong trình duyệt không hỗ trợ Lớp phủ điều khiển cửa sổ.
Trong cả hai trường hợp, theo mặc định, HTML được xây dựng cho các cửa sổ điều khiển
lớp phủ sẽ hiển thị cùng dòng như nội dung HTML thông thường và các biến env()
giá trị dự phòng
sẽ thúc đẩy vị trí. Trên các trình duyệt hỗ trợ, bạn cũng có thể quyết định không hiển thị
HTML được chỉ định cho lớp phủ kiểm soát cửa sổ bằng cách kiểm tra thuộc tính visible
của lớp phủ và nếu
nó sẽ báo cáo false
, sau đó ẩn nội dung HTML đó.
Xin nhắc lại, những trình duyệt không hỗ trợ sẽ không xem xét
"display_override"
thuộc tính tệp kê khai ứng dụng web hoặc không nhận ra
"window-controls-overlay"
, do đó sử dụng giá trị có thể có tiếp theo theo chuỗi dự phòng,
ví dụ: "standalone"
.
Những điểm cần lưu ý về giao diện người dùng
Mặc dù điều này có thể hấp dẫn, nhưng bạn không nên tạo trình đơn thả xuống cổ điển trong khu vực Lớp phủ điều khiển cửa sổ. Làm như vậy sẽ vi phạm hướng dẫn thiết kế cho macOS, nền tảng mà người dùng mong đợi thanh trình đơn (cả nền tảng do hệ thống cung cấp và tuỳ chỉnh) ở đầu màn hình.
Nếu ứng dụng của bạn cung cấp trải nghiệm toàn màn hình, hãy cân nhắc kỹ xem việc đó có hợp lý hay không
cho Lớp phủ Điều khiển cửa sổ là một phần của chế độ xem toàn màn hình. Bạn có thể
muốn sắp xếp lại bố cục của mình khi
onfullscreenchange
kích hoạt sự kiện.
Bản minh hoạ
Tôi đã tạo một bản minh hoạ để bạn phát trong đó khác nhau giữa trình duyệt hỗ trợ và không hỗ trợ cũng như ở trạng thái đã cài đặt và chưa được cài đặt. Cho trải nghiệm Lớp phủ chế độ điều khiển cửa sổ thực tế, bạn cần cài đặt ứng dụng này. Bạn có thể thấy hai ảnh chụp màn hình về những việc sẽ xảy ra ở bên dưới. Chiến lược phát hành đĩa đơn mã nguồn của ứng dụng này hiện có trên Glitch.
Tính năng tìm kiếm trong lớp phủ điều khiển cửa sổ có đầy đủ chức năng:
Lưu ý về bảo mật
Nhóm Chromium đã thiết kế và triển khai API Lớp phủ chế độ điều khiển cửa sổ bằng các nguyên tắc cốt lõi được xác định trong Kiểm soát quyền truy cập vào các tính năng nền tảng web mạnh mẽ, bao gồm cả người dùng khả năng kiểm soát, tính minh bạch và tính công thái học.
Giả mạo
Việc cung cấp cho trang web quyền kiểm soát một phần thanh tiêu đề tạo điều kiện cho nhà phát triển giả mạo nội dung trước đây là một khu vực đáng tin cậy, do trình duyệt kiểm soát. Hiện tại, trong trình duyệt Chromium, các tính năng bao gồm thanh tiêu đề khi khởi chạy ban đầu hiển thị tiêu đề trang web ở bên trái, và nguồn gốc của trang ở bên phải (theo sau là nút "cài đặt và nội dung khác" và cửa sổ ). Sau vài giây, văn bản gốc sẽ biến mất. Nếu trình duyệt được đặt từ phải sang trái (RTL), bố cục này được lật để văn bản gốc nằm ở bên trái. Thao tác này sẽ mở ra các thành phần điều khiển cửa sổ sẽ phủ lên để giả mạo nguồn gốc nếu không có đủ khoảng đệm giữa nguồn gốc và cạnh phải của lớp phủ. Ví dụ: nguồn gốc "evil.ltd" có thể được thêm vào bằng "google.com", khiến người dùng tin rằng nguồn đó đáng tin cậy. Kế hoạch là duy trì để người dùng biết nguồn gốc của ứng dụng và có thể đảm bảo rằng ứng dụng đó khớp với kỳ vọng của họ. Đối với trình duyệt được định cấu hình theo cấu hình RTL, phải có đủ khoảng đệm ở bên phải nguồn gốc để ngăn trang web độc hại thêm nguồn gốc không an toàn đó với một nguồn đáng tin cậy.
Tạo vân tay số
Việc bật lớp phủ điều khiển cửa sổ và các vùng có thể kéo không được đặt ra
nhiều mối lo ngại đáng kể về quyền riêng tư ngoài việc phát hiện tính năng. Tuy nhiên, do
kích thước và vị trí khác nhau của các nút điều khiển cửa sổ khi hoạt động
hệ thống,
navigator.
phương thức trả về một DOMRect
có vị trí và kích thước tiết lộ thông tin về hệ điều hành dựa trên
mà trình duyệt đang chạy. Hiện tại, nhà phát triển đã có thể khám phá hệ điều hành
từ chuỗi tác nhân người dùng, nhưng do vấn đề về vân tay số, nên có
thảo luận về việc cố định chuỗi UA và hợp nhất các phiên bản hệ điều hành. Có một
trong cộng đồng trình duyệt thường xuyên tìm hiểu tần suất
kích thước của lớp phủ điều khiển cửa sổ thay đổi trên các nền tảng, khi
giả định rằng các giải pháp này khá ổn định trên các phiên bản hệ điều hành và do đó sẽ không
sẽ giúp ích cho việc quan sát các phiên bản hệ điều hành nhỏ. Mặc dù đây là một tiềm năng
vấn đề về tạo vân tay số, vấn đề này chỉ áp dụng cho những PWA đã cài đặt sử dụng
và không áp dụng cho việc sử dụng trình duyệt nói chung. Ngoài ra,
Không thể sử dụng API navigator.
cho
iframe được nhúng bên trong PWA.
Di chuyển
Việc chuyển sang một nguồn gốc khác trong PWA sẽ khiến PWA quay về chế độ độc lập thông thường thanh tiêu đề ngay cả khi thanh tiêu đề đáp ứng các tiêu chí nêu trên và được chạy bằng lớp phủ điều khiển cửa sổ. Điều này là để điều chỉnh cho phù hợp với thanh màu đen xuất hiện khi điều hướng đến một nguồn gốc khác. Sau khi quay lại điểm gốc ban đầu, lớp phủ điều khiển cửa sổ sẽ được sử dụng lại.
Phản hồi
Nhóm Chromium muốn biết ý kiến của bạn về trải nghiệm của bạn với API Lớp phủ chế độ điều khiển cửa sổ.
Cho chúng tôi biết về thiết kế API
Có điều gì về API không hoạt động như bạn mong đợi không? Hoặc có phương thức nào bị thiếu hoặc thuộc tính nào bạn cần để triển khai ý tưởng của mình? Có câu hỏi hoặc nhận xét về bảo mật mẫu? Báo cáo vấn đề về thông số kỹ thuật trên kho lưu trữ GitHub tương ứng hoặc thêm ý kiến của bạn vào một vấn đề hiện tại.
Báo cáo sự cố về triển khai
Bạn có phát hiện lỗi trong quá trình triển khai Chromium không? Hay cách triển khai có khác với thông số kỹ thuật không?
Báo cáo lỗi tại new.crbug.com. Hãy nhớ cung cấp càng nhiều thông tin chi tiết càng tốt,
các hướng dẫn đơn giản để tái tạo và nhập UI>Browser>WebAppInstalls
vào phần Components (Thành phần)
. Glitch rất hữu ích khi chia sẻ các bản dựng lại nhanh chóng và dễ dàng.
Hiện thông tin hỗ trợ về API này
Bạn có dự định sử dụng API Lớp phủ chế độ điều khiển cửa sổ không? Sự hỗ trợ công khai của bạn giúp ích cho nhóm Chromium để ưu tiên các tính năng và cho các nhà cung cấp trình duyệt khác thấy tầm quan trọng của việc hỗ trợ các tính năng đó.
Gửi tweet tới @ChromiumDev kèm theo
#WindowControlsOverlay
và cho chúng tôi biết bạn đang sử dụng hashtag đó ở đâu và như thế nào.
Các đường liên kết hữu ích
- Người giải thích
- Bản nháp quy cách
- Lỗi Chromium
- Mục Trạng thái của Nền tảng Chrome
- Bài đánh giá TAG
- Tài liệu liên quan của Microsoft Edge
Xác nhận
Lớp phủ điều khiển cửa sổ đã được triển khai và chỉ định bởi Amanda Baker thuộc nhóm Microsoft Edge. Bài viết này do Joe Medley xem xét và Kenneth Rohde Christiansen. Hình ảnh chính của Sigmund trên Unsplash.