Chọn CSS thuần túy

Trước tiên hãy giải quyết vấn đề này. hộp chọn là một ý tưởng tồi. Tạo kiểu hộp chọn là một ý tưởng tồi. Các trình duyệt web sẽ không bao giờ hỗ trợ kiểu dáng CSS đầy đủ của các hộp chọn gốc. Tóm lại, điều này là do các hộp chọn được coi là các điều khiển hệ điều hành gốc — giống như “cơm” xung quanh bên ngoài trình duyệt của bạn. Điều đó có nghĩa là họ có thể làm những thứ như thế này

Các hộp chọn có thể thoát khỏi canvas của trình duyệt, trong một số trường hợp nhất định (brrrr)

Thay đổi giao diện của chúng và người dùng không còn biết họ đang tìm kiếm gì

Tốt. Đợi đã, bạn vẫn muốn tạo kiểu cho chúng?

Có một số thư viện JavaScript có thể trợ giúp - ví dụ như Chosen, jQuery selectBox, SelectBoxIt hoặc Select2 có tên gây nhầm lẫn. Một số trong số này thêm các tính năng hữu ích, chẳng hạn như tìm kiếm. Nhưng họ đều có một điểm chung. chúng không mất nhiều thời gian để triển khai, nhưng luôn có vấn đề với chúng trong giai đoạn Thử nghiệm chấp nhận của người dùng của một dự án. Nhiều vấn đề trong số này phát sinh từ thực tế là tất cả các thư viện này đều ẩn hộp chọn ban đầu và sao chép nó với các phần tử HTML khác, chẳng hạn như ký tự neo hoặc thẻ đầu vào. Điều này có nghĩa là các sự kiện được thêm vào hộp chọn ban đầu thường bị mất và hành động của người dùng không được ghi lại chính xác

Điều gì sẽ xảy ra nếu chúng ta có thể làm điều tương tự bằng CSS thuần túy, gợi cảm, sử dụng các phần tử HTML gốc có ý nghĩa về mặt ngữ nghĩa?

Hộp chọn thậm chí là gì?

Có một vài loại hộp chọn khác nhau

Về chức năng, tất cả những thứ này, ngoại trừ loại “nhiều”, hoạt động giống như các nút radio. nếu người dùng chọn một tùy chọn, sau đó đổi ý, lựa chọn ban đầu của họ sẽ bị bỏ chọn. Đối với mã phía máy chủ, người dùng đã đưa ra lựa chọn. Nó không quan tâm làm thế nào sự lựa chọn đó được thực hiện

Vì vậy, hầu hết các hộp chọn chỉ là nút radio?

Yup - tất cả những gì máy chủ nhận được trong bài đăng của biểu mẫu là các cặp tên-giá trị. Nó không biết hoặc không quan tâm điều khiển nào được sử dụng để nắm bắt chúng từ người dùng

Chọn hộp thay thế 1 (spoiler. nó không hoạt động)

Suy nghĩ ban đầu của tôi là "điều gì sẽ xảy ra nếu tôi đặt một loạt các nút radio và thẻ nhãn bên trong một vùng chứa, sau đó làm cho vùng chứa mở rộng, khi một trong số chúng đạt được tiêu điểm?"

  • Bản thân các nút radio sẽ được ẩn đi một cách trực quan
  • Các thẻ nhãn sẽ được xếp chồng lên nhau, sử dụng position: absolute
  • Vùng chứa cũng cần được định vị tuyệt đối để khi mở rộng, vùng chứa sẽ nằm trên bất kỳ nội dung nào sau đây
  • Ngay sau khi một nút radio đạt được tiêu điểm, vị trí của tất cả các phần tử label trong vùng chứa sẽ chuyển sang static. Vì tôi cũng đã thay đổi thuộc tính hiển thị của chúng trước đó thành block, nên chúng sẽ xếp chồng lên nhau và buộc vùng chứa lấy toàn bộ chiều cao tự nhiên của chúng

Tôi đã làm tất cả những điều đó, và điều này đã xảy ra

Vấn đề chính là không thể thực sự chọn bất kỳ giá trị nào. Tôi cho rằng điều này là do sự kiện mờ (vì muốn có một cái tên hay hơn) xảy ra trước khi tiêu điểm vào phần tử label chọn nút radio tiếp theo

Nhưng có một vấn đề khác nghiêm trọng hơn. Quy tắc thực hiện hầu hết công việc là đây

input:focus ~ label {position: static;}

Điều này đọc bằng tiếng Anh là “Nếu một yếu tố input được đặt vào tiêu điểm, thì hãy thay đổi tất cả các thẻ label sau thành position: static". ~ là bộ chọn anh chị em sau đây. Không có bộ chọn theo dõi và tiếp tục trong CSS và không chắc là sẽ có,. Tôi nghĩ điều này là do CSS nghĩ về việc phân tích cú pháp DOM, từ trên xuống dưới (đây cũng là lý do không có bộ chọn chính trong CSS). Nó không nhanh nhẹn như JavaScript, thứ chạy quanh cả cây như một con tinh tinh

thử hai. chuyển đổi cũ

Kỹ thuật sử dụng hộp kiểm để hiển thị và ẩn nội dung, bằng cách sử dụng bộ chọn anh chị em liền kề đã xuất hiện được một thời gian. Suy nghĩ ban đầu của tôi là sử dụng nó để chuyển đổi mở và đóng hộp chọn. Điều đó không lý tưởng — sau khi người dùng đã chọn một tùy chọn bên trong hộp chọn, hộp sẽ không đóng cho đến khi họ nhấn nút chuyển đổi một lần nữa

Điều này đã hiệu quả, nhưng tôi tự hỏi liệu tôi có thể cải thiện nó không

Tôi đã thử thủ thuật thay đổi tiêu cự một lần nữa. ngay khi người dùng chọn một tùy chọn bên trong hộp chọn, tiêu điểm sẽ chuyển sang nút radio đó và lựa chọn sẽ đóng lại. Thật không may, điều này không hoạt động có lẽ vì lý do chính xác giống như lần thử đầu tiên không hoạt động. điều gì đó về tiêu điểm bị mất trước khi có thể thay đổi trạng thái của nút radio. tôi không biết

cố gắng ba. tất cả các nút radio, mọi lúc

Điều gì sẽ xảy ra nếu bản thân công tắc chọn là một phần của cùng một loạt các nút radio như phần còn lại của hộp chọn?

.radio-toggle:checked ~ .select label {position: static;}

Trong tiếng Anh, quy tắc này có nội dung “nếu một phần tử có lớp label0 được chọn, hãy tìm tất cả các phần tử sau có lớp label1, sau đó thay đổi vị trí của tất cả các phần tử label bên trong nó thành static"

Điều này cũng có nghĩa là nếu hộp kiểm đó không còn được chọn nữa, các thành phần nhãn sẽ trở lại giá trị label4 trước đó của chúng là label5 (xếp chúng lên một lần nữa). Thử nghiệm

tôi quên mất một điều

Phiên bản CSS gốc, thuần túy của sự thay thế hộp chọn này có một lỗ hổng khủng khiếp. nó chỉ có thể truy cập một phần thông qua bàn phím. Tôi đã nhấn mạnh vấn đề này bởi người dùng Reddit jestho, người có một phiếu giảm giá đã đánh chìm bài đăng của tôi khỏi tầm nhìn

Nhưng tất nhiên, jestho hoàn toàn đúng. điều hướng bàn phím là hoàn toàn quan trọng đối với các điều khiển như vậy. Tôi đã làm những gì có thể trong css thuần túy, nhưng tất cả những gì tôi có thể làm là thêm một ____1_______6 xung quanh hộp chọn, khi nó xuất hiện lần đầu tiên. Thật không may, một khi người dùng chọn một giá trị từ trong hộp chọn, chuyển sang một điều khiển khác, sau đó quay lại hộp chọn đó, phần tô sáng không còn hiển thị nữa (điều này là do để làm như vậy, các thay đổi trên phần tử con sẽ cần

Và tất nhiên, việc ghi lại các lần nhấn phím và cho phép điều hướng đặc biệt trong một hộp chọn riêng lẻ hoàn toàn nằm ngoài thẩm quyền của CSS. Điều đó có nghĩa là đã đến lúc

thử bốn. các hộp chọn CSS có thể tạo kiểu thuần túy, hiện có thêm JavaScript

Hầu hết JavaScript ở đó để nắm bắt và giải thích các lần nhấn phím khác nhau, chẳng hạn như

  • Phím con trỏ (di chuyển lên và xuống — điều này hầu hết miễn phí, nhưng JavaScript dừng tiêu điểm ở cuối và đầu của phạm vi giá trị)
  • Trang lên (di chuyển khoảng cách có thể định cấu hình lên hoặc đến giá trị đầu tiên, nếu có)
  • Trang xuống (như trên, nhưng xuống)
  • Dấu cách (mở hộp chọn)
  • Enter (chuyển đổi mở và đóng hộp chọn)
  • Thoát (đóng hộp chọn)

Việc sử dụng tab được nắm bắt bởi các sự kiện gắn liền với các thay đổi trong tiêu điểm, vì vậy tôi không cần phải viết bất kỳ jQuery nào để tìm kiếm điều đó

Điều hướng bàn phím JavaScript là một chủ đề gây tranh cãi, vì vậy tôi đã cố gắng sao chép hành vi của hộp chọn mặc định (Windows, xin lỗi). Để điều hướng bằng bàn phím trong các thành phần trang khác, tôi khuyên bạn nên xem Thực tiễn tác giả WAI-ARIA hoặc nếu bạn thích W3C vì bất kỳ lý do gì, Dự án A11Y

Tôi không thích bản chất mã hóa cứng của rất nhiều JavaScript này (bao gồm cả của tôi. ). Lý tưởng nhất là điều hướng bàn phím nên có một số loại bộ giải có các chức năng khác để hiểu các khái niệm như đầu tiên, cuối cùng, tiếp theo, trước đó, v.v. và có thể được thêm vào bất kỳ cấu trúc DOM nào với một vài tham số. Nhưng đó là một dự án hoàn toàn khác

Làm cách nào để chọn kiểu bằng CSS?

Có nhiều cách để thiết kế menu thả xuống Mỗi tùy chọn menu có thể được xác định bởi phần tử .

Làm cách nào để thêm CSS cho tùy chọn được chọn trong codepen?

Bạn cũng có thể liên kết đến một Bút khác tại đây (sử dụng. Tiện ích mở rộng URL css) và chúng tôi sẽ lấy CSS từ Bút đó và bao gồm nó . Nếu nó đang sử dụng một bộ xử lý trước phù hợp, hãy sử dụng Tiện ích mở rộng URL thích hợp và chúng tôi sẽ kết hợp mã trước khi xử lý trước, vì vậy bạn có thể sử dụng Bút được liên kết làm phụ thuộc thực sự.

Làm cách nào để tùy chỉnh danh sách thả xuống trong CSS?

Giải thích ví dụ . g. một phần tử Sử dụng phần tử vùng chứa (như . Bọc một phần tử