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 trong 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. Bài khảo sát này chỉ mất 3 phút để hoàn thành!

Hãy cùng 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à 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 tham gia hành vi mới bằng appearance: base-select. Phần tử giả của 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 cách như minh hoạ 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ọn chỉ sử dụng cửa sổ bật lên trong bộ chọn nếu không chọn 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 tuỳ chỉnh ở bên phải. Vấn đề 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ề lựa chọn cơ bản và lựa chọn tuỳ chỉnh.

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

Biểu đồ thể hiện các phần của một lựa chọn.

Sau khi bạn ở chế độ chọn có thể tuỳ chỉnh mới, bạn sẽ có quyền truy cập vào các phần tử mới sau đây: – 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 tuỳ chọn đang được chọn làm thành phần hỗ trợ tiếp cận mặc định (tuỳ chọn 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 đã chọn. 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 trên 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, thêm chỉ báo mũi tên của riêng bạn và thêm nội dung tuỳ ý bên trong cũng như 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 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 sẽ bật/tắt ::picker(select). Các tuỳ chọn và phần tử khác ngay bên trong vùng chọn sẽ được chuyển lên trên ::picker(select) hoặc bạn có thể sử dụng trình bao bọc của riêng mình để 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. Tức là danh sách tuỳ chọn thả xuống trong một lựa chọn đóng vai trò là cửa sổ bật lên được liên kết với nút điều kiện kích hoạt để mở lựa chọn đó.

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 mở và đóng.

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ử chọn lọc.

Định kiểu cơ bản

Thay đổi có thể đơn giản như việc định kiểu hình ảnh của phần tử lựa 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 CSS bất kỳ mà bạn muốn cho các phần bạn 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 lựa 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. Bạn có thể 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ả 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 có biểu tượng đại diện cho phương á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 hiệu ứng 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ị biểu tượng đến 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 vùng chọn có một tuỳ chọn hiển thị tiêu điểm.

/* 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);
}
Nút chọn tương tác theo kiểu Gmail với nội dung dần được hiển thị 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. Có một số hạn chế đối với tính năng này để người dùng dễ sử dụng.

  • 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 (lấy làm tâm điểm) bên trong <select>, chẳng hạn như các 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><hr>.
  • Nút phân tách hiện đang trong giai đoạn thử nghiệm vì chúng tôi đã tìm ra một 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 chi tiết hơn.

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!