Việc tạo kiểu cho các thành phần điều khiển biểu mẫu như phần tử <select> đã được báo cáo là một điểm khó khăn hàng đầu của nhà phát triển trong nhiều năm và chúng tôi đang nỗ lực tìm giải pháp. Mặc dù công việc này rất phức tạp và mất nhiều thời gian để hoàn thiện, nhưng chúng tôi sắp ra mắt tính năng này. Phiên bản có thể tuỳ chỉnh của phần tử chọn chính thức ở Giai đoạn 2 trong WHATWG, với sự quan tâm mạnh mẽ của nhiều trình duyệt và một nguyên mẫu để bạn thử nghiệm từ Chrome Canary 130.
Hãy dùng thử và cho chúng tôi biết ý kiến phản hồi của bạn
Kiểm tra để đảm bảo rằng bạn đã cập nhật bản cài đặt Chrome Canary lên phiên bản 130 và đã bật cờ tính năng nền tảng web thử nghiệm. Bạn có thể bật cờ này bằng cách truy cập vào chrome://flags trong thanh địa chỉ rồi bật #experimental-web-platform-features. Sau đó, bạn sẽ có thể xem các bản minh hoạ Codepen trong bài đăng này. Ngoài ra, bạn có thể xem bộ sưu tập Codepen này để xem tất cả ở cùng một nơi.
Hãy sử dụng biểu mẫu này để đưa ra ý kiến phản hồi về tính năng này. Bạn chỉ mất 3 phút để hoàn tất!
Hãy cùng tìm hiểu các tính năng của API lựa chọn có thể tuỳ chỉnh, được xây dựng dựa trên thẻ lựa chọn HTML hiện có.
Chọn sử dụng <select> mới
Để chọn sử dụng hành vi mới, hãy dùng thuộc tính CSS appearance trên cả nút chọn trong trang và bộ chọn. Để chọn sử dụng, hãy đặt appearance: base-select trên phần tử <select> và trên ::picker(select).
::picker(select) là một phần tử giả mới do tác nhân người dùng cung cấp, chỉ áp dụng cho các phần tử <select> đã chọn sử dụng hành vi mới bằng appearance: base-select. Phần tử giả bộ chọn này là cửa sổ bật lên được kích hoạt bằng nút chọn cơ sở. Bạn có thể chọn sử dụng cả hai như trong đoạn mã sau:
select,
::picker(select) {
appearance: base-select;
}
Bạn có thể chọn chỉ sử dụng nút trên trang, nhưng không thể chỉ sử dụng cửa sổ bật lên của bộ chọn mà không sử dụng nút trên trang. ::picker(select) chỉ được tạo sau khi appearance: base-select được áp dụng cho <select>.
Bây giờ, bạn đã có thể tuỳ chỉnh phần tử chọn. Phần tử chọn mới có thể tuỳ chỉnh đi kèm với một số kiểu mặc định trông giống nhau trên các trình duyệt và hệ điều hành. Dưới đây là giao diện của phần tử chọn tuỳ chỉnh mặc định so với phần tử chọn hiện có trong Chrome trên macOS:
Phân tích các phần
Khi đang ở chế độ chọn mới có thể tuỳ chỉnh, bạn có thể sử dụng các phần tử mới sau:
- selectedoption: phản ánh HTML bên trong của tuỳ chọn hiện được chọn.
option::before: chứa dấu kiểm để cho biết lựa chọn hiện được chọn là một khả năng hỗ trợ tiếp cận mặc định (có thể thay đổi).
– ::picker(select): cửa sổ bật lên chứa tất cả nội dung bên ngoài button bên trong một lựa chọn có thể tuỳ chỉnh.
Bạn có thể tạo kiểu cho bất kỳ phần nào của lựa chọn. Ví dụ: bạn có thể thêm nội dung tuỳ ý không tương tác trong các phần tử <option>, tạo kiểu cho nút trong trang để mở trình đơn thả xuống và tạo kiểu cho danh sách thả xuống các lựa chọn (::picker(select)).
Bạn cũng có thể tạo kiểu cho button, tự tạo chỉ báo mũi tên và thêm nội dung tuỳ ý vào bên trong và xung quanh bất kỳ phần tử nào. Ngoài việc thêm nội dung, bạn có thể ẩn bất kỳ phần tử mới và kiểu mặc định nào trong số này. Ví dụ: nếu bạn không muốn có dấu kiểm chỉ báo trong phần tử giả ::before của tuỳ chọn, hãy sử dụng CSS sau.
/* Remove the default checkmark from the selected option */
option::before {
display: none;
}
Mặc dù có thể có số lượng phần tử không giới hạn bên trong phần tử chọn, nhưng trình duyệt sẽ nhóm mọi phần tử bên ngoài phần tử <button> vào phần tử giả ::picker(select). Phần tử này hoạt động như một cửa sổ bật lên được liên kết với nút. <button> này bật/tắt ::picker(select). Các tuỳ chọn và phần tử khác ngay bên trong phần tử chọn sẽ được đưa vào ::picker(select) hoặc bạn có thể tự tạo trình bao bọc để tạo kiểu. Phần tử bao bọc này cũng sẽ được đặt bên trong phần tử giả ::picker(select).
<select>
<button>
<selectedoption></selectedoption>
</button>
// Everything else that will go into the ::picker(select) popover
</select>
<select> mới có thể tuỳ chỉnh sử dụng chức năng của popover và định vị neo. Tính năng này được xây dựng dựa trên hai công nghệ cơ bản sau đây. Điều này có nghĩa là danh sách lựa chọn thả xuống trong một lựa chọn sẽ đóng vai trò là một cửa sổ bật lên được liên kết với nút kích hoạt mở lựa chọn đó.
Bạn có thể sử dụng tính năng định vị neo để tạo kiểu cho cửa sổ bật lên ::picker(select) này (bao gồm cả việc neo cửa sổ bật lên vào các phần tử khác). Mô hình nội dung này cũng có nghĩa là các kiểu ảnh động lớp trên cùng hoạt động với danh sách tuỳ chọn để tạo hiệu ứng động cho hiệu ứng vào và ra.
Cải thiện phần tử <select> hiện có
Trước đây, nhóm Chrome đã nghiên cứu ý tưởng về phần tử <selectlist>. Nội dung được mô tả trong bài đăng này là tính năng được thiết kế lại để sử dụng lại phần tử <select> hiện có.
Một trong những lợi ích chính của việc sử dụng lại phần tử <select> hiện có là khả năng cải thiện dần phần tử HTML cơ bản. So với một phần tử hoàn toàn mới, việc sử dụng lại <select> vẫn sẽ hiển thị nội dung có ý nghĩa trên trang của bạn. Ví dụ sau đây cho thấy phần tử chọn tuỳ chỉnh so với những gì người dùng thấy trong trình duyệt không được hỗ trợ:
option đều được hiển thị trong phiên bản dự phòng của phần tử chọn.Định kiểu cơ bản
Thay đổi có thể đơn giản như kiểu hình ảnh của phần tử chọn. Ví dụ: để cập nhật kiểu nút, kiểu di chuột và tiêu điểm hoặc nền của các tuỳ chọn chọn. Sau khi chọn sử dụng appearance: base-select, hãy áp dụng bất kỳ CSS nào bạn muốn cho các phần của lựa chọn.
Để tuỳ chỉnh chỉ báo mũi tên, hãy thêm nút và mũi tên của riêng bạn vào bên trong phần tử chọn.
<select>
<button>
<selectedoption></selectedoption>
<span>
// Arrow here
</span>
</button>
// Everything else that will go into the ::picker(select) popover
</select>
Sau đó, hãy tạo kiểu cho mũi tên:
/* style the arrow */
button span {
/* arrow styles */
transition: rotate 0.2s;
}
/* adjust arrow styles when the picker is open */
select:open button span {
rotate: -180deg;
}
Nội dung phức tạp trong các lựa chọn
Bạn có thể tiến xa hơn bằng cách thêm và tạo kiểu cho nội dung ngoài chuỗi trong các phần tử <option> bên trong <select>. Một ví dụ cơ bản là thêm hình ảnh quốc kỳ bên cạnh tên quốc gia trong trình đơn thả xuống. Để thực hiện việc này, hãy thêm một phần tử hình ảnh bên cạnh văn bản lựa chọn.
<option value="france">
<img src="img/flag_of_france.svg" alt="" />
<span>France</span>
</option>
Một ví dụ phức tạp hơn có thể bao gồm ảnh hồ sơ, tên và thông tin thay thế để giúp bạn đưa ra quyết định về mục cần chọn trong trình đơn thả xuống.
<option value="eur">
<img src="euro-flag.png" alt="" />
<div class="currency">
<div class="currency-short">EUR</div>
<div class="currency-long">Euro</div>
</div>
<div class="symbol" aria-hidden="true">€</div>
</option>
Tạo kiểu cho lựa chọn đã chọn
Bạn có thể muốn lựa chọn đã chọn hiển thị ở trạng thái đã chọn khác với trạng thái trong trình đơn thả xuống. Ví dụ về điều này là giao diện người dùng Gmail, trong đó, để tiết kiệm không gian, nhãn sẽ bị xoá sau khi bạn chọn tuỳ chọn. Hãy thực hiện việc này bằng cách kết nối với phần tử <selectedoption> để tạo kiểu. <option> chứa tất cả mã đánh dấu sau:
<option value="reply-all">
<img class="material-symbol" src="material-symbol-reply.png">
<span class="text">Reply all</span>
</option>
Bây giờ, hãy áp dụng display: none trên .text bên trong <selectedoption> để ẩn nội dung văn bản và chỉ hiện biểu tượng:
selectedoption .text {
display: none;
}
Các lựa chọn tương tác
Với toàn quyền kiểm soát kiểu của ::picker(select), hãy xây dựng dựa trên bản minh hoạ trước đó để làm cho bản minh hoạ này có tính tương tác khi di chuột và lấy tiêu điểm. Trong bản minh hoạ này, hàm calc-size() mới được dùng để tạo ảnh động cho chiều rộng của bộ chọn, từ việc hiển thị các biểu tượng đến việc hiển thị toàn bộ chiều rộng của các lựa chọn khi di chuột hoặc nếu lựa chọn có một lựa chọn có focus-visible.
/* base styles when picker is open but not interacted with */
::picker(select) {
width: var(--icon-width);
transition: width 0.5s;
}
/* animate the text in on hover & focus */
::picker(select):hover,
select:has(option:focus-visible)::picker(select) {
/* auto width! */
width: calc-size(auto, size + 0.5rem);
}
Các điểm hạn chế và lưu ý về khả năng hỗ trợ tiếp cận
Sức mạnh càng lớn thì trách nhiệm càng cao. Để đảm bảo mọi người đều có thể sử dụng, tính năng này có một số hạn chế.
- Ngoài các phần tử
<option>, bạn chưa được phép sử dụng các phần tử tương tác (có thể làm tâm điểm) bên trong<select>, chẳng hạn như nút hoặc các phần tử khác. Hiện tại, mô hình nội dung đề xuất chỉ cho phép các phần tử<div>,<span>,<option>,<optgroup>,<img>,<svg>và<hr>. - Nút phân tách hiện đang trong giai đoạn thử nghiệm khi chúng tôi tìm ra giải pháp hỗ trợ tiếp cận.
Trong tương lai, mô hình nội dung dự kiến sẽ mở rộng để linh hoạt hơn, khi câu chuyện về khả năng hỗ trợ tiếp cận cho những trải nghiệm này được hoàn thiện.
Kết luận
Chúng tôi rất vui mừng khi thấy tính năng này tiến triển thông qua các nhóm làm việc và cơ quan tiêu chuẩn, đồng thời chia sẻ tiến trình của chúng tôi khi chúng tôi tích cực xây dựng nguyên mẫu và đánh giá hình dạng của tính năng này. Nếu bạn gặp phải vấn đề nào đó không hoạt động như mong đợi, hãy cho chúng tôi biết!
Tính năng này vẫn đang trong quá trình phát triển, nên chúng tôi rất mong nhận được ý kiến phản hồi của bạn thông qua biểu mẫu phản hồi ngắn này.
Cảm ơn bạn đã góp phần giúp chúng tôi thực hiện đúng và giúp việc xây dựng các chế độ kiểm soát biểu mẫu dễ tiếp cận, có thể tuỳ chỉnh trên web trở nên dễ dàng hơn!