Tiêu điểm kiểu

Chỉ báo tiêu điểm (thường được biểu thị bằng "vòng tiêu điểm") xác định phần tử đang được lấy tiêu điểm trên trang của bạn. Đối với những người dùng không thể hoặc không muốn sử dụng chuột, chỉ báo này cực kỳ quan trọng vì nó đóng vai trò là một chỉ báo thay thế cho con trỏ chuột.

Nếu chỉ báo tiêu điểm mặc định của trình duyệt xung đột với thiết kế của bạn, bạn có thể dùng CSS để tạo lại kiểu cho chỉ báo đó. Hãy nhớ quan tâm đến người dùng.

Sử dụng :focus để luôn hiện chỉ báo lấy tiêu điểm

Lớp giả :focus được áp dụng cho các phần tử đang được lấy tiêu điểm, bất kể phương thức nhập hoặc thiết bị (chẳng hạn như chuột, bàn phím hoặc bút cảm ứng) đang được sử dụng.

Ví dụ: <div> sau đây có một tabindex giúp nó có thể lấy tiêu điểm, với một kiểu tuỳ chỉnh cho trạng thái :focus:

div[tabindex="0"]:focus {
  outline: 4px dashed orange;
}

Dù bạn sử dụng thiết bị nào, <div> vẫn trông giống nhau khi được lấy nét.

Rất tiếc, các trình duyệt có thể không nhất quán về cách áp dụng tiêu điểm. Việc một phần tử có nhận được tâm điểm hay không có thể phụ thuộc vào trình duyệt và hệ điều hành.

Ví dụ: <button> sau đây có CSS tuỳ chỉnh cho trạng thái :focus.

button:focus {
  outline: 4px dashed orange;
}

Nếu nhấp vào <button> bằng chuột trong Chrome trên macOS, bạn sẽ thấy kiểu tiêu điểm tuỳ chỉnh của nút này. Tuy nhiên, bạn sẽ không thấy kiểu tiêu điểm tuỳ chỉnh nếu nhấp vào <button> trong Safari trên macOS. Lý do là trong Safari, phần tử này không nhận được tiêu điểm khi bạn nhấp vào.

Hành vi lấy nét không nhất quán. Kiểm thử trang của bạn trên nhiều thiết bị và với nhiều phương thức nhập để đảm bảo người dùng chấp nhận các kiểu tiêu điểm của bạn.

Dùng :focus-visible để chọn hiển thị chỉ báo lấy tiêu điểm

Lớp giả :focus-visible được áp dụng khi một phần tử nhận được tiêu điểm và trình duyệt xác định (bằng phương pháp phỏng đoán) rằng việc hiển thị chỉ báo tiêu điểm sẽ có lợi cho người dùng. Cụ thể, nếu hoạt động tương tác gần đây nhất của người dùng là với bàn phím và thao tác nhấn phím không bao gồm phím meta, ALT, OPTION hoặc CONTROL, thì :focus-visible sẽ khớp.

Nút trong ví dụ sau đây chọn lọc cho thấy một chỉ báo tiêu điểm. Nếu bạn dùng chuột để nhấp, kết quả sẽ khác với trường hợp bạn dùng bàn phím để nhấn phím Tab vào đó.

button:focus-visible {
  outline: 4px dashed orange;
}

Sử dụng :focus-within để tạo kiểu cho phần tử mẹ của một phần tử được lấy tiêu điểm

Lớp giả :focus-within được áp dụng cho một phần tử khi chính phần tử đó nhận được tiêu điểm hoặc khi một phần tử con nhận được tiêu điểm. Bạn có thể dùng tính năng này để làm nổi bật một khu vực trên trang nhằm thu hút sự chú ý của người dùng đến khu vực đó.

Ví dụ: biểu mẫu nhận tiêu điểm khi chính biểu mẫu đó được chọn và cả khi bất kỳ nút chọn nào của biểu mẫu được chọn.

form:focus-within {
  background: #ffecb3;
}

Thời điểm hiển thị chỉ báo lấy tiêu điểm

Một câu hỏi hay là tự hỏi bản thân: "Nếu bạn nhấp vào chế độ kiểm soát này trong khi dùng thiết bị di động, bạn có mong đợi chế độ này hiển thị bàn phím không?"

  • Nếu có: Chế độ kiểm soát luôn hiển thị chỉ báo tiêu điểm, bất kể thiết bị đầu vào. Ví dụ: điều này hầu như luôn đúng với phần tử <input type="text">. Người dùng cần gửi dữ liệu đầu vào đến phần tử bằng bàn phím, bất kể phần tử đầu vào trở thành tâm điểm như thế nào.
  • Nếu không: Thao tác kiểm soát có thể chọn hiển thị một chỉ báo tiêu điểm một cách chọn lọc. Ví dụ: khi người dùng nhấp vào một <button> bằng chuột hoặc trên màn hình cảm ứng, hành động sẽ hoàn tất. Có thể không cần chỉ báo tiêu điểm. Tuy nhiên, nếu người dùng đang thao tác bằng bàn phím, thì bạn nên cho thấy chỉ báo tiêu điểm để người dùng có thể quyết định xem họ có muốn kích hoạt chế độ kiểm soát bằng phím ENTER hoặc SPACE hay không.

Tránh outline: none

Thành thật mà nói, cách trình duyệt quyết định thời điểm vẽ chỉ báo tiêu điểm rất khó hiểu. Việc thay đổi giao diện của một phần tử <button> bằng CSS hoặc cung cấp cho một phần tử một tabindex sẽ khiến hành vi mặc định của vòng tiêu điểm của trình duyệt bắt đầu hoạt động.

Đôi khi, nhà phát triển xoá chỉ báo tiêu điểm bằng CSS:

/* Don't do this!!! */
:focus {
  outline: none;
}

Cách tốt hơn để giải quyết vấn đề này là kết hợp :focus và polyfill :focus-visible. Khối mã đầu tiên minh hoạ cách hoạt động của polyfill và ứng dụng mẫu bên dưới cung cấp ví dụ về cách sử dụng polyfill để thay đổi chỉ báo tiêu điểm trên một nút.

/*
  This hides the focus indicator if the element receives focus with a
  mouse, but it still shows up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
  outline: none;
}

/*
  Optionally: Define a strong focus indicator for keyboard focus.
  If you choose to skip this step, then the browser's default focus
  indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
  ...
}