Tập trung

The CSS Podcast – 018: Tiêu điểm

Trên trang web, bạn nhấp vào một đường liên kết để chuyển người dùng đến nội dung chính của trang web. Những đường liên kết này thường được gọi là đường liên kết bỏ qua hoặc đường liên kết neo. Khi liên kết đó được kích hoạt bằng bàn phím, sử dụng phím tabenter, vùng chứa nội dung chính sẽ có vòng tiêu điểm xung quanh. Tại sao lại như vậy?

Lý do là <main> có giá trị thuộc tính tabindex="-1", có nghĩa là thuộc tính này có thể được lấy tiêu điểm theo phương thức lập trình. Khi <main> được nhắm mục tiêu (vì #main-content trong thanh URL của trình duyệt khớp với id), hệ thống sẽ nhận được tiêu điểm có lập trình. Bạn nên xoá kiểu tâm điểm trong những trường hợp như vậy, nhưng việc xử lý tiêu điểm một cách phù hợp và cẩn thận sẽ giúp tạo ra trải nghiệm người dùng tốt, dễ tiếp cận. Đây cũng có thể là một nơi tuyệt vời để thêm một số điểm thú vị vào các hoạt động tương tác.

Tại sao trọng tâm lại quan trọng?

Là nhà phát triển web, nhiệm vụ của bạn là làm cho trang web trở nên dễ tiếp cận và dành cho tất cả mọi người. Việc tạo trạng thái tiêu điểm có thể truy cập bằng CSS là một phần trong trách nhiệm này.

Kiểu tiêu điểm hỗ trợ những người sử dụng thiết bị như bàn phím hoặc công tắc điều khiển để di chuyển và tương tác với trang web. Nếu một phần tử nhận được tiêu điểm và không có chỉ báo trực quan, người dùng có thể mất dấu những gì đang được lấy tiêu điểm. Điều này có thể gây ra vấn đề điều hướng và dẫn đến hành vi không mong muốn nếu người dùng truy cập vào đường liên kết không chính xác.

Cách các phần tử nhận được tiêu điểm

Một số phần tử nhất định sẽ tự động có thể lấy tiêu điểm; đây là những phần tử chấp nhận tương tác và nhập, chẳng hạn như <a>, <button>, <input><select>. Tóm lại, tất cả các phần tử biểu mẫu, nút và đường liên kết. Thông thường, bạn có thể di chuyển các phần tử có thể làm tâm điểm của một trang web bằng cách sử dụng phím tab để tiến trên trang và di chuyển + tab để lùi lại.

Ngoài ra, còn có một thuộc tính HTML có tên là tabindex cho phép bạn thay đổi chỉ mục thẻ – thứ tự các phần tử được lấy tiêu điểm – mỗi khi người dùng nhấn phím tab hoặc tiêu điểm được chuyển đổi bằng một thay đổi về hàm băm trong URL hoặc bằng một sự kiện JavaScript. Nếu tabindex trên một phần tử HTML được đặt thành 0, thì phần tử đó có thể nhận tiêu điểm thông qua phím tab và sẽ tuân theo chỉ mục thẻ chung, được xác định theo thứ tự nguồn tài liệu.

Nếu bạn đặt tabindex thành -1, thì đối tượng đó chỉ có thể nhận tiêu điểm theo phương thức lập trình, nghĩa là chỉ khi một sự kiện JavaScript xảy ra hoặc có thay đổi hàm băm (trùng khớp với id của phần tử trong URL) xảy ra. Nếu bạn đặt tabindex thành giá trị cao hơn 0, thì giá trị này sẽ bị xoá khỏi chỉ mục thẻ toàn cục, được xác định theo thứ tự nguồn tài liệu. Trình tự nhấn phím Tab hiện sẽ được xác định theo giá trị của tabindex, vì vậy, một phần tử có tabindex="1" sẽ nhận được tiêu điểm trước một phần tử có tabindex="2", chẳng hạn.

Tiêu điểm tạo kiểu

Hành vi mặc định của trình duyệt khi một phần tử nhận được tiêu điểm là hiển thị một vòng tròn tiêu điểm. Vòng tròn tiêu điểm này khác nhau giữa cả trình duyệt và hệ điều hành.

Bạn có thể thay đổi hành vi này bằng CSS, sử dụng các lớp giả :focus, :focus-within:focus-visible mà bạn đã tìm hiểu trong bài học về lớp giả. Điều quan trọng là bạn phải đặt kiểu tiêu điểm có độ tương phản với kiểu mặc định của một phần tử. Ví dụ: một phương pháp phổ biến là sử dụng thuộc tính outline.

a:focus {
  outline: 2px solid slateblue;
}

Thuộc tính outline có thể xuất hiện quá gần văn bản của đường liên kết, nhưng thuộc tính outline-offset có thể giúp giải quyết vấn đề này, vì thuộc tính này thêm padding hình ảnh bổ sung mà không ảnh hưởng đến kích thước hình học mà phần tử lấp đầy. Giá trị số dương cho outline-offset sẽ đẩy đường viền ra ngoài, giá trị âm sẽ kéo đường viền vào bên trong.

Hiện tại, trong một số trình duyệt, nếu bạn đặt border-radius trong phần tử và sử dụng outline, thì thành phần này sẽ không khớp (đường viền sẽ có các góc sắc). Do đó, bạn nên sử dụng box-shadow có bán kính làm mờ nhỏ vì box-shadow sẽ cắt theo hình dạng, tuân theo border-radius, nhưng kiểu này sẽ không hiển thị ở Chế độ tương phản cao của Windows. Điều này là do Chế độ tương phản cao của Windows không áp dụng bóng và chủ yếu bỏ qua hình nền để ưu tiên chế độ cài đặt mà người dùng ưu tiên.

Tóm tắt

Việc tạo trạng thái tiêu điểm có độ tương phản với trạng thái mặc định của phần tử là vô cùng quan trọng. Các kiểu trình duyệt mặc định đã thực hiện việc này cho bạn, nhưng nếu bạn muốn thay đổi hành vi này, hãy nhớ những điều sau:

  • Tránh sử dụng outline: none trên một phần tử có thể nhận tiêu điểm bàn phím.
  • Tránh thay thế kiểu outline bằng box-shadow. vì chúng không xuất hiện trong Chế độ tương phản cao của Windows.
  • Chỉ đặt giá trị dương cho tabindex trên phần tử HTML nếu bạn thực sự cần.
  • Đảm bảo trạng thái lấy nét rất rõ ràng so với trạng thái mặc định.

Kiểm tra mức độ hiểu biết

Kiểm tra kiến thức của bạn về tiêu điểm

Mục nào sau đây là thành phần có thể tự động lấy tiêu điểm?

<a>
🎉
<p>
Hãy thử lại!
<button>
🎉
<input>
🎉
<output>
Hãy thử lại!
<select>
🎉

Thiết bị đầu vào nào sau đây có thể đặt tiêu điểm?

Tay điều khiển trò chơi
Tay điều khiển trò chơi thường gửi sự kiện bàn phím khi người dùng nhấn vào các nút.
Bàn phím
Chắc chắn sẽ gây ra tiêu điểm khi được dùng để điều hướng trên web.
Chuột
Chuột cần có thị giác và không còn đặt tiêu điểm vào các phần tử khi sử dụng. Tất cả trình duyệt đều từng đặt tiêu điểm vào các nút khi được nhấp vào, nhưng điều đó đã thay đổi.
Công nghệ hỗ trợ (trình đọc màn hình, công tắc, v.v.)
Chắc chắn sẽ gây ra tiêu điểm khi được dùng để điều hướng trên web.
Khoai tây
Rất tiếc, mặc dù có thể dùng khoai tây làm con trỏ trên màn hình cảm ứng, nhưng nó không gây ra tiêu điểm sau khi tương tác với các phương thức nhập trên màn hình.