Skip to content Skip to sidebar Skip to footer

Accessibility: Using Javascript Only Links With Href="#"

I have a react SPA in which I have some links which navigate to other pages or other locations on the same page, These navigations are either decided programmatically or are depend

Solution 1:

Short Answer

Links should be used if the URL changes (navigation) for everything else a button should be used. <a href="#" is not a good practice but for a SPA it should be OK if your link text is accurate and detailed. Avoid smooth scroll or give people a way to switch it off as it can be disorientating.

Longer Answer

I gave quite an extensive answer on <a> vs <button> in SPAs here, so I hope that is sufficient to answer which one to use in what scenario for general use cases.

With regards to the # in the URL due to you not knowing the URL before hand. It would be much better if you start it as # if the URL is unknown but then update the href once you know where you are going to route people.

This is for the reasons discussed in the answer I linked regarding reassurance, i.e. knowing where a link will take me.

Obviously if you are not able to do this then make sure the link text is very descriptive so that I can be confident I am going to the right place.

Scrolling within a SPA

With regards to the scrolling to different parts of the page that would still be a link as you say, assuming that you update the url with #section-name. You should do this, but if your application router cannot handle URL fragments then I would not update the URL at all and change this to a button.

At this stage I would use some visually hidden text within the button to explain that this scrolls to a section on the current page.

The example below illustrates this. Please use the CSS class below to visually hide text as it has better compatibility than bootstrap sr-only class as explained in this answer I gave.

.visually-hidden { 
    border: 0;
    padding: 0;
    margin: 0;
    position: absolute !important;
    height: 1px; 
    width: 1px;
    overflow: hidden;
    clip: rect(1px1px1px1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<button><spanclass="visually-hidden">Go To </span>Section name<spanclass="visually-hidden"> on this page</span></button>

A quick word on smooth scrolling

Finally I would caution you on the use of smooth scrolling. If you use this make sure there is a way to switch it off as it may be distracting or disorientating for people with either motion disorders or anxiety disorders.

One way you can do this is to use the CSS media query prefers-reduced-motion.

Final Thoughts

Without seeing each scenario it is hard to give a 100% definitive answer, if you can try and follow standard navigation patterns of buttons for same page actions, links with url fragments for navigating to sections of the same page and links to other pages, even if these are handled via AJAX and only partial reloads.

Obviously that is the aim, I am aware that with some routing solutions this is not always possible in which case use your best judgement and test it with a screen reader as screen reader users are most likely to suffer from a poorly formed navigation system in a SPA.

One last tip - if you do change page in a SPA, make the <h1> on the next page programatically focusable with tabindex="-1" and focus that once the page loads. It is a great way to let users with little to no vision know that navigation is complete in a SPA using AJAX.

Post a Comment for "Accessibility: Using Javascript Only Links With Href="#""