Tính năng mới trong giao diện người dùng trên web: Tóm tắt I/O 2025

Xuất bản: Ngày 14 tháng 8 năm 2025

Khi mùa sự kiện Google I/O kết thúc, bài đăng này sẽ tóm tắt những điểm nổi bật nhất về CSS và Giao diện người dùng web được chia sẻ tại các sự kiện của chúng tôi trong năm nay.

Các tính năng cực kỳ mạnh mẽ mà trước đây nhà phát triển chỉ dám mơ ước đã xuất hiện trong các trình duyệt và đang đạt được khả năng tương thích trên nhiều trình duyệt nhanh hơn bao giờ hết. Tuy nhiên, mặc dù có tiến bộ này, một số mẫu giao diện người dùng phổ biến nhất vẫn khó triển khai một cách chính xác một cách đáng ngạc nhiên. Bạn thường phải dựa vào các khung JavaScript, các thủ thuật CSS phức tạp và vô số mã tuỳ chỉnh để tạo các thành phần có vẻ đơn giản hơn.

Nhóm Chrome, cùng với các nhà cung cấp trình duyệt khác, các tổ chức tiêu chuẩn như CSSWG và WHATWG, cũng như các nhóm cộng đồng như Open UI, đang tập trung vào việc triển khai những mẫu giao diện người dùng cơ bản này một cách thực sự đơn giản.

Trình đơn chọn có thể tuỳ chỉnh

Phần tử <select> là phần tử cần thiết cho các biểu mẫu, nhưng cấu trúc bên trong của phần tử này từ trước đến nay vẫn được trình duyệt che chắn, khiến việc tạo kiểu CSS nhất quán và toàn diện gần như không thể. Để tạo một <select> tốt hơn, bạn cần hiểu rõ các khối xây dựng của thành phần này, đó là Popover API và CSS Anchor Positioning API.

Popover API: Hiện đã có trong Baseline

Trình đơn thả xuống tuỳ chỉnh cần có một hộp tuỳ chọn nổi xuất hiện phía trên tất cả các phần tử giao diện người dùng khác, dễ dàng đóng và quản lý tiêu điểm một cách chính xác. Popover API xử lý tất cả những điều này và kể từ năm nay, API này đã đạt được trạng thái Mới có sẵn trong Baseline, nghĩa là API này ổn định trong mọi trình duyệt chính.

Browser Support

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 125.
  • Safari: 17.

Source

Để tạo một cửa sổ bật lên, bạn cần có 2 phần: một phần tử kích hoạt (chẳng hạn như <button>) và chính phần tử cửa sổ bật lên. Kết nối các thành phần này bằng cách đặt cho cửa sổ bật lên một thuộc tính id[popover], sau đó tham chiếu id đó trong thuộc tính [popovertarget] của nút.

Popover API quản lý toàn bộ vòng đời của phần tử, cung cấp:

  • Kết xuất lớp trên cùng: Không còn phải lo lắng về chỉ mục z nữa.
  • Khả năng đóng nhanh không bắt buộc: Đóng khi người dùng nhấp vào bên ngoài vùng cửa sổ bật lên.
  • Quản lý tiêu điểm tự động: Trình duyệt xử lý thao tác bằng phím tab để di chuyển vào và ra khỏi cửa sổ bật lên.
  • Các liên kết có thể truy cập: Mô hình tương tác cơ bản được xử lý theo cách tự nhiên.

Phần tử <dialog> được nâng cấp

Mặc dù cửa sổ bật lên rất hữu ích, nhưng không phải lúc nào đây cũng là lựa chọn phù hợp. Ví dụ: trong các hoạt động tương tác chặn trang yêu cầu người dùng phản hồi, phương thức <dialog> phù hợp hơn.

Trước đây, <dialog> thiếu một số tiện ích của [popover], nhưng điều đó đang thay đổi. Với thuộc tính closedby="any" mới, hộp thoại phương thức hiện hỗ trợ chức năng tắt nhanh, đóng khi người dùng nhấp vào bên ngoài hoặc nhấn phím Escape.

Browser Support

  • Chrome: 134.
  • Edge: 134.
  • Firefox Technology Preview: supported.
  • Safari: not supported.

Source

Ngoài ra, trình gọi lệnh ([command][commandfor]) cung cấp một cách thức khai báo, không cần JavaScript để kết nối một nút với một hành động, chẳng hạn như mở một hộp thoại bằng command="show-modal".

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: behind a flag.
  • Safari Technology Preview: supported.

Source

<dialog> Phần tử + closedby=any + lệnh gọi lệnh [popover] thuộc tính
Mục đích sử dụng chính Tương tác phương thức (thoả thuận người dùng, hướng dẫn từng bước, v.v.) Giao diện người dùng tạm thời (trình đơn, chú thích, thẻ, cảnh báo dạng thông báo)
Có thể đóng bằng cách nhấn vào vùng sáng
Traps Focus Không
Trang trơ Không
Kích hoạt khai báo
Triển khai Phần tử Thuộc tính
Kết xuất ở lớp trên cùng
Có thể tạo kiểu hoàn toàn

Vị trí điểm neo CSS

Sau khi xuất hiện, cửa sổ bật lên cần được đặt tương ứng với phần tử đã mở cửa sổ đó. Việc tính toán thủ công bằng JavaScript rất dễ bị lỗi và có thể ảnh hưởng đến hiệu suất.

Từ Chrome 125, bạn có thể sử dụng CSS Anchor Positioning API. Khả năng mới này sẽ khai báo để liên kết một phần tử với một phần tử khác, tự động xử lý việc định vị lại khi phần tử đó gần đến cạnh màn hình. Tính năng này là một phần của Interop 2025, một sáng kiến trên nhiều trình duyệt nhằm triển khai các tính năng được yêu cầu nhiều nhất. Điều này có nghĩa là chúng ta có thể kỳ vọng tính năng này sẽ có trong tất cả các trình duyệt chính vào cuối năm 2025.

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: not supported.
  • Safari: not supported.

Source

Minh hoạ cách các phần khác nhau của tính năng định vị phần tử cố định tương quan với mã, chẳng hạn như cạnh trên cùng của phần tử cố định là anchor(top) và cạnh bên phải là anchor(right).
Sơ đồ minh hoạ cách định vị điểm neo CSS.

Mặc dù bạn có thể liên kết rõ ràng các phần tử bằng thuộc tính anchor-nameposition-anchor, nhưng bản cập nhật trong quy cách và trong Chrome 133 sẽ tạo mối quan hệ ngầm ẩn giữa <popover><button> đang gọi của phần tử đó. Điều này giúp đơn giản hoá đáng kể mã và có nghĩa là giờ đây, bạn có thể đặt vị trí cho cửa sổ bật lên chỉ bằng một dòng CSS, chẳng hạn như: position-area: bottom span-left.

Công cụ liên kết trên chrome.dev cho bạn biết cách sử dụng position-area để có được vị trí mà bạn có thể muốn:

Tiến thêm một bước nữa bằng cách để trình duyệt định vị lại các điểm neo, ngăn chúng bị lệch khỏi màn hình, bằng cách xác định các phương án dự phòng bằng position-try-fallbacks. Bản minh hoạ sau đây cho thấy một cửa sổ bật lên sử dụng thuộc tính này cho logic định vị lại tích hợp:


<select> có thể tuỳ chỉnh hoàn toàn

Với những khối xây dựng đó trong các phiên bản trước, kiểu dáng gốc của web cho các phần tử <select> cuối cùng đã xuất hiện trong Chrome 134. Trong đó có thuộc tính appearance mới, các phần tử giả mới và phần tử <selectedcontent>.

Để mở khoá chế độ tuỳ chỉnh, hãy áp dụng appearance: base-select; cho phần tử <select> và phần tử giả ::picker(select) mới của phần tử đó. Phần tử này nhắm đến danh sách thả xuống gồm các lựa chọn. Điều này cho phép bạn sử dụng các phần nội bộ mới để tạo kiểu, bao gồm:

  • <selectedcontent>: Biểu thị nội dung của lựa chọn đã chọn xuất hiện trong nút.
  • ::picker-icon: Biểu tượng mũi tên thả xuống
  • <option>:checked::checkmark: Để tạo kiểu cho lựa chọn đã chọn và chỉ báo dấu kiểm của lựa chọn đó
Sơ đồ minh hoạ các phần mới của select, chẳng hạn như ::picker-icon, selectedcontent và ::picker(select).
Các phần của thành phần chọn có thể tuỳ chỉnh.

Điều này cho phép nội dung phong phú trong các lựa chọn và kiểm soát chặt chẽ việc hiển thị. Ví dụ: bạn có thể hiện biểu tượng và phụ đề trong danh sách lựa chọn nhưng ẩn chúng ở trạng thái đóng bằng cách sử dụng display: none trong selectedcontent.


Điều tuyệt vời nhất là bạn có thể tăng cường API này một cách liên tục. Trong những trình duyệt không hỗ trợ các tính năng này, người dùng vẫn sẽ nhận được một lựa chọn gốc trên web hoạt động bình thường. Bạn sẽ có được giao diện tuỳ chỉnh trong khi vẫn giữ được khả năng hỗ trợ tiếp cận, thao tác bằng bàn phím và tích hợp biểu mẫu sẵn có của phần tử chọn gốc trên web.

Các quảng cáo dạng băng chuyền

Băng chuyền xuất hiện ở mọi nơi trên web, chứ không chỉ trong các phần nổi bật. Điều này bao gồm nội dung có thể cuộn theo chiều ngang trong bố cục chặt chẽ, chẳng hạn như giao diện người dùng của cửa hàng ứng dụng. Tuy nhiên, việc tạo băng chuyền trên web vẫn là một thách thức, với nhiều yếu tố cần cân nhắc như quản lý trạng thái, hiện tượng giật khi cuộn, tính tương tác và khả năng hỗ trợ tiếp cận. Nhưng nếu bạn nghĩ về điều đó, thì băng chuyền về cơ bản là các vùng cuộn đẹp mắt với các khả năng tương tác bổ sung trên giao diện người dùng.

Làm quen với thành phần cuộn

Để tạo một băng chuyền, bạn bắt đầu bằng một danh sách các mục tràn ra ngoài vùng chứa. Để ẩn thanh cuộn ngang trong khi vẫn giữ cho nội dung có thể cuộn, hãy sử dụng scrollbar-width: none. Ngoài ra, để tạo cảm giác "nhanh" cho trình cuộn, hãy áp dụng scroll-snap-typescroll-snap-align. Điều này đảm bảo rằng các mục sẽ chụp nhanh vào đúng vị trí khi người dùng cuộn.

Trước và sau với ::scroll-button

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: not supported.
  • Safari: not supported.

Source

Phần tử giả ::scroll-button() mới (xuất hiện trong Chrome 135) hướng dẫn trình duyệt tạo các nút "tiếp theo" và "trước đó" có trạng thái và dễ tiếp cận. Trình duyệt tự động xử lý đúng vai trò ARIA, thứ tự thẻ và thậm chí vô hiệu hoá các nút khi bạn đến đầu hoặc cuối – tất cả đều không cần thêm JavaScript.

Để khởi tạo các nút cuộn, hãy cung cấp cho chúng nội dung và nhãn hỗ trợ tiếp cận, như sau:

.carousel {

  &::scroll-button(left) {
    content: "⬅" / "Scroll Previous";
  }
  
  &::scroll-button(right) {
    content: "⮕" / "Scroll Next";
  }
}
hình ảnh băng chuyền có nút trái và phải
Ảnh chụp màn hình của nút cuộn đơn giản trong bản minh hoạ trước đó.

Tạo kiểu cho các nút này và đặt vị trí của chúng so với băng chuyền gốc bằng tính năng định vị điểm neo CSS. Đây là phương pháp được đề xuất để thực hiện việc này.

Điều hướng trực tiếp bằng ::scroll-marker

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: not supported.
  • Safari: not supported.

Source

Đối với chỉ báo dấu chấm hoặc hình thu nhỏ, các phần tử giả ::scroll-marker::scroll-marker-group sẽ liên kết trực tiếp các điểm đánh dấu điều hướng với các mục trong vùng chứa có thể cuộn. Trình duyệt coi nhóm này như một tablist và xử lý thao tác điều hướng bằng bàn phím.

Tương tự như nút cuộn, hãy bắt đầu các điểm đánh dấu cuộn bằng cách chọn sử dụng thuộc tính content và cung cấp một nhãn hỗ trợ tiếp cận. Trong ví dụ sau, một thuộc tính dữ liệu được dùng để đặt nhãn cho điểm đánh dấu cuộn. Ngoài ra, hãy đặt các điểm đánh dấu cuộn trong ::scroll-marker-group bằng cách sử dụng thuộc tính scroll-marker-group. Cuối cùng, hãy tạo kiểu cho điểm đánh dấu đang hoạt động bằng cách sử dụng giả lớp :target-current mới. Sau đây là ví dụ về giao diện của một băng chuyền cơ bản:

.carousel {
  scroll-marker-group: after;
  
  > li::scroll-marker {
    content: ''/ attr(data-name);
  }

  > li::scroll-marker:target-current {
    background: blue;
  }
}
hình ảnh băng chuyền có chỉ báo dấu chấm ở dưới cùng
Ảnh chụp màn hình của điểm đánh dấu cuộn cơ bản trong bản minh hoạ trước đó.

Truy vấn trạng thái cuộn

Các tính năng CSS mới liên quan đến thao tác cuộn giúp bạn tạo băng chuyền linh động và có tính tương tác cao hơn. truy vấn trạng thái cuộn là một truy vấn nội dung nghe nhìn mới áp dụng dựa trên trạng thái của trình cuộn. Có 3 loại truy vấn trạng thái cuộn mà bạn có thể truy cập bằng cách sử dụng scroll-state() trong câu lệnh @container. Các loại chiến dịch phụ đó là:

  • scroll-state(snapped): Khớp khi một phần tử ở vị trí "đã điều chỉnh". Trong băng chuyền, đó là khi mục được cố định ở giữa băng chuyền.
  • scroll-state(stuck): Tạo kiểu cho một phần tử, chẳng hạn như tiêu đề, khi phần tử mẹ trở nên cố định.
  • scroll-state(scrollable): Thêm các chỉ báo trực quan (chẳng hạn như hiệu ứng mờ) để cho biết có thêm nội dung cần cuộn đến.

Tổng hợp kiến thức đã học

Sự kết hợp giữa các thành phần cơ bản mới của băng chuyền CSS, các truy vấn trạng thái cuộn và tính năng định vị điểm neo giúp bạn dễ dàng tạo các băng chuyền tuỳ chỉnh và có tính tương tác. Tiến thêm một bước bằng cách kết hợp ảnh động dựa trên thao tác cuộn để liên kết ảnh động trực tiếp với vị trí cuộn, tạo ra các hiệu ứng hiệu suất cao như thu phóng và làm mờ các mục khi chúng cuộn vào chế độ xem. Những ảnh động này chạy trên luồng chính, mang lại trải nghiệm mượt mà.


Băng chuyền tương tác này kết hợp các truy vấn scroll-state(), ::scroll-button, ::scroll-marker, tính năng định vị điểm neo CSS và :target-current.

Ngoài ra, bạn có thể sử dụng một thuộc tính mới có tên là interactivity để giúp người dùng tập trung vào nội dung đang hoạt động. interactivity: inert cho phép người dùng áp dụng tính trơ bằng CSS, khiến các mục trong băng chuyền ngoài màn hình không thể lấy tiêu điểm và xoá các mục đó khỏi cây hỗ trợ tiếp cận.

Tìm hiểu thêm về Băng chuyền CSS.

Thẻ thông tin tương tác

Thẻ thông tin (các cửa sổ bật lên đa dạng nội dung xuất hiện khi bạn di chuột lên tên người dùng hoặc đường liên kết) rất hữu ích nhưng lại khó xây dựng một cách chính xác. Để xử lý đúng độ trễ, sự kiện và hỗ trợ nhiều thiết bị, bạn có thể cần một nhóm chuyên trách trong nhiều tháng. Nhưng chúng tôi đang phát triển một giải pháp khai báo mới có thể giải quyết vấn đề này một lần và mãi mãi.

Chú thích bật lên dựa trên mối quan tâm có [interestfor]

Điều kỳ diệu cốt lõi đằng sau thẻ di chuột khai báo là thuộc tính [interestfor]. Tính năng sắp ra mắt này mang đến sức mạnh của cửa sổ bật lên nhưng kích hoạt chúng dựa trên "mối quan tâm" của người dùng. Ví dụ: sự quan tâm của người dùng trên một thiết bị trỏ sẽ là con trỏ di chuột, điều hướng bằng phím tab bằng bàn phím hoặc nhấn và giữ hoặc nhấn trên màn hình cảm ứng. Vấn đề về hoạt động tương tác trên thiết bị di động vẫn chưa được giải quyết.

Để chuyển đổi một cửa sổ bật lên dựa trên lượt nhấp thành một cửa sổ bật lên dựa trên mối quan tâm, hãy tạo một phần tử gọi. Phần tử này có thể là <button> hoặc <a> và đặt cho phần tử đó một thuộc tính [interestfor] bằng với id của phần tử [popover]. Trong HTML, mã này có dạng như sau:

<button interestfor="profile-callout">
  ...
</button>

<div id="profile-callout" popover>
 ...
</div>

Trình duyệt xử lý tất cả logic sự kiện phức tạp, bao gồm:

  • Sự kiện nhập và thoát: Di chuột trên các thiết bị có con trỏ chính xác, điều hướng bằng phím tab trên bàn phím, nhấn và giữ hoặc chạm trên các thiết bị có con trỏ thô.
  • Độ trễ của sự kiện: Kiểm soát độ trễ khi vào và thoát bằng một thuộc tính CSS duy nhất.

Tính năng này hỗ trợ các tính năng khác của cửa sổ bật lên, chẳng hạn như hỗ trợ lớp trên cùng, trong đó cửa sổ bật lên hiển thị trên một lớp mới phía trên phần còn lại của cây DOM. Các liên kết thành phần ngữ nghĩa và mô hình cây hỗ trợ tiếp cận cơ bản được xử lý một cách tự nhiên.

Tạo kiểu cho các thành phần kích hoạt mối quan tâm

Trình kích hoạt mối quan tâm có một số chức năng mới. Một trong số đó là khả năng kiểm soát độ trễ khi vào và thoát bằng cách sử dụng một thuộc tính CSS: interest-target-delay. Khả năng còn lại là tạo kiểu cho phần tử gọi dựa trên việc phần tử đó có được quan tâm hay không, bằng cách sử dụng giả lớp :has-interest.

[interesttarget] {
  interest-target-delay: 0s 1s;

  &:has-interest {
    background: yellow;
  }
}


popover="hint" và giao diện người dùng đa chức năng

Một phần quan trọng của vấn đề cần giải quyết đối với trình kích hoạt mối quan tâm là một loại cửa sổ bật lên mới: popover="hint". Điểm khác biệt chính so với các cửa sổ bật lên khác là cửa sổ bật lên gợi ý không đóng các cửa sổ bật lên khác khi mở. Đây là lựa chọn hoàn hảo cho chú thích hoặc thẻ xem trước sẽ xuất hiện mà không cần đóng một trình đơn hoặc cửa sổ trò chuyện đã mở.

Browser Support

  • Chrome: 133.
  • Edge: 133.
  • Firefox: not supported.
  • Safari: not supported.

popover=autopopover=manualpopover=hint
Đóng nhanh (thông qua thao tác nhấp ra ngoài hoặc nhấn phím esc)Không
Đóng các phần tử popover=auto khác khi được mởKhôngKhông
Đóng các phần tử popover=hint khác khi được mởKhông
Đóng các phần tử popover=manual khác khi được mởKhôngKhôngKhông
Có thể mở và đóng cửa sổ bật lên bằng JS (showPopover() hoặc hidePopover())
Quản lý tiêu điểm mặc định cho điểm dừng phím tab tiếp theo
Có thể ẩn hoặc chuyển đổi bằng popovertargetaction
Có thể mở trong popover của phần tử mẹ để giữ phần tử mẹ mở

Điều này cho phép bạn tạo giao diện người dùng mạnh mẽ, đa chức năng theo cách khai báo. Giờ đây, một nút có thể có một cửa sổ bật lên tự động bằng cách sử dụng popovertarget cho thao tác nhấp chính (chẳng hạn như mở bảng thông báo) một cửa sổ bật lên gợi ý được kích hoạt theo mối quan tâm để hiện một chú thích hữu ích khi di chuột.


Tương lai là khai báo

Các tính năng được đề cập ở đây thể hiện một bước chuyển đổi cơ bản hướng đến một nền tảng web mạnh mẽ và khai báo hơn. Bằng cách cho phép trình duyệt xử lý công việc phức tạp, lặp đi lặp lại về việc quản lý trạng thái và khả năng hỗ trợ tiếp cận, chúng ta có thể loại bỏ hàng loạt JavaScript, cải thiện hiệu suất và tập trung vào những gì chúng ta làm tốt nhất: tạo ra trải nghiệm người dùng hấp dẫn và cải tiến. Đây thực sự là thời kỳ hoàng kim của giao diện người dùng trên web và chỉ mới bắt đầu. Hãy theo dõi ngay tại đây khi chúng tôi nỗ lực xây dựng một web mạnh mẽ hơn và dễ sử dụng hơn.

Tài nguyên khác: