От автора: ссылки необходимы для навигации по любому веб-сайту с момента появления современной сети в 2000-х годах. Не существует определенного числа, выражающего максимальное количество ссылок на любой веб-странице. Однако можно с уверенностью предположить, что семантический HTML header будет иметь несколько ссылок анкоров.
В конце концов, header — это точка входа во вложенную структуру вашего сайта. Хотя переполненная навигация может быть не такой проблемой (как множество всплывающих окон и привлекающих внимание рекламных объявлений), она, безусловно, может быть утомительной для посетителей.
Навигация в интернете без мыши не так тривиальна, как может показаться. В зависимости от реализации веб-сайта совместимость с клавиатурой может быть реализована плохо. Интересно, что лидеры отрасли понимают важность доступности и охвата более широких слоев населения. Таким образом, мы можем наблюдать вполне заслуженный сдвиг парадигмы в сторону веб-доступа с клавиатуры.
Рекомендую вам использовать вашу любимую социальную сеть с клавиатурой, чтобы лучше понять основную проблему. Каждый раз, когда «клавиатурный пользователь» посещает страницу, ему приходится нажимать TAB для навигации, прежде чем можно будет прочитать какой-либо значимый контент. Специалисты по пользовательскому опыту (UX) обычно выявляли такую проблему и решали ее с помощью так называемых «скиплинков».
Skiplinks
Такой анкор предназначен для использования в качестве первого HTML-элемента, к которому пользователь может перейти с помощью TAB. Он часто существует скрытым в навигации заголовка, прежде чем другие ссылки могут быть идентифицированы. Обычная реализация HTML может выглядеть примерно так:
1 2 3 4 5 6 |
<header> <a class="skip-link" href="#main-id">Skip Navigation Links</a> <nav> ... more links </nav> </header> |
Ваш стиль CSS может быть разработан следующим образом:
1 2 3 4 5 6 7 8 9 10 11 |
.skip-link { margin-right: 1rem; position: absolute; transform: translateX(-200%); transition: transform 0.3s; &:focus { position: static; transform: translateX(0); } } |
По умолчанию наш Skiplink имеет position: absolute; чтобы не нарушать поток HTML. Когда для навигации используется клавиатура, .skip-link получает фокус и вставляется обратно в статическую позицию HTML.
Мы используем transformX из-за его производительности при переходе в сфокусированное состояние. Основное предположение, побуждающее нас использовать преобразование, основано на расширении header вместе с областью просмотра. Если ваш header имеет статический размер, рекомендуется использовать свойство left.
Подводные камни реализации
Вышеупомянутой реализации достаточно для многих проектов. Это, безусловно, порадует пользователей навигации с помощью клавиатуры. Однако, если вы заинтересованы в многократно используемой и надежной инженерной инфраструктуре, рекомендуется учитывать следующие подводные камни:
Возможность повторного использования: чаще всего в вашем веб-приложении преобладают различные варианты header -ов. Обычно маркетинговый компонент и компонент header веб-приложения удовлетворяют разные потребности.
Фрагментная (#) навигация. Ваше веб-приложение сложное, потенциально может содержать сотни страниц, имеющих общую структуру ориентиров HTML. Внедрение атрибута id для соответствия href вашего скиплинка может быть утомительным и подверженным ошибкам.
Поисковая оптимизация (SEO): Ваша якорная ссылка неизбежно будет проанализирована поисковыми роботами. Скрывать Skiplink не рекомендуется, как предлагает Google в своей авторской статье о скрытых текстовых ссылках.
Скиплинки в React
Как мы можем снизить все вышеперечисленные риски, заботясь как о инженерах, так и о пользователях? Мы можем реализовать навигацию по фрагментам, программно прокручивая элемент, используя комбинацию document.querySelector() и добавляя .focus() к выбранному элементу-оболочке HTML.
SEO можно улучшить, используя кнопки вместо якорных ссылок Skiplinks. Кнопки не так легко интерпретируются сканерами веб-сайтов, однако наша реализация должна быть неизменной.
Независимо от того, используете ли вы кнопки или якоря, мы хотим создать повторно используемый компонент, который инкапсулирует желаемую функциональность. Очевидно, что нам понадобится обработчик события onClick, который следует перенаправить нашим дочерним элементам. Реализация React + TypeScript показана ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import React from 'react'; interface SkipLinkProperties { className?: string; children: React.ReactElement; /** * The css query aiding the selection of the * container (main, section etc) we want to scroll to; */ skipTo: string; } const SkipLink: React.FC<SkipLinkProperties> = props => { const onClick = (event: React.SyntheticEvent) => { event.preventDefault(); const container: (HTMLElement | null) = document.querySelector(props.skipTo); if (container) { container.tabIndex = -1; container.focus(); setTimeout(() => container.removeAttribute("tabindex"), 1000); } }; return React.cloneElement(props.children, { onClick, className: props.className }); } SkipLink.defaultProps = { className: "skip-link", skipTo: "main:first-of-type", }; export default SkipLink; |
React.cloneElement() особенно полезен в нашей реализации. Мы передаем дополнительное свойство className, которое может не понадобиться в вашей собственной реализации. Рекомендуется использовать это свойство, чтобы имя класса было согласованным между несколькими импортами, не полагаясь на дочерние элементы.
Потенциальная композиция для вашего проекта может выглядеть так:
1 2 3 |
<SkipLink className="primary skip-link"> <button type="button">Skip Navigation Links</button> </SkipLink> |
Будем надеяться, что Skiplinks будут приняты и стандартизированы в более широком спектре Интернета. Их легко реализовать, одновременно улучшая доступность навигации клавиатурой на вашем веб-сайте.
Автор: George Argyrousis
Источник: levelup.gitconnected.com
Редакция: Команда webformyself.
Читайте нас в Telegram, VK, Яндекс.Дзен