Yêu cầu phản hồi của nhà phát triển: chọn tuỳ chỉnh

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à vấ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 ra giải pháp. Mặc dù công việc này 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ử select đã chính thức ở Giai đoạn 2 trong WHATWG, với sự quan tâm mạnh mẽ trên 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 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 trên thanh địa chỉ rồi bật #experimental-web-platform-features. Sau đó, bạn sẽ thấy 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ác dự án ở cùng một nơi.

Hãy sử dụng biểu mẫu này để gửi ý kiến phản hồi về tính năng này. Việc này chỉ mất 3 phút!

Hãy tìm hiểu các tính năng của API select có thể tuỳ chỉnh, được xây dựng dựa trên thẻ select HTML hiện có.

Chọn sử dụng <select> mới

Để chọn sử dụng hành vi mới, hãy sử dụng thuộc tính appearance CSS trên cả nút chọn trong trang và bộ chọn 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ả do tác nhân người dùng mới 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ả lập 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 mã sau:

select,
::picker(select) {
  appearance: base-select;
}

Bạn có thể chọn chỉ sử dụng nút trong 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 trong trang. ::picker(select) chỉ được tạo sau khi appearance: base-select được áp dụng cho <select>.

Bây giờ, bạn đã sẵn sàng tuỳ chỉnh phần tử select. Bộ 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 lựa chọn tuỳ chỉnh mặc định so với lựa chọn hiện có trong Chrome trên macOS:

Kiểu tác nhân người dùng mặc định cho lựa chọn có thể tuỳ chỉnh ở bên phải. Điều này có thể thay đổi và chúng tôi rất mong nhận được ý kiến phản hồi của bạn.
Bản minh hoạ về một phần tử chọn cơ bản so với phần tử chọn có thể tuỳ chỉnh.

Phân tích các phần

Sơ đồ cho thấy các phần của một câu lệnh chọn.

Khi bạn ở chế độ chọn mới có thể tuỳ chỉnh, các phần tử mới mà bạn hiện có quyền truy cập bao gồm: – selectedoption: phản ánh HTML bên trong của tuỳ chọn hiện đang được chọn. – option::before: chứa dấu kiểm để cho biết tuỳ chọn hiện được chọn là một tính năng hỗ trợ tiếp cận mặc định (tính năng này 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 phần tử select. Ví dụ: bạn có thể thêm nội dung không tương tác tuỳ ý trong các phần tử <option>, tạo kiểu cho nút trong trang để mở trình đơn thả xuống chọn và tạo kiểu cho danh sách các tuỳ chọn thả xuống (::picker(select)).

Bạn cũng có thể tạo kiểu cho button, chỉ báo mũi tên tự tạo và thêm nội dung tuỳ ý 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ỳ thành phần mới nào 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ả lập ::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 thứ 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à các phần tử khác ngay bên trong phần tử select sẽ được chuyển lên ::picker(select) hoặc bạn có thể mang trình bao bọc của riêng mình cho mục đích tạo kiểu. Trình 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> có thể tuỳ chỉnh mới sử dụng chức năng của cửa sổ bật lênvị trí neo. Công cụ này được xây dựng bằng hai công nghệ cơ bản này. Điều này có nghĩa là danh sách tuỳ chọn thả xuống trong một phần tử select đó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ở phần tử select.

Bạn có thể sử dụng vị trí 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ổ này 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 ảnh động khi vào và thoát.

Cải thiện phần tử <select> hiện có

Trước đây, nhóm Chrome đang làm việc với ý tưởng về phần tử <selectlist>. Nội dung 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 lựa chọn tuỳ chỉnh so với nội dung mà người dùng trong trình duyệt không được hỗ trợ sẽ thấy:

Tất cả nội dung văn bản trong option được hiển thị trong phiên bản dự phòng của phần tử select.

Định kiểu cơ bản

Các 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à lấy 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 phần tử chọn.

Thay đổi kiểu của nhiều phần trong phần chọn bằng nút mặc định.

Để 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 chọn.

<select>
  <button>
    <selectedoption></selectedoption>
    <span>
      // Arrow here
    </span>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

Sau đó, 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 tuỳ chọn

Hãy tiến xa hơn với khả năng thêm và tạo kiểu nội dung ngoài các chuỗi trong phần tử <option> bên trong <select>. Ví dụ cơ bản là thêm hình ảnh cờ 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 tuỳ chọn.

<option value="france">
  <img src="img/flag_of_france.svg" alt="" />
  <span>France</span>
</option>
Bộ chọn quốc gia có cờ.

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>
Ảnh chụp màn hình bộ chọn đơn vị tiền tệ.

Định kiểu cho tuỳ chọn đã chọn

Bạn có thể muốn tuỳ chọn đã chọn hiển thị theo cách khác trong trạng thái đã chọn so với trong trình đơn thả xuống. Ví dụ: giao diện người dùng của 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 nối vào phần tử <selectedoption> để tạo kiểu. <option> chứa tất cả cá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 thị biểu tượng:

selectedoption .text {
  display: none;
}
Chọn kiểu Gmail với biểu tượng đại diện cho tuỳ chọn đã chọn.

Tuỳ 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 trên bản minh hoạ trước đó để tạo 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 tuỳ chọn khi di chuột hoặc nếu bộ chọn có một tuỳ chọn có tiêu điểm hiển thị.

/* 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);
}
Chọn theo kiểu Gmail có tính tương tác với nội dung hiển thị dần khi di chuột hoặc lấy tiêu điểm.

Giới hạn và ghi chú về khả năng hỗ trợ tiếp cận

Quyền lực càng lớn thì trách nhiệm càng cao. Để đảm bảo mọi người đều có thể truy cập, tính năng này có một số hạn chế.

  • Ngoài các phần tử <option>, không có phần tử tương tác (có thể lấy tiêu điểm) nào được phép bên trong <select>, chẳng hạn như các nút hoặ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><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 này 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 làm rõ.

Kết luận

Chúng tôi rất vui khi thấy tính năng này được phát triển thông qua các nhóm làm việc và tổ chức tiêu chuẩn, đồng thời chia sẻ tiến trình của chúng tôi khi tích cực xây dựng nguyên mẫu và đánh giá hình thức 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!

Mặc dù tính năng này vẫn đang trong quá trình phát triển, nhưng 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 ý kiến phản hồi ngắn này.

Cảm ơn bạn đã góp phần giúp chúng tôi đảm bảo việc này được thực hiện đúng cách và giúp bạn dễ dàng tạo các thành phần điều khiển biểu mẫu có thể tuỳ chỉnh và dễ tiếp cận trên web!