Cửa sổ bật lên = gợi ý

Ngày xuất bản: 26 tháng 2 năm 2025

Chrome 133 xây dựng dựa trên tính năng cửa sổ bật lên hiện có bằng cách giới thiệu một chế độ mới: popover="hint". Chế độ do trình duyệt quản lý này cho phép một ngữ cảnh xếp chồng mới giúp đơn giản hoá việc tạo chú giải công cụ và các phần tử nổi tạm thời tương tự. Điều này giúp giảm bớt công sức của nhà phát triển trong khi vẫn duy trì tính linh hoạt trong thiết kế.

Giới thiệu và quá trình phát triển

Popover API, được giới thiệu trong Chrome 114, cho phép bạn tạo giao diện người dùng nổi dễ tiếp cận, chẳng hạn như trình đơn và chú giải công cụ. Theo mặc định, popover="auto" sẽ xử lý chức năng đóng nhẹ và quản lý tiêu điểm cho bạn mà không cần thêm tập lệnh, như đã đề cập trong phần Giới thiệu về Popover API. Khi mở một cửa sổ bật lên popover="auto", tất cả các cửa sổ bật lên không phải là cửa sổ gốc khác có popover="auto" sẽ bị đóng, tạo ra một API tiện lợi thực hiện việc hợp lý nhất.

Cửa sổ bật lên đóng các cửa sổ bật lên khác

<div id="p1" popover>First Popover</div>
<button popovertarget="p1">Open popover 1</button>
<div id="p2" popover>Second Popover</div>
<button popovertarget="p2">Open popover 2</button>

Trong ví dụ này, việc mở trình đơn bật lên 2 sẽ đóng trình đơn bật lên 1, vì popover="auto" chỉ cho phép mở một trình đơn bật lên như vậy tại một thời điểm.

Mặc dù hành vi này hoạt động tốt cho trình đơn và hộp thoại, nhưng có thể gây ra vấn đề khi nhiều loại giao diện người dùng nổi cần cùng tồn tại. Ví dụ: một trình đơn và chú giải công cụ đều sử dụng popover="auto" có thể xung đột, trong đó việc mở chú giải công cụ sẽ đóng trình đơn. Đây có vẻ là một trường hợp không phổ biến, nhưng lại xuất hiện rất nhiều trong giao diện người dùng kiểu ứng dụng hiện đại. Ví dụ: các trình đơn trên tiêu đề của github.com sử dụng cửa sổ bật lên cho cả trình đơn và chú giải công cụ, cho phép cả hai hiển thị cùng lúc trong một số điều kiện nhất định:

Một trình đơn đang mở.
Trình đơn GitHub.

Một cách để giải quyết vấn đề này là sử dụng popover="manual" cho các phần tử chú giải công cụ, cho phép kiểm soát toàn bộ cửa sổ bật lên bằng tập lệnh. Tuy nhiên, việc này đòi hỏi bạn phải triển khai lại hành vi xếp chồng, đóng nhẹ và quản lý tiêu điểm – chính xác là những tác vụ mà Popover API được thiết kế để xử lý. Điều này đã thôi thúc chúng tôi tìm hiểu các cách mở rộng API để cung cấp chức năng còn thiếu này.

Thông qua nghiên cứu dành cho nhà phát triển, chúng tôi đã xác định được hai ngữ cảnh xếp chồng phổ biến:

  • Giao diện người dùng ổn định: Ví dụ: trình đơn và hộp thoại.
  • Giao diện người dùng tạm thời: Ví dụ: thẻ di chuột và chú giải công cụ.

Để đáp ứng cả hai yêu cầu, popover="hint" giới thiệu một ngăn xếp thứ hai, khác với popover="auto", đảm bảo rằng các trình đơn vẫn mở ngay cả khi chú giải công cụ xuất hiện. Thay vì giới thiệu nhiều ngữ cảnh xếp chồng cho các loại giao diện người dùng khác nhau (về cơ bản sẽ phát minh lại z-index), phương pháp này giúp đơn giản hoá mọi thứ bằng cách chỉ xác định hai danh mục rộng: giao diện người dùng ổn định (auto) và giao diện người dùng tạm thời (hint). Điều này tạo ra sự cân bằng giữa tính linh hoạt và tránh tái xuất hiện các vấn đề tương tự mà bạn gặp phải trước khi sử dụng cửa sổ bật lên.

Hành vi của giá trị mới

Cả popover="auto"popover="hint" đều hỗ trợ tính năng đóng nhẹ, nghĩa là các cửa sổ này sẽ tự động đóng khi người dùng nhấp vào bên ngoài hoặc nhấn phím Esc trên bàn phím. Về mặt này, cả hai kiểu đều giống hệt nhau.

Khi nói đến việc buộc ẩn các cửa sổ bật lên khác, popover="auto" sẽ đóng tất cả các cửa sổ bật lên autohint khác khi mở, đảm bảo rằng chỉ một cửa sổ bật lên như vậy hoạt động cùng một lúc (ngoại lệ duy nhất ở đây là các cửa sổ bật lên lồng nhau, được giải thích bên dưới). Mặt khác, popover="hint" chỉ buộc ẩn các cửa sổ bật lên hint khác, cho phép trình đơn và chú giải công cụ vẫn mở và tồn tại cùng nhau.

Điểm khác biệt lớn nhất giữa hai loại này là hành vi lồng ghép. popover="auto" hỗ trợ tính năng lồng, cho phép một cửa sổ bật lên con vẫn mở trong một cửa sổ bật lên mẹ khác. popover="hint" có một hành vi lồng ghép đặc biệt, đó là nơi các "ngăn xếp" riêng biệt xuất hiện. Khi một cửa sổ bật lên hint nằm bên trong một cửa sổ bật lên auto, cửa sổ bật lên đó sẽ tham gia ngăn xếp auto để duy trì tính năng nhóm theo ngữ cảnh, nghĩa là cửa sổ bật lên đó sẽ vẫn mở cho đến khi các cửa sổ bật lên auto hoặc hint khác buộc cửa sổ bật lên đó ẩn. Điều này mang lại hành vi trực quan, trong đó chú giải công cụ không làm gián đoạn các trình đơn hoặc cửa sổ bật lên khác.

Cuối cùng, đối với các trường hợp sử dụng rất khác nhau, luôn có popover="manual" không đi kèm với bất kỳ hành vi nào trong số này, cho phép bạn xác định chức năng và hành vi chính xác mà bạn cần.

popover="auto" popover="hint" popover="manual"
Bỏ qua ánh sáng Không
Buộc ẩn: autohint không liên quan hint không liên quan Nothing
Lồng ghép: Đặc biệt (đã mô tả trước đó) Không áp dụng – không có tính năng đóng bằng đèn

Kích hoạt khi di chuột

Một mẫu trải nghiệm người dùng phổ biến là chú giải công cụ và thẻ di chuột được kích hoạt bằng thao tác di chuột. Khi bạn di chuột qua một phần tử mà bạn quan tâm trong một khoảng thời gian, thẻ di chuột sẽ xuất hiện. Hiện tại, hành vi đó cần được triển khai thông qua JavaScript, chẳng hạn như bằng cách thêm trình nghe cho các sự kiện mouseentermouseleave. Tuy nhiên, một API khác đang được phát triển sẽ giúp tính năng kích hoạt bằng thao tác di chuột trở nên khai báo: Interest Invokers API.

API này vẫn đang trong quá trình phát triển, nhưng ý tưởng chung là thêm một thuộc tính có tên là interesttarget vào nhiều loại phần tử, nhờ đó các phần tử này có hành vi kích hoạt khi di chuột:

<a interesttarget="my-hovercard" href="...">
  Hover to show the hovercard
</a>
<span popover="hint" id="my-hovercard">
  This is the hovercard
</span> 

Với HTML trước đó, khi di chuột qua đường liên kết <a>, cửa sổ bật lên my-hovercard sẽ tự động hiển thị. Việc di chuyển con trỏ ra khỏi phần tử đó sẽ ẩn cửa sổ bật lên. Tất cả đều không cần JavaScript!

Ví dụ

<button>An interesting button</button>
<div popover="hint">More info about the button</div>
[popover] {
  margin: 0;
  inset: auto;
  position-area: bottom right;
}
const button = document.querySelector('button');
const popover = document.querySelector('[popover]');

button.onmouseenter = () => {
  setTimeout(() => {
    popover.showPopover({source: button});
  }, 500);
}

button.onmouseleave = () => {
  setTimeout(() => {
    popover.hidePopover();
  }, 500);
}
Nút có chú giải công cụ.
Thử trực tiếp tính năng này.

Ví dụ này sử dụng popover="hint" để tạo một chú giải công cụ cơ bản, cung cấp thêm thông tin về nút khi di chuột qua nút đó. Thao tác kích hoạt khi di chuột được cung cấp bởi trình xử lý sự kiện cho mouseentermouseleave với độ trễ đơn giản là 0,5 giây. Lưu ý rằng có một số chi tiết không được xử lý trong ví dụ này:

  1. Việc di chuột qua cửa sổ bật lên không ngăn việc di chuột ra khỏi phần tử kích hoạt đóng cửa sổ bật lên. Ví dụ: bạn không thể sao chép hoặc dán văn bản từ cửa sổ bật lên.
  2. Không có "độ trễ": chỉ cần di chuột qua nút trong một phần nhỏ giây là đủ để kích hoạt cửa sổ bật lên, ngay cả khi nút đó bị di chuột ra nhanh trước khi hết thời gian trễ. Trong trường hợp này, chú giải công cụ "nhấp nháy" mở và đóng nhanh chóng.
  3. Không thể truy cập vào ví dụ này: mọi người dùng không sử dụng chuột đều không thể truy cập vào nội dung của chú giải công cụ.

Bạn có thể khắc phục những thiếu sót này bằng cách thêm JavaScript. Ví dụ: bạn cần thêm focus (hoặc có thể là trình xử lý sự kiện keydownkeyup)) để hỗ trợ việc kích hoạt cửa sổ bật lên dựa trên bàn phím. Để biết nội dung giải thích về những điều cần xử lý chính xác để đảm bảo có thể truy cập vào chú giải công cụ, hãy xem bài đăng tuyệt vời này trên blog của Sarah Higley. Tất cả các vấn đề này (và nhiều vấn đề khác) sẽ được Interest Invokers API tự động xử lý theo cách khai báo.

Tìm hiểu thêm

Hãy xem nội dung giải thích về tính năng hoặc thông số kỹ thuật HTML để biết thêm thông tin chi tiết.