Khả năng truy cập web [còn được gọi là a11y] là thiết kế và tạo các trang web mà mọi người đều có thể sử dụng. Hỗ trợ trợ năng là cần thiết để cho phép công nghệ hỗ trợ diễn giải các trang web
React hỗ trợ đầy đủ việc xây dựng các trang web có thể truy cập, thường bằng cách sử dụng các kỹ thuật HTML tiêu chuẩn
Tiêu chuẩn và Nguyên tắc
WCAG
Nguyên tắc về khả năng truy cập nội dung web cung cấp các nguyên tắc để tạo các trang web có thể truy cập
Danh sách kiểm tra WCAG sau đây cung cấp tổng quan
- Danh sách kiểm tra WCAG từ Wuhcag
- Danh sách kiểm tra WCAG từ WebAIM
- Checklist từ Dự án A11Y
WAI-ARIA
Tài liệu Sáng kiến khả năng truy cập web - Ứng dụng Internet phong phú có thể truy cập chứa các kỹ thuật để xây dựng các tiện ích JavaScript có thể truy cập đầy đủ
Lưu ý rằng tất cả các thuộc tính HTML của
import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
1 đều được hỗ trợ đầy đủ trong JSX. Trong khi hầu hết các thuộc tính và thuộc tính DOM trong React đều là camelCased, thì các thuộc tính này phải có dấu gạch nối [còn được gọi là kebab-case, lisp-case, v.v.] giống như trong HTML thuần túy
HTML ngữ nghĩa
Semantic HTML là nền tảng của khả năng truy cập trong một ứng dụng web. Việc sử dụng các phần tử HTML khác nhau để củng cố ý nghĩa của thông tin trong trang web của chúng tôi thường sẽ cung cấp cho chúng tôi khả năng truy cập miễn phí
- Tài liệu tham khảo phần tử MDN HTML
Đôi khi, chúng tôi phá vỡ ngữ nghĩa HTML khi chúng tôi thêm các phần tử
import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
2 vào JSX của mình để làm cho mã React của chúng tôi hoạt động, đặc biệt là khi làm việc với các danh sách [import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
3, import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
4 và import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
5] và HTML import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
6. Trong những trường hợp này, chúng ta nên sử dụng React Fragment để nhóm nhiều phần tử lại với nhauVí dụ,
import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
Bạn có thể ánh xạ một tập hợp các mục thành một mảng các mảnh giống như bất kỳ loại phần tử nào khác
________số 8_______
Khi bạn không cần bất kỳ đạo cụ nào trên thẻ Fragment, bạn có thể sử dụng , nếu công cụ của bạn hỗ trợ nó
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
Để biết thêm thông tin, hãy xem tài liệu Mảnh vỡ
Biểu mẫu có thể truy cập
dán nhãn
Mọi điều khiển biểu mẫu HTML, chẳng hạn như
import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
7 và import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
8, cần được gắn nhãn có thể truy cập được. Chúng tôi cần cung cấp các nhãn mô tả cũng được hiển thị cho trình đọc màn hìnhCác tài nguyên sau đây cho chúng tôi biết cách thực hiện việc này
- W3C chỉ cho chúng ta cách gắn nhãn các phần tử
- WebAIM chỉ cho chúng tôi cách gắn nhãn các phần tử
- Nhóm Paciello giải thích tên có thể truy cập
Mặc dù các thực hành HTML tiêu chuẩn này có thể được sử dụng trực tiếp trong React, nhưng hãy lưu ý rằng thuộc tính
import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
9 được viết là function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
0 trong JSXName:
Thông báo lỗi cho người dùng
Các tình huống lỗi cần được hiểu bởi tất cả người dùng. Liên kết sau đây cũng chỉ cho chúng tôi cách hiển thị văn bản lỗi cho trình đọc màn hình
- W3C thể hiện thông báo người dùng
- WebAIM xem xét xác thực biểu mẫu
Kiểm soát lấy nét
Đảm bảo rằng ứng dụng web của bạn chỉ có thể được vận hành hoàn toàn bằng bàn phím
- WebAIM nói về khả năng truy cập bàn phím
Tiêu điểm bàn phím và phác thảo tiêu điểm
Tiêu điểm bàn phím đề cập đến phần tử hiện tại trong DOM được chọn để chấp nhận đầu vào từ bàn phím. Chúng tôi nhìn thấy nó ở khắp mọi nơi dưới dạng đường viền tiêu điểm tương tự như được hiển thị trong hình ảnh sau đây
Chỉ sử dụng CSS loại bỏ đường viền này, chẳng hạn như bằng cách đặt
function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
1, nếu bạn đang thay thế nó bằng một triển khai đường viền tiêu điểm khácCơ chế chuyển đến nội dung mong muốn
Cung cấp cơ chế cho phép người dùng bỏ qua các phần điều hướng trước đây trong ứng dụng của bạn vì điều này hỗ trợ và tăng tốc điều hướng bàn phím
Liên kết bỏ qua hoặc Liên kết bỏ qua điều hướng là các liên kết điều hướng ẩn chỉ hiển thị khi người dùng bàn phím tương tác với trang. Chúng rất dễ triển khai với các neo trang nội bộ và một số kiểu dáng
- WebAIM - Bỏ qua liên kết điều hướng
Ngoài ra, hãy sử dụng các yếu tố và vai trò mốc, chẳng hạn như
function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
2 và function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
3, để phân định các vùng của trang vì công nghệ hỗ trợ cho phép người dùng nhanh chóng điều hướng đến các phần nàyĐọc thêm về việc sử dụng các yếu tố này để tăng cường khả năng tiếp cận tại đây
- Cột mốc có thể truy cập
Quản lý tập trung theo chương trình
Các ứng dụng React của chúng tôi liên tục sửa đổi HTML DOM trong thời gian chạy, đôi khi dẫn đến mất tiêu điểm bàn phím hoặc được đặt thành một phần tử không mong muốn. Để khắc phục điều này, chúng ta cần di chuyển tiêu điểm bàn phím theo đúng hướng theo lập trình. Ví dụ: bằng cách đặt lại tiêu điểm bàn phím thành nút đã mở cửa sổ phương thức sau khi đóng cửa sổ phương thức đó
MDN Web Docs xem xét điều này và mô tả cách chúng tôi có thể xây dựng các tiện ích JavaScript có thể điều hướng bằng bàn phím
Để set focus trong React, chúng ta có thể sử dụng Refs to DOM elements
Sử dụng điều này, trước tiên chúng ta tạo một tham chiếu đến một phần tử trong JSX của một lớp thành phần
class CustomTextInput extends React.Component {
constructor[props] {
super[props];
// Create a ref to store the textInput DOM element this.textInput = React.createRef[]; }
render[] {
// Use the `ref` callback to store a reference to the text input DOM // element in an instance field [for example, this.textInput]. return [
];
}
}
Sau đó, chúng tôi có thể tập trung nó ở nơi khác trong thành phần của chúng tôi khi cần
focus[] {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
this.textInput.current.focus[];
}
Đôi khi, một thành phần cha mẹ cần đặt tiêu điểm cho một thành phần trong thành phần con. Chúng ta có thể làm điều này bằng cách thông qua một chỗ dựa đặc biệt trên thành phần con để chuyển tiếp tham chiếu của cha mẹ tới nút DOM của con
function CustomTextInput[props] {
return [
];
}
class Parent extends React.Component {
constructor[props] {
super[props];
this.inputElement = React.createRef[]; }
render[] {
return [
];
}
}
// Now you can set focus when required.
this.inputElement.current.focus[];
Khi sử dụng HOC để mở rộng các thành phần, nên chuyển tiếp ref đến thành phần được bao bọc bằng cách sử dụng chức năng
function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
4 của React. Nếu HOC của bên thứ ba không triển khai chuyển tiếp giới thiệu, mẫu trên vẫn có thể được sử dụng làm phương án dự phòngMột ví dụ quản lý tập trung tuyệt vời là phương thức phản ứng aria. Đây là một ví dụ tương đối hiếm về cửa sổ phương thức có thể truy cập đầy đủ. Nó không chỉ đặt tiêu điểm ban đầu vào nút hủy [ngăn người dùng bàn phím vô tình kích hoạt hành động thành công] và bẫy tiêu điểm bàn phím bên trong phương thức, mà còn đặt lại tiêu điểm trở lại thành phần đã kích hoạt chế độ ban đầu
Ghi chú
Mặc dù đây là một tính năng trợ năng rất quan trọng nhưng đây cũng là một kỹ thuật nên được sử dụng một cách thận trọng. Sử dụng nó để sửa chữa dòng tiêu điểm bàn phím khi nó bị loạn, không phải để thử và đoán xem người dùng muốn sử dụng ứng dụng như thế nào
Sự kiện chuột và con trỏ
Đảm bảo rằng tất cả các chức năng được hiển thị thông qua sự kiện chuột hoặc con trỏ cũng có thể được truy cập chỉ bằng bàn phím. Chỉ phụ thuộc vào thiết bị con trỏ sẽ dẫn đến nhiều trường hợp người dùng bàn phím không sử dụng được ứng dụng của bạn
Để minh họa điều này, hãy xem một ví dụ điển hình về khả năng truy cập bị hỏng do các sự kiện nhấp chuột gây ra. Đây là mẫu nhấp chuột bên ngoài, trong đó người dùng có thể vô hiệu hóa cửa sổ bật lên đã mở bằng cách nhấp vào bên ngoài phần tử
Điều này thường được thực hiện bằng cách đính kèm một sự kiện
function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
5 vào đối tượng function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
6 để đóng cửa sổ bật lênclass OuterClickExample extends React.Component {
constructor[props] {
super[props];
this.state = { isOpen: false };
this.toggleContainer = React.createRef[];
this.onClickHandler = this.onClickHandler.bind[this];
this.onClickOutsideHandler = this.onClickOutsideHandler.bind[this];
}
componentDidMount[] { window.addEventListener['click', this.onClickOutsideHandler]; }
componentWillUnmount[] {
window.removeEventListener['click', this.onClickOutsideHandler];
}
onClickHandler[] {
this.setState[currentState => [{
isOpen: !currentState.isOpen
}]];
}
onClickOutsideHandler[event] { if [this.state.isOpen && !this.toggleContainer.current.contains[event.target]] { this.setState[{ isOpen: false }]; } }
render[] {
return [
Select an option
{this.state.isOpen && [
Option 1
Option 2
Option 3
]}
];
}
}
Điều này có thể hoạt động tốt đối với người dùng có thiết bị con trỏ, chẳng hạn như chuột, nhưng chỉ vận hành thiết bị này bằng bàn phím sẽ dẫn đến chức năng bị hỏng khi chuyển sang phần tử tiếp theo vì đối tượng
function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
6 không bao giờ nhận được sự kiện function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
5. Điều này có thể dẫn đến chức năng bị che khuất ngăn người dùng sử dụng ứng dụng của bạnThay vào đó, chức năng tương tự có thể đạt được bằng cách sử dụng các trình xử lý sự kiện thích hợp, chẳng hạn như
function Glossary[props] {
return [
{props.items.map[item => [
// Fragments should also have a `key` prop when mapping collections
{item.term}
{item.description}
]]}
];
}
9 và function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
0class BlurExample extends React.Component {
constructor[props] {
super[props];
this.state = { isOpen: false };
this.timeOutId = null;
this.onClickHandler = this.onClickHandler.bind[this];
this.onBlurHandler = this.onBlurHandler.bind[this];
this.onFocusHandler = this.onFocusHandler.bind[this];
}
onClickHandler[] {
this.setState[currentState => [{
isOpen: !currentState.isOpen
}]];
}
// We close the popover on the next tick by using setTimeout. // This is necessary because we need to first check if // another child of the element has received focus as // the blur event fires prior to the new focus event. onBlurHandler[] { this.timeOutId = setTimeout[[] => { this.setState[{ isOpen: false }]; }]; }
// If a child receives focus, do not close the popover. onFocusHandler[] { clearTimeout[this.timeOutId]; }
render[] {
// React assists us by bubbling the blur and // focus events to the parent. return [
Select an option
{this.state.isOpen && [
Option 1
Option 2
Option 3
]}
];
}
}
Mã này hiển thị chức năng cho cả người dùng thiết bị con trỏ và bàn phím. Cũng lưu ý thêm đạo cụ
import React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
1 để hỗ trợ người dùng trình đọc màn hình. Để đơn giản, các sự kiện bàn phím để kích hoạt tương tác function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
2 của các tùy chọn bật lên chưa được triển khaiĐây là một ví dụ về nhiều trường hợp chỉ phụ thuộc vào các sự kiện con trỏ và chuột sẽ phá vỡ chức năng của người dùng bàn phím. Luôn kiểm tra bằng bàn phím sẽ ngay lập tức làm nổi bật các khu vực có vấn đề, sau đó có thể khắc phục bằng cách sử dụng trình xử lý sự kiện nhận biết bàn phím
Widget phức tạp hơn
Trải nghiệm người dùng phức tạp hơn không có nghĩa là ít truy cập hơn. Trong khi khả năng tiếp cận đạt được dễ dàng nhất bằng cách mã hóa càng gần với HTML càng tốt, thì ngay cả tiện ích phức tạp nhất cũng có thể được mã hóa một cách dễ dàng
Ở đây chúng tôi yêu cầu kiến thức về cũng như. Đây là những hộp công cụ chứa đầy các thuộc tính HTML được hỗ trợ đầy đủ trong JSX và cho phép chúng tôi xây dựng các thành phần React có chức năng cao, có thể truy cập đầy đủ
Mỗi loại widget có một mẫu thiết kế cụ thể và được người dùng cũng như tác nhân người dùng mong đợi sẽ hoạt động theo một cách nhất định
- Hướng dẫn thực hành tác giả ARIA [APG] - Mẫu thiết kế và ví dụ
- Heydon Pickering - Các ví dụ về ARIA
- Thành phần bao gồm
Các điểm khác để xem xét
Cài đặt ngôn ngữ
Cho biết ngôn ngữ con người của văn bản trang vì phần mềm trình đọc màn hình sử dụng ngôn ngữ này để chọn cài đặt giọng nói chính xác
Đặt tiêu đề tài liệu
Đặt tài liệu
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
3 để mô tả chính xác nội dung trang hiện tại vì điều này đảm bảo rằng người dùng vẫn biết về ngữ cảnh trang hiện tại- WCAG - Tìm hiểu Yêu cầu Tiêu đề Tài liệu
Chúng ta có thể thiết lập điều này trong React bằng cách sử dụng Thành phần tiêu đề tài liệu React
Độ tương phản màu
Đảm bảo rằng tất cả văn bản có thể đọc được trên trang web của bạn có đủ độ tương phản màu sắc để người dùng có thị lực kém có thể đọc được ở mức tối đa
- WCAG - Hiểu Yêu cầu về Độ tương phản Màu sắc
- Mọi thứ về độ tương phản màu sắc và tại sao bạn nên suy nghĩ lại về nó
- A11yProject - Độ tương phản màu là gì
Có thể rất tẻ nhạt khi tính toán thủ công các kết hợp màu thích hợp cho tất cả các trường hợp trong trang web của bạn, vì vậy, thay vào đó, bạn có thể tính toán toàn bộ bảng màu có thể truy cập bằng Colorable
Cả công cụ rìu và WAVE được đề cập bên dưới cũng bao gồm các bài kiểm tra độ tương phản màu và sẽ báo cáo về các lỗi tương phản
Nếu bạn muốn mở rộng khả năng kiểm tra độ tương phản của mình, bạn có thể sử dụng các công cụ này
- WebAIM - Trình kiểm tra độ tương phản màu
- Nhóm Paciello - Máy phân tích độ tương phản màu
Công cụ phát triển và thử nghiệm
Có một số công cụ chúng tôi có thể sử dụng để hỗ trợ tạo các ứng dụng web có thể truy cập
Bàn phím
Cho đến nay, cách dễ nhất và cũng là một trong những kiểm tra quan trọng nhất là kiểm tra xem có thể truy cập và sử dụng toàn bộ trang web của bạn chỉ bằng bàn phím hay không. làm điều này bằng cách
- Ngắt kết nối chuột của bạn
- Sử dụng
4 vàfunction ListItem[{ item }] { return [ {item.term} {item.description} ]; }
5 để duyệtfunction ListItem[{ item }] { return [ {item.term} {item.description} ]; }
- Sử dụng
6 để kích hoạt các phần tửfunction ListItem[{ item }] { return [ {item.term} {item.description} ]; }
- Khi được yêu cầu, sử dụng các phím mũi tên trên bàn phím của bạn để tương tác với một số thành phần, chẳng hạn như menu và danh sách thả xuống
Hỗ trợ phát triển
Chúng tôi có thể kiểm tra một số tính năng trợ năng trực tiếp trong mã JSX của mình. Thông thường, các kiểm tra intellisense đã được cung cấp trong IDE nhận biết JSX cho các vai trò, trạng thái và thuộc tính ARIA. Chúng tôi cũng có quyền truy cập vào công cụ sau
eslint-plugin-jsx-a11y
Plugin eslint-plugin-jsx-a11y cho ESLint cung cấp phản hồi AST linting về các vấn đề về khả năng truy cập trong JSX của bạn. Nhiều IDE cho phép bạn tích hợp trực tiếp những phát hiện này vào cửa sổ phân tích mã và mã nguồn
Tạo ứng dụng React có plugin này với một tập hợp con các quy tắc được kích hoạt. Nếu bạn muốn bật nhiều quy tắc trợ năng hơn nữa, bạn có thể tạo tệp
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
7 trong thư mục gốc của dự án với nội dung nàyimport React, { Fragment } from 'react';
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
function Glossary[props] {
return [
{props.items.map[item => [
]]}
];
}
0Kiểm tra khả năng truy cập trong trình duyệt
Có một số công cụ có thể chạy kiểm tra khả năng truy cập trên các trang web trong trình duyệt của bạn. Vui lòng sử dụng chúng kết hợp với các kiểm tra khả năng truy cập khác được đề cập ở đây vì chúng chỉ có thể kiểm tra khả năng truy cập kỹ thuật của HTML của bạn
aXe, aXe-core và Reac-axe
Deque Systems cung cấp aXe-core để kiểm tra khả năng truy cập tự động và từ đầu đến cuối cho các ứng dụng của bạn. Mô-đun này bao gồm tích hợp cho Selenium
Công cụ trợ năng hoặc aXe, là tiện ích mở rộng của trình kiểm tra khả năng truy cập được xây dựng trên
function ListItem[{ item }] {
return [
{item.term}
{item.description}
];
}
8Bạn cũng có thể sử dụng mô-đun @axe-core/react để báo cáo trực tiếp các phát hiện về khả năng truy cập này cho bảng điều khiển trong khi phát triển và gỡ lỗi
WebAIM WAVE
Công cụ đánh giá khả năng truy cập web là một tiện ích mở rộng trình duyệt khả năng truy cập khác
Trình kiểm tra trợ năng và Cây trợ năng
Cây khả năng truy cập là một tập hợp con của cây DOM chứa các đối tượng có thể truy cập cho mọi thành phần DOM sẽ được tiếp xúc với công nghệ hỗ trợ, chẳng hạn như trình đọc màn hình
Trong một số trình duyệt, chúng ta có thể dễ dàng xem thông tin về khả năng truy cập của từng thành phần trong cây khả năng truy cập
- Sử dụng Trình kiểm tra khả năng truy cập trong Firefox
- Sử dụng Trình kiểm tra khả năng truy cập trong OS X Safari
Trình đọc màn hình
Kiểm tra bằng trình đọc màn hình sẽ là một phần của kiểm tra khả năng truy cập của bạn
Xin lưu ý rằng sự kết hợp của trình duyệt/trình đọc màn hình là quan trọng. Bạn nên thử nghiệm ứng dụng của mình trong trình duyệt phù hợp nhất với trình đọc màn hình mà bạn chọn
Trình đọc màn hình thường được sử dụng
NVDA trong Firefox
NonVisual Desktop Access hay NVDA là trình đọc màn hình Windows mã nguồn mở được sử dụng rộng rãi
Tham khảo các hướng dẫn sau về cách sử dụng NVDA tốt nhất
- WebAIM - Sử dụng NVDA để đánh giá khả năng truy cập web
- Deque - Phím tắt NVDA
Thuyết minh trong Safari
VoiceOver là trình đọc màn hình tích hợp trên các thiết bị của Apple
Tham khảo các hướng dẫn sau về cách kích hoạt và sử dụng VoiceOver
- WebAIM - Sử dụng VoiceOver để đánh giá khả năng truy cập web
- Deque - Phím tắt VoiceOver cho OS X
- Deque - Phím tắt VoiceOver cho iOS
JAWS trong Internet Explorer
Truy cập công việc bằng giọng nói hoặc JAWS, là trình đọc màn hình được sử dụng phổ biến trên Windows
Tham khảo các hướng dẫn sau đây về cách sử dụng JAWS tốt nhất
- WebAIM - Sử dụng JAWS để đánh giá khả năng truy cập web
- Deque - Phím tắt JAWS
Trình đọc màn hình khác
ChromeVox trong Google Chrome
ChromeVox là trình đọc màn hình tích hợp trên Chromebook và có sẵn dưới dạng tiện ích mở rộng cho Google Chrome