Цветовой контраст — важный аспект доступности веб-приложений, который часто упускается из виду. В соответствии с WCAG (Web Content Accessibility Guidelines), для удобства восприятия пользователями с ограниченными возможностями, контраст между фоном и текстом должен быть достаточным. Для этого нужно проверять соответствие контраста установленным нормам. В контексте тестирования на React, проверка цветового контраста становится важной частью обеспечения доступности интерфейса.
В этой главе будет рассмотрено, как проверить цветовой контраст
элементов с помощью React Testing Library и различных библиотек, таких
как axe-core и jest-axe.
Цветовой контраст описывает, насколько различимы два цвета на экране. В контексте веб-дизайна это обычно касается контраста текста по отношению к фону. WCAG указывает на минимальные требования для контраста: для обычного текста коэффициент контраста должен быть не менее 4.5:1, а для текста, размер которого более 18pt, — 3:1. Несоответствие этим требованиям может привести к трудностям при восприятии контента, особенно для людей с дальтонизмом или проблемами со зрением.
Для того чтобы удостовериться, что интерфейс соответствует стандартам
доступности, необходимо включить тестирование контраста. В React Testing
Library для этого можно использовать сочетание библиотеки для
тестирования доступности jest-axe и инструментов для
анализа стилей.
Для начала необходимо установить несколько библиотек:
npm install --save-dev @testing-library/react @testing-library/jest-dom jest-axe
@testing-library/react и
@testing-library/jest-dom обеспечивают стандартные
инструменты для тестирования React-компонентов, а jest-axe
интегрирует axe-core, который выполняет анализ доступности
и проверяет соответствие контрастности.
В коде теста можно использовать jest-axe для проверки
цветового контраста следующим образом:
import { render } from '@testing-library/react';
import { axe, toHaveNoViolations } from 'jest-axe';
import MyComponent from './MyComponent';
expect.extend(toHaveNoViolations);
test('MyComponent should have no accessibility violations', async () => {
const { container } = render(<MyComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Этот тест рендерит компонент MyComponent и затем
проверяет его на наличие нарушений доступности, включая цветовой
контраст. Если тест не обнаружит нарушений, он пройдет успешно, в
противном случае будет выведено сообщение о нарушении.
Если тестирование покажет, что контраст цветов нарушает требования,
axe-core вернет подробную информацию о нарушении, включая
элементы, которые не соответствуют стандартам, и описание ошибки. Для
устранения проблемы нужно будет откорректировать стили компонента,
увеличив контраст между фоном и текстом.
Пример нарушения:
Color contrast is insufficient for text element. Text has a contrast ratio of 3.2:1, which is less than the required 4.5:1 for normal text.
Для исправления можно изменить цвет текста или фона, чтобы контраст стал выше требуемого минимального значения.
axe-core для более детальной проверкиaxe-core может предоставить подробную информацию о
нарушениях доступности, не ограничиваясь только цветовым контрастом.
Например, можно получить все доступные нарушения сразу, а не только
связанные с контрастом:
import { render } from '@testing-library/react';
import { axe } from 'jest-axe';
import MyComponent from './MyComponent';
test('should not have accessibility violations', async () => {
const { container } = render(<MyComponent />);
const results = await axe(container);
console.log(results); // Посмотреть все нарушения
expect(results.violations).toHaveLength(0);
});
Это позволяет проводить комплексное тестирование доступности интерфейсов, обнаруживая не только проблемы с контрастом, но и с другими аспектами, такими как структура элементов или отсутствие важных атрибутов ARIA.
В некоторых случаях компонент может использовать inline-стили или
динамически изменяющиеся стили, которые могут повлиять на видимость
контраста. В таких случаях также можно использовать
jest-axe для проверки контраста в реальных условиях
рендеринга, включая изменения, происходящие во время работы
приложения.
Для inline-стилей тест будет работать следующим образом:
import { render } from '@testing-library/react';
import { axe } from 'jest-axe';
import MyComponent from './MyComponent';
test('should have no contrast violations with inline styles', async () => {
const { container } = render(
<MyComponent style={{ color: 'rgb(255, 0, 0)', backgroundColor: 'rgb(0, 0, 0)' }} />
);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Здесь тест проверяет компонент с inline-стилями, и axe
анализирует контрастность элементов, включая динамические изменения,
заданные стилями.
Если вам нужно более точно настроить проверку контраста в зависимости
от особенностей проекта, можно использовать кастомные правила проверки
контраста. Например, можно настроить проверку только для определенных
компонентов или типов контента. Для этого потребуется изменить
конфигурацию axe-core, добавив пользовательские
настройки.
Пример настройки кастомного правила для проверки контраста:
import { configureAxe } from 'jest-axe';
const axe = configureAxe({
rules: [
{
id: 'color-contrast',
enabled: true,
selector: '.my-component',
},
],
});
test('should have no contrast violations in specific component', async () => {
const { container } = render(<MyComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Такой подход дает больше контроля над тем, какие элементы тестировать и как это делать, что полезно при сложных интерфейсах с индивидуальными требованиями доступности.
Цветовой контраст является важной частью доступности веб-приложений,
и его проверка должна быть интегрирована в процесс тестирования. React
Testing Library в сочетании с jest-axe и
axe-core предоставляет эффективные средства для
автоматизации тестов на доступность, включая проверку контраста. Важно
помнить, что цветовой контраст не является единственным аспектом
доступности, но его проверка поможет улучшить восприятие вашего
приложения пользователями с ограниченными возможностями.